/* ================================================================
   CampSuite Global Styles
   Grandma-first: large text, generous touch targets, high contrast
   ================================================================ */

/* Base font: 16px everywhere - never smaller than the browser default */
html {
    font-size: 16px;
}

@media (min-width: 768px) {
    html {
        font-size: 16px;
    }
}

html {
    position: relative;
    min-height: 100%;
}

body {
    margin-bottom: 60px;
    -webkit-text-size-adjust: 100%;
    /* UI typeface - Poppins, one family for the whole interface, with the
       native system stack as a fast fallback until it loads. Display headings
       are the same face at a heavier weight rather than a second family. */
    font-family: "Poppins", -apple-system, BlinkMacSystemFont, "SF Pro Text",
        "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Headings: slightly tighter tracking reads more "designed" without
   hurting legibility. Weights stay bold so hierarchy is obvious. */
h1, h2, h3, h4 {
    letter-spacing: -0.01em;
}

/* ── Craft details - the small things templates never bother with ──
   Selected text takes the sky-and-deep-blue brand pairing, tapping on a
   phone doesn't flash a grey rectangle, scrollbars are thin and warm
   instead of stock chrome, and every column of figures lines up like
   a ledger (tabular numerals in tables and stat numbers). */
::selection { background: #d7e6f4; color: #0f213f; }

html { -webkit-tap-highlight-color: transparent; }

table,
.cs-m-summary-number {
    font-variant-numeric: tabular-nums;
}

@media (min-width: 768px) {
    * { scrollbar-width: thin; scrollbar-color: #ced2dd transparent; }
    *::-webkit-scrollbar { width: 10px; height: 10px; }
    *::-webkit-scrollbar-track { background: transparent; }
    *::-webkit-scrollbar-thumb {
        background: #ced2dd;
        border-radius: 5px;
        border: 2px solid transparent;
        background-clip: content-box;
    }
    *::-webkit-scrollbar-thumb:hover { background-color: #9ba1b0; }
}

/* Display face - Poppins at a heavier weight. Page titles and hero moments sit
   in the same family as the body copy, so a heading reads as the same voice
   raised rather than as a different typeface borrowed for the occasion. */
.cs-font-display {
    font-family: "Poppins", "Segoe UI", system-ui, sans-serif;
    letter-spacing: -0.01em;
    font-optical-sizing: auto;
}

/* ── Focus styles ── visible, high-contrast ring for keyboard users.
   Brand blue so it matches the rest of the UI. */
:focus-visible {
    outline: 3px solid #22568c;
    outline-offset: 2px;
}

/* ── Form inputs ── bigger touch targets, clearer text */
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="password"],
input[type="date"],
input[type="time"],
input[type="search"],
select,
textarea {
    font-size: 1rem;
    min-height: 48px;
}

@media (min-width: 768px) {
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="number"],
    input[type="password"],
    input[type="date"],
    input[type="time"],
    input[type="search"],
    select,
    textarea {
        min-height: 44px;
    }
}

/* ── Checkboxes & radio buttons ── larger touch targets */
input[type="checkbox"],
input[type="radio"] {
    min-width: 20px;
    min-height: 20px;
}

/* ── Buttons ── generous touch targets (44px minimum on mobile) */
button,
[type="submit"],
a.inline-flex {
    min-height: 44px;
}

/* ── Smooth transitions for interactive elements ── */
input, select, textarea, button, a {
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

/* ── Icons ── one consistent, lighter line weight everywhere. The stock 2px
   heroicon stroke is the generic-template look; 1.7px reads drawn-for-us.
   Only touches icons that declare the stock weight on the <svg> itself, so
   deliberate heavier strokes (chevrons at 2.5) and SVG artwork with per-shape
   widths (the site-map drawings) are untouched. */
svg[stroke-width="2"] {
    stroke-width: 1.7;
}

/* ── Mobile drawer animation ──
   visibility toggles with the slide so the closed drawer is out of the tab
   order and invisible to screen readers (transform alone hides neither). */
#cs-mobile {
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 0.25s ease, visibility 0s linear 0.25s;
    -webkit-overflow-scrolling: touch;
}

#cs-mobile.cs-open {
    transform: translateX(0);
    visibility: visible;
    transition: transform 0.25s ease, visibility 0s linear 0s;
}

#cs-overlay {
    opacity: 0;
    transition: opacity 0.25s ease;
}

#cs-overlay.cs-open {
    opacity: 1;
}

/* ── Table responsive helpers ── */
@media (max-width: 767px) {
    .cs-table-desktop {
        display: none !important;
    }
}

@media (min-width: 768px) {
    .cs-table-mobile {
        display: none !important;
    }
}

/* ── Validation messages ── make errors prominent and readable */
.field-validation-error {
    font-size: 0.9375rem;
    font-weight: 500;
}

/* Hide the validation summary container when there are no errors */
.validation-summary-valid {
    display: none;
}

/* ── Contact search results dropdown ── */
.cs-search-results {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    background: #fff;
    border: 1.5px solid #e4e6ed;
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
    z-index: 110;
    max-height: 220px;
    overflow-y: auto;
    margin-top: 4px;
}

.cs-search-results.cs-visible {
    display: block;
}

.cs-search-item {
    padding: 12px 16px;
    cursor: pointer;
    border-bottom: 1px solid #f7f8fa;
    transition: background 0.1s;
}

.cs-search-item:hover {
    background: #eef4fa;
}

.cs-search-item:last-child {
    border-bottom: none;
}

.cs-search-item-name {
    font-weight: 600;
    font-size: 0.9375rem;
    color: #181b21;
}

.cs-search-item-detail {
    font-size: 0.8125rem;
    color: #6c7280;
    margin-top: 2px;
}

/* A blocked guest is flagged in the results, so nobody picks one by mistake. */
.cs-search-item-blocked {
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 9999px;
    background: #fee2e2;
    color: #b42318;
    font-size: 0.6875rem;
    font-weight: 700;
}

/* ── Match banner (duplicate detection) ── */
.cs-match-banner {
    display: none;
    padding: 12px 16px;
    border-radius: 10px;
    background: #f2f6f9;
    border: 1.5px solid #c2d4e3;
    margin-top: 12px;
    font-size: 0.875rem;
    align-items: center;
    gap: 10px;
}

.cs-match-banner.cs-visible {
    display: flex;
}

.cs-match-banner-icon {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: #3a5f7e;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.9375rem;
    flex-shrink: 0;
}

.cs-match-banner-info {
    flex: 1;
    min-width: 0;
}

.cs-match-banner-name {
    font-weight: 700;
    color: #2b4255;
}

.cs-match-banner-detail {
    font-size: 0.8125rem;
    color: #4b7699;
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cs-match-use {
    padding: 6px 14px;
    border-radius: 10px;
    border: none;
    background: #3a5f7e;
    color: #fff;
    font-size: 0.8125rem;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
    min-height: 36px;
}

.cs-match-use:hover {
    background: #324f68;
}

/* ── Linked guest banner ── */
.cs-linked-guest {
    display: none;
    padding: 12px 16px;
    border-radius: 10px;
    background: #eef4fa;
    border: 1.5px solid #b4d0e9;
    font-size: 0.875rem;
    align-items: center;
    gap: 10px;
}

.cs-linked-guest.cs-visible {
    display: flex;
}

.cs-linked-guest-icon {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: #22568c;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.125rem;
    flex-shrink: 0;
}

.cs-linked-guest-info {
    flex: 1;
}

.cs-linked-guest-name {
    font-weight: 700;
    color: #1b4472;
}

.cs-linked-guest-detail {
    font-size: 0.8125rem;
    color: #22568c;
    margin-top: 2px;
}

.cs-linked-clear {
    padding: 6px 14px;
    border-radius: 10px;
    border: 1.5px solid #b4d0e9;
    background: #fff;
    color: #22568c;
    font-size: 0.8125rem;
    font-weight: 700;
    cursor: pointer;
    min-height: 36px;
}

.cs-linked-clear:hover {
    background: #eef4fa;
}

/* ── Stepper (+ / - buttons for party size) ── */
.cs-stepper {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    border: 1.5px solid #e4e6ed;
    border-radius: 10px;
    overflow: hidden;
    background: #fff;
}

.cs-stepper-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    background: #f7f8fa;
    border: none;
    cursor: pointer;
    color: #4e5461;
    transition: background 0.15s, color 0.15s;
    flex-shrink: 0;
}

.cs-stepper-btn:hover {
    background: #e4e6ed;
    color: #181b21;
}

.cs-stepper-btn:active {
    background: #ced2dd;
}

.cs-stepper-value {
    width: 48px !important;
    min-height: 48px !important;
    text-align: center;
    font-size: 1.125rem;
    font-weight: 700;
    color: #181b21;
    border: none !important;
    border-left: 1.5px solid #e4e6ed !important;
    border-right: 1.5px solid #e4e6ed !important;
    border-radius: 0 !important;
    padding: 0 !important;
    box-shadow: none !important;
    background: #fff;
    -moz-appearance: textfield;
}

.cs-stepper-value::-webkit-inner-spin-button,
.cs-stepper-value::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* ── iOS Safari modal fixes ──
   On iOS, position:fixed + keyboard causes viewport issues.
   Using overflow-y:auto on the overlay with overscroll-contain
   lets the modal scroll naturally when the keyboard opens. */
@supports (-webkit-touch-callout: none) {
    .fixed.overflow-y-auto {
        -webkit-overflow-scrolling: touch;
    }
}

/* ── Pricing table mobile layout ── */
@media (max-width: 767px) {
    .cs-pricing-table {
        display: block;
    }

    .cs-pricing-table thead {
        display: none;
    }

    .cs-pricing-table tbody {
        display: flex;
        flex-direction: column;
        gap: 1rem;
    }

    .cs-pricing-table tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.5rem;
        padding: 0.75rem;
        border: 1px solid #e4e6ed;
        border-radius: 0.625rem;
        background: #fff;
    }

    .cs-pricing-table td:first-child {
        flex: 0 0 100%;
        padding: 0;
        font-weight: 600;
        font-size: 0.9375rem;
        margin-bottom: 0.25rem;
    }

    .cs-pricing-table td {
        flex: 1 1 0;
        min-width: 0;
        padding: 0;
    }

    .cs-pricing-table td input {
        width: 100% !important;
    }

    .cs-pricing-season-label {
        display: block;
        font-size: 0.75rem;
        font-weight: 500;
        color: #6c7280;
        margin-bottom: 2px;
    }
}

@media (min-width: 768px) {
    .cs-pricing-season-label {
        display: none;
    }
}

/* ─── Audience toggle (Settings → Extras) ─────────────────────────
   Three big tappable cards for "where should we show this extra".
   Visual checkbox: the native input is hidden but still receives focus,
   and the card lifts + paints emerald when the box is ticked.
   ──────────────────────────────────────────────────────────────── */
.audience-toggle {
    position: relative;
    display: block;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.audience-toggle-input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    width: 0;
    height: 0;
}

.audience-toggle-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 16px 14px;
    border-radius: 10px;
    border: 2px solid #e4e6ed;
    background: #ffffff;
    transition: border-color 160ms ease, background 160ms ease, box-shadow 160ms ease, transform 120ms ease;
    height: 100%;
}

.audience-toggle:hover .audience-toggle-card {
    border-color: #9ba1b0;
    background: #f7f8fa;
}

.audience-toggle-input:focus-visible + .audience-toggle-card {
    outline: 3px solid #22568c;
    outline-offset: 2px;
}

.audience-toggle-input:checked + .audience-toggle-card {
    border-color: #22568c;
    background: linear-gradient(180deg, #eef4fa 0%, #ffffff 100%);
    box-shadow: 0 1px 0 #d7e6f4, 0 6px 16px rgba(15, 33, 63, 0.12);
    transform: translateY(-1px);
}

.audience-toggle-input:checked + .audience-toggle-card::after {
    content: "✓";
    position: absolute;
    top: 10px;
    right: 12px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: #22568c;
    color: #ffffff;
    font-weight: 800;
    font-size: 14px;
    line-height: 26px;
    text-align: center;
    box-shadow: 0 2px 6px rgba(15, 33, 63, 0.35);
}

.audience-toggle-emoji {
    font-size: 28px;
    line-height: 1;
    margin-bottom: 2px;
}

.audience-toggle-title {
    font-size: 16px;
    font-weight: 700;
    color: #181b21;
    line-height: 1.25;
}

.audience-toggle-sub {
    font-size: 13px;
    color: #6c7280;
    line-height: 1.35;
}

/* ──────────────────────────────────────────────────────────────
   Rich HTML email editor (Quill) - styled to match the Tailwind UI
   ────────────────────────────────────────────────────────────── */
.cs-editor-wrap .ql-toolbar.ql-snow {
    border: 1px solid #ced2dd;
    border-bottom: none;
    border-radius: 0.75rem 0.75rem 0 0;
    background: #f7f8fa;
    padding: 8px 10px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
}

/* Toolbar groups, separated by a soft divider so related controls read as a set.
   Tailwind's CDN preflight resets <button>/<svg>, which strips Quill's own toolbar
   styling - so we restyle the buttons and pickers from scratch here. */
.cs-editor-wrap .ql-toolbar.ql-snow .ql-formats {
    margin: 0;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding-right: 8px;
    border-right: 1px solid #e4e6ed;
}

.cs-editor-wrap .ql-toolbar.ql-snow .ql-formats:last-child {
    border-right: none;
    padding-right: 0;
}

/* Each toolbar control is a proper, tappable, rounded button. */
.cs-editor-wrap .ql-toolbar.ql-snow button {
    width: 32px;
    height: 32px;
    padding: 5px;
    border: none;
    border-radius: 8px;
    background: transparent;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    float: none;
    transition: background-color .12s ease;
}

.cs-editor-wrap .ql-toolbar.ql-snow button svg {
    width: 18px;
    height: 18px;
}

.cs-editor-wrap .ql-toolbar.ql-snow button:hover,
.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-label:hover {
    background: #e4e6ed;
}

.cs-editor-wrap .ql-toolbar.ql-snow button .ql-stroke,
.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-label .ql-stroke {
    stroke: #4e5461;
}

.cs-editor-wrap .ql-toolbar.ql-snow button .ql-fill,
.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-label .ql-fill {
    fill: #4e5461;
}

/* Active / hovered controls pick up the brand blue. */
.cs-editor-wrap .ql-toolbar.ql-snow button.ql-active,
.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-label.ql-active {
    background: #eef4fa;
}

.cs-editor-wrap .ql-toolbar.ql-snow button.ql-active .ql-stroke,
.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-label.ql-active .ql-stroke,
.cs-editor-wrap .ql-toolbar.ql-snow button:hover .ql-stroke,
.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-label:hover .ql-stroke {
    stroke: #1b4472;
}

.cs-editor-wrap .ql-toolbar.ql-snow button.ql-active .ql-fill,
.cs-editor-wrap .ql-toolbar.ql-snow button:hover .ql-fill {
    fill: #1b4472;
}

/* Dropdown pickers (heading level, text colour). */
.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker {
    height: 32px;
    display: inline-flex;
    align-items: center;
    color: #4e5461;
    font-size: 14px;
    font-weight: 500;
}

.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-label {
    border: none;
    border-radius: 8px;
    padding: 0 6px;
    display: inline-flex;
    align-items: center;
}

.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-label::before {
    line-height: 32px;
}

.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-options {
    border-radius: 10px;
    border: 1px solid #e4e6ed;
    box-shadow: 0 10px 28px rgba(15, 23, 42, 0.14);
    padding: 6px;
}

.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-item:hover,
.cs-editor-wrap .ql-toolbar.ql-snow .ql-picker-item.ql-selected {
    color: #1b4472;
}

.cs-editor-wrap .ql-container.ql-snow {
    border: 1px solid #ced2dd;
    border-radius: 0 0 0.75rem 0.75rem;
    font-family: "Poppins", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    font-size: 16px;
    background: #ffffff;
}

.cs-editor-wrap .ql-editor {
    min-height: 240px;
    line-height: 1.6;
    color: #181b21;
}

.cs-editor-wrap .ql-editor.ql-blank::before {
    color: #9ba1b0;
    font-style: normal;
}

/* Brand-blue focus ring to match the rest of the app. */
.cs-editor-wrap:focus-within .ql-toolbar.ql-snow,
.cs-editor-wrap:focus-within .ql-container.ql-snow {
    border-color: #2f6faf;
}

/* Friendly blockquote = the "info card" used in templates. */
.cs-editor-wrap .ql-editor blockquote {
    border-left: 4px solid #22568c;
    background: #f7f8fa;
    border-radius: 8px;
    padding: 12px 16px;
    margin: 0 0 12px;
    color: #3a3f4a;
}

/* Raw HTML source view. */
.cs-html-source {
    width: 100%;
    min-height: 280px;
    border: 1px solid #ced2dd;
    border-radius: 0.625rem;
    padding: 12px 14px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    line-height: 1.55;
    color: #181b21;
    background: #ffffff;
}

.cs-html-source:focus {
    outline: none;
    border-color: #2f6faf;
    box-shadow: 0 0 0 1px #2f6faf;
}

.cs-source-toggle.cs-source-active {
    background: #eef4fa;
    border-color: #2f6faf;
    color: #1b4472;
}

/* Attachment chips (selected files on the send / template forms). */
.cs-attachment-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #eef4fa;
    border: 1px solid #b4d0e9;
    color: #0f213f;
    border-radius: 9999px;
    padding: 4px 12px;
    font-size: 13px;
    font-weight: 500;
}

/* ════════════════════════════════════════════════════════════════
   CampSuite Design System - reusable components
   ----------------------------------------------------------------
   The single source of truth for buttons, inputs, cards, page
   headers and the Save/action bar. Use these class names on new and
   updated screens so every page looks and behaves the same way.
   See DESIGN.md for the full pattern guide.
   ════════════════════════════════════════════════════════════════ */

/* ── Buttons ─────────────────────────────────────────────────────
   .cs-btn is the base; add a variant that says what the action IS.

   Eight roles, and the treatment follows the role rather than the other way
   round. The distinction that matters most is between a decision and a
   command: an everyday working command is NOT a quiet CTA, and drawing it as
   one is what turns a record toolbar into a row of identical outlined
   rectangles.

     cs-btn-primary         the one main action here          deep blue, filled
     cs-btn-brand           the booking-led CTA               orange, filled
     cs-btn-secondary       a real alternative decision       white, blue outline
     cs-btn-command         an everyday working command       no box until hovered
     cs-btn-command-danger  a sharp command, kept quiet       no box, red on hover
     cs-btn-danger          destructive, and says so at rest  white, red outline
     cs-btn-icon            an icon-only control              square, no box
     cs-btn-link            a text action                     underlined on hover

   "Secondary" is not "everything that is not primary". A toolbar of commands
   wearing cs-btn-secondary is the single biggest reason a dense screen reads
   as generated - see DESIGN.md section 7. */
.cs-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 48px;
    padding: 0.75rem 1.5rem;
    /* 8px. Calmer than the 10px this used to be and a long way from Tailwind's
       stock 16px: the geometry of an application button, not of a landing-page
       CTA. Grid furniture goes further down still, to 4px, and that step is
       deliberate - see DESIGN.md "The working grid". */
    border-radius: 0.5rem;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
    border: 1.5px solid transparent;
    cursor: pointer;
    text-align: center;
    transition: background-color .15s ease, border-color .15s ease,
                color .15s ease, transform .08s ease;
    -webkit-tap-highlight-color: transparent;
}

.cs-btn:active { transform: translateY(1px); }

.cs-btn:focus-visible {
    outline: 3px solid #22568c;
    outline-offset: 2px;
}

/* Above the phone, and only under a pointer that can be precise, the action
   button is 44px rather than 48. A finger needs the height and a mouse does
   not, and paying the finger's price on a laptop is part of what makes an
   operational screen feel like a phone app. Anything with a coarse pointer
   keeps 48 whatever the width, which is the case that matters: a tablet at
   reception is a wide screen being poked. */
@media (min-width: 640px) and (pointer: fine) {
    .cs-btn { min-height: 44px; padding: 0.6rem 1.35rem; }
}

/* Primary = THE main action on this surface: Save, Confirm, Approve, Send.
   Deep Blue with white words - the brand's own ink, so the main action on every
   screen is unmistakably CampSuite and still the strongest thing on it.

   It used to be Sunset Orange, which put orange on nearly every screen: a Save,
   an Add guest and the top bar's Take a booking side by side, each shouting.
   Orange is the brand's one spark and it belongs to the booking, so it moved to
   cs-btn-brand alone and the main action took the deep blue the logo sits on.
   The brand icon's orange accent reads on it exactly as the mark does on the bar.

   Flat. Depth is for cards, modals and dropdowns - things genuinely above the page. */
.cs-btn-primary {
    background: #0f213f;
    color: #fff;
}
.cs-btn-primary:hover { background: #1b3358; }
.cs-btn-primary:active { background: #0a1830; }

/* Brand = the booking, and only the booking: Take a booking in the top bar, Create
   booking at the foot of the form. Sunset Orange with deep-blue words, the pairing
   of the logo. If a screen has two orange things, one of them is wrong. */
.cs-btn-brand {
    background: #f06436;
    color: #0f213f;
}
.cs-btn-brand:hover { background: #e0561f; }
.cs-btn-brand:active { background: #cf4a15; }

/* Secondary = the alternative the person is being offered beside the primary:
   Cancel, Go back, Not now, Keep the existing booking. A deep-blue outline,
   clearly on-brand and quieter than the orange.

   Reserve it for a genuine decision. It is NOT the class for an everyday
   command - that is cs-btn-command, and reaching for this instead is what
   produces a toolbar of eight identical capsules. No shadow: an outline is
   already a boundary, and border plus radius plus shadow plus background on
   every clickable thing is the generated-dashboard combination. */
.cs-btn-secondary {
    background: #fff;
    color: #22568c;
    border-color: #b4d0e9;
}
.cs-btn-secondary:hover { background: #eef4fa; border-color: #22568c; }
.cs-btn-secondary:active { background: #d7e6f4; }

/* Danger = destructive, and it has to say so where it stands: the confirm
   inside a delete dialog, the button on a Delete page. Quiet until hovered,
   but never mistakable for an ordinary action.

   For a destructive command sitting on a working toolbar, use
   cs-btn-command-danger instead. A red-outlined box parked permanently on a
   record bar is a warning nobody reads by the second week. */
.cs-btn-danger {
    background: #fff;
    color: #b42318;
    border-color: #f4c9c4;
}
.cs-btn-danger:hover { background: #fef3f2; border-color: #e8a59d; }
.cs-btn-danger:active { background: #fde3e0; }

/* ── The working command ─────────────────────────────────────────
   Send message. Add payment. Refund. Raise an invoice. Print. Export. Check
   in. The everyday verbs on a record, a toolbar or a grid.

   No box at rest. A command is a thing you do, not an offer being made, and a
   dense screen where every verb wears its own bordered capsule reads as a wall
   of competing CTAs - which is exactly what Dynamics, Sage and Xero all avoid
   by drawing their command bars this way. The picture and the word carry it;
   the surface appears under the pointer, which is where the person already is.
   40px tall, so it is still a real target with a finger.

   This is the class most working screens should be reaching for, and the one
   that was missing: everything that was not the main action became
   cs-btn-secondary by default, and the bar filled up with them. */
.cs-btn-command {
    background: transparent;
    color: #262a32;
    border-color: transparent;
    /* A command is a picture and a verb, one to three words by design. Wrapping "Take away"
       over two lines inside a narrow action column makes a toolbar look broken, and the
       record bar was already saying so for its own copy of these. */
    white-space: nowrap;
    min-height: 40px;
    padding: 0.4rem 0.7rem;
    /* Six, against the button's eight. A command sits in a row of its own kind
       and softens as the row gets longer; the tighter corner keeps a bar of six
       of them reading as one toolbar rather than as six separate controls. */
    border-radius: 0.375rem;
    font-size: 0.9375rem;
    font-weight: 600;
    gap: 0.45rem;
}
.cs-btn-command:hover { background: #eef4fa; color: #1b4472; }
.cs-btn-command:active { background: #d7e6f4; }
/* Doing something right now, or holding its menu open. The wash on its own
   would be the hover state again, so the ink deepens with it. */
.cs-btn-command.is-active,
.cs-btn-command[aria-expanded="true"],
.cs-btn-command[aria-current="true"] { background: #eef4fa; color: #1b4472; }

/* The sharp end of a command bar. Everything here is already guarded by a
   dialog or its own confirm page, so this is about telling the eye where the
   sharp commands are rather than about stopping a press: neutral until you go
   near it, red when you do. Colour is never the only signal - the label says
   Delete and the glyph is a bin. */
.cs-btn-command-danger {
    background: transparent;
    color: #4e5461;
    border-color: transparent;
    white-space: nowrap;
    min-height: 40px;
    padding: 0.4rem 0.7rem;
    border-radius: 0.375rem;
    font-size: 0.9375rem;
    font-weight: 600;
    gap: 0.45rem;
}
.cs-btn-command-danger > svg { color: #9ba1b0; }
@media (hover: hover) {
    .cs-btn-command-danger:hover { background: #fef3f2; color: #b42318; }
    .cs-btn-command-danger:hover > svg { color: #b42318; }
}
/* Under a finger a command is 48px like every other target (§1), not 40: the
   command bar is where a phone user's thumb spends its time. */
@media (pointer: coarse) {
    .cs-btn-command,
    .cs-btn-command-danger { min-height: 48px; }
}
.cs-btn-command-danger:active { background: #fde3e0; color: #b42318; }
.cs-btn-command-danger:focus-visible { color: #b42318; }
.cs-btn-command-danger:focus-visible > svg { color: #b42318; }

/* A command's glyph, sized by the class rather than by the markup, so a caller
   passes an empty class and cannot get it wrong. The brand set is two-tone - a
   currentColor line drawing with one Sunset Orange element - so a command is
   the same picture on the bar as it is in the menu that got you to the screen.
   A destructive glyph carries no orange, because the danger state recolours the
   whole drawing and an accent that stayed put would read as a fault. */
.cs-btn-command > svg,
.cs-btn-command-danger > svg {
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
}

/* An icon on its own: a close, a remove, a fold. Square, so it does not read as
   a button that has lost its label. */
.cs-btn-icon {
    background: transparent;
    color: #4e5461;
    border-color: transparent;
    min-height: 40px;
    min-width: 40px;
    padding: 0.4rem;
    border-radius: 0.375rem;
    gap: 0;
}
.cs-btn-icon:hover { background: #eef4fa; color: #1b4472; }
.cs-btn-icon:active { background: #d7e6f4; }
.cs-btn-icon > svg { flex: none; width: 1.25rem; height: 1.25rem; }
/* Under a finger an icon on its own is 48px too (§1), on the console's own pages. The website
   editor keeps its own 44px rule inside its panels (cs-site-editor.css), which this does not reach. */
@media (pointer: coarse) {
    .cs-page .cs-btn-icon { min-width: 48px; min-height: 48px; }
}

/* A text action. Not a button at all to look at, but it keeps a real target
   height so it can still be hit with a thumb. */
.cs-btn-link {
    background: transparent;
    color: #22568c;
    border-color: transparent;
    min-height: 40px;
    padding: 0.25rem;
    font-size: 0.9375rem;
    text-decoration: none;
}
.cs-btn-link:hover { color: #1b4472; text-decoration: underline; text-underline-offset: 3px; }
.cs-btn-link:active { transform: none; }

/* A link INSIDE a sentence, which is not the same thing as cs-btn-link above.
   cs-btn-link is a control: it carries a 40px tap target and its own padding, so
   dropping one into a paragraph pushes the line it sits in apart. This is the
   other half of that pair - it takes the size of the prose around it and says
   "link" with colour, weight and an underline on hover.

   The customer portal had already worked this out and had shipped the class; the
   operator app had grown about a dozen answers to the same question instead
   (`text-emerald-700 underline`, `font-medium text-slate-900 hover:underline`, a
   bare `hover:underline`), and three links on Park details were asking for
   `cs-link` by name against a sheet that had never defined it, so they rendered
   in raw browser blue. The portal's definition is the one, unchanged, in all
   three sheets. */
.cs-link {
    color: #22568c;
    font-weight: 600;
    text-decoration: none;
    border-radius: 4px;
}
.cs-link:hover { color: #1b4472; text-decoration: underline; }
.cs-link:focus-visible { outline: 3px solid #22568c; outline-offset: 2px; }

.cs-btn-block { width: 100%; }

/* Small = compact toolbar / modal-header buttons. Still a comfortable tap
   target (40px) but tighter than the full-size action button. */
.cs-btn-sm {
    min-height: 40px;
    padding: 0.4rem 0.85rem;
    font-size: 0.9375rem;
    border-radius: 0.375rem;
    gap: 0.35rem;
}
@media (min-width: 640px) and (pointer: fine) {
    .cs-btn-sm { min-height: 36px; padding: 0.35rem 0.75rem; }
    /* A command is already at command height and does not shrink again with
       the rest: 36px is below what a bar somebody drives all day should ask
       of them, mouse or no mouse. */
    .cs-btn-command,
    .cs-btn-command-danger,
    .cs-btn-icon,
    .cs-btn-link { min-height: 40px; padding: 0.4rem 0.7rem; }
    .cs-btn-icon { padding: 0.4rem; }
    .cs-btn-link { padding: 0.25rem; }
}

/* ── Segmented chip (radio "pills") ──────────────────────────────
   A branded, grandma-proof way to pick one of a few options (priority,
   frequency). Big tap target, clear selected state in brand blue. Wrap a
   hidden radio input and a label span; the whole chip is the tap target. */
.cs-segchip {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    min-height: 44px;
    padding: 0.5rem 0.5rem;
    border-radius: 0.5rem;
    border: 1.5px solid #e4e6ed;
    background: #fff;
    color: #4e5461;
    font-weight: 600;
    font-size: 0.9375rem;
    line-height: 1.1;
    text-align: center;
    cursor: pointer;
    transition: border-color .12s ease, background-color .12s ease, color .12s ease, box-shadow .12s ease;
    -webkit-tap-highlight-color: transparent;
}
.cs-segchip:hover { border-color: #c3c8d3; }
.cs-segchip:has(input:checked) {
    background: #22568c;
    border-color: #22568c;
    color: #fff;
    box-shadow: 0 1px 2px rgba(34, 86, 140, .25);
}
.cs-segchip:has(input:focus-visible) { outline: 3px solid rgba(34, 86, 140, .4); outline-offset: 1px; }

/* ── Form fields ─────────────────────────────────────────────────
   .cs-input works for input / select / textarea. */
.cs-input {
    width: 100%;
    border-radius: 0.625rem;
    border: 1.5px solid #ced2dd;
    background: #fff;
    padding: 0.75rem 1rem;
    font-size: 1rem;
    color: #181b21;
    box-shadow: 0 1px 2px rgba(24, 27, 33, .04);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.cs-input::placeholder { color: #9ba1b0; }
.cs-input:focus {
    outline: none;
    border-color: #22568c;
    box-shadow: 0 0 0 4px rgba(34, 86, 140, .15);
}
/* A field somebody has to change before it is saved. The words under it (a
   cs-verdict or a cs-hint it is described by) say why; the rose border says
   which field, and it stays rose while the field has focus. */
.cs-input[aria-invalid="true"] { border-color: #b42318; }

.cs-label {
    display: block;
    font-size: 1rem;
    font-weight: 600;
    color: #262a32;
    margin-bottom: 0.375rem;
}
.cs-hint { font-size: 1rem; color: #6c7280; margin-top: 0.375rem; }
/* A field the server refused, and what it said about it, in the one colour the state map
   gives a problem. The validation tag helpers only add these classes when there is an error,
   so nothing else is touched. Declared here, after .cs-hint, because the message is usually a
   cs-hint and would otherwise print its complaint in the same quiet grey as its advice. */
.cs-hint.field-validation-error,
.field-validation-error { color: #b42318; }
.cs-input.input-validation-error { border-color: #b42318; }
/* A merge field named inside a sentence ("Any email with [GuidebookLink] in it..."), so the
   owner can see it is the thing to type into a template, not part of the prose. */
.cs-token {
    padding: 0.05rem 0.3rem;
    border-radius: 0.25rem;
    background: #f1f2f6;
    color: #262a32;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.8125rem;
    white-space: nowrap;
}

/* ── Cards ───────────────────────────────────────────────────────
   The standard container for content & form sections. */
.cs-card {
    border-radius: 0.75rem;                /* 12px - calm, ledger-like */
    border: 1px solid #e6e9ef;
    background: #fff;
    overflow: hidden;
}
/* The title sits at the top of the panel it names, with no bar of its own under
   it. A header strip ruled off from its body is the Bootstrap card every admin
   template is built from; a heading and the content under it is a page. */
.cs-card-header {
    background: #fff;
    padding: 1.125rem 1.25rem 0.875rem;
}
.cs-card-header + .cs-card-body { padding-top: 0; }
.cs-card-title { font-size: 1.125rem; font-weight: 600; color: #0f213f; letter-spacing: -0.01em; }
.cs-card-sub   { font-size: 1rem; color: #6c7280; margin-top: 0.125rem; }
.cs-card-body  { padding: 1.25rem; }

/* A card holding a temporary state that is currently ON and wants noticing every
   time the screen is opened: outreach sending paused, a park suspended, a queue
   stopped. Rose per the DESIGN.md section 8 state map, and always paired with an
   icon and the word, never colour alone. Use the plain .cs-card for the same
   panel when the state is off - a panel that is rose all year stops meaning
   anything. Ported from the operator sheet; see DESIGN.md section 12. */
.cs-card-alert { border-color: #f3cfcf; background: #fdf6f5; }
.cs-card-alert .cs-card-header { border-bottom-color: #f3cfcf; background: #fbeceb; }

/* ── Soft panel and inline notice ────────────────────────────────
   A soft panel INSIDE a card, for one self-contained rule set apart from the
   fields around it; and the short, in-flow "before you do that" beside the
   field it is about, rather than a card or a toast. cs-notice-amber is "are
   you sure" and cs-notice-rose is "this is wrong", per the DESIGN.md section 8
   map; the plain class is neutral. Always a title AND a sentence, so it reads
   without the colour.

   Ported from the operator sheet, where these have always been. DESIGN.md
   section 11 has documented cs-subpanel as an admin class for some time
   against a stylesheet that had never carried it, so a console page asking
   for it got no panel at all. See section 12 on the copies. */
.cs-subpanel {
    border-radius: 0.75rem;
    border: 1px solid #e4e6ed;
    background: #f7f8fa;
    padding: 1rem;
}

/* ── Inline notice (cs-notice) ────────────────────────────────────
   A short, in-flow "before you do that" beside the field it is about, rather
   than a card or a toast. The consequence of a currency change sits inside the
   country/currency panel; a fire ban gets a .cs-card-alert instead, because that
   is a whole panel about a state rather than a sentence about a field.

   Amber is "are you sure" per the §8 state map; rose is "this is wrong". Always
   a heading plus the sentence, so it reads without the colour. */
.cs-notice {
    border-radius: 0.75rem;
    border: 1px solid #e4e6ed;
    background: #fff;
    padding: 0.85rem 1rem;
}
.cs-notice-title { font-size: 1rem; font-weight: 600; color: #181b21; }
.cs-notice-body  { font-size: 1rem; color: #414652; margin-top: 0.25rem; }
/* A text action on a line of its own in a notice ("Show the steps for Wix") keeps its 40px
   target, but starts on the text's edge at the text's size, as a cs-link beside it does: the
   margin takes back cs-btn-link's padding and cs-btn's border, which Chrome draws 1px wide. */
.cs-notice-body > .cs-btn-link { margin-left: calc(-0.25rem - 1px); font-size: inherit; }

/* A long action in a notice wraps inside it rather than running off the edge of
   a phone: a command is nowrap in a toolbar, but a notice is prose. */
.cs-notice .cs-btn { white-space: normal; text-align: left; max-width: 100%; }

/* Amber and rose are a dot before the title, not a wash over the whole box: the
   tinted panel with brown text on cream was the generated-dashboard alert. The
   words still carry it, so the body stays in the ordinary secondary ink. */
.cs-notice-amber .cs-notice-title::before,
.cs-notice-rose .cs-notice-title::before {
    content: "";
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    margin-right: 0.5rem;
    border-radius: 9999px;
    vertical-align: 0.12em;
    background: #c98a1a;
}
.cs-notice-rose .cs-notice-title::before { background: #c0392b; }

.cs-notice-rose { border-color: #f3cfcf; }
.cs-notice-rose .cs-notice-title { color: #8c2f24; }

/* The one panel on a screen that is allowed to invert: a deep-blue card for the
   door out of this screen and into a conversation. One per screen, and never for
   a panel somebody has to read a form inside. */
.cs-card-deep {
    border-color: #0f213f;
    background: #0f213f;
    color: #fff;
}
.cs-card-deep .cs-card-header { border-bottom-color: rgba(255, 255, 255, .16); background: transparent; }
.cs-card-deep .cs-card-title  { color: #fff; }
.cs-card-deep .cs-card-sub    { color: #c6d2e2; }
.cs-card-deep a:not([class])  { color: #fff; text-decoration: underline; }

.cs-card-link { transition: border-color .15s ease, background-color .15s ease; }
/* A link that is a panel answers the pointer by lighting up where it is, not by
   floating off the page: the hover lift and its shadow were the template tell. */
.cs-card-link:hover {
    border-color: #c9d6e6;
    background: #fafbfd;
}
/* The deep-blue card keeps its sky when the pointer is on it: a paler blue, never the
   near-white above, which would wipe out its white words. */
.cs-card-deep.cs-card-link:hover {
    border-color: #22568c;
    background: #13284a;
}


/* ── Channel logos ───────────────────────────────────────────────
   A sales channel is recognised by its own logo, not by our styling of
   its name, so the Channels screens show each brand's real artwork at
   one consistent height. Never recolour or crop them; they sit on our
   warm paper surfaces as supplied. Rendered through the shared
   _ChannelLogo partial - don't hand-roll an <img> next to a name. */
.cs-channel-logo {
    display: inline-flex;
    align-items: center;
    height: 1.75rem;                       /* card size */
    max-width: 11rem;
}
.cs-channel-logo img {
    height: 100%;
    width: auto;
    max-width: 100%;
    object-fit: contain;
}
/* A stacked lockup (mark above the name, e.g. Pitchup) is mostly picture, so
   at a wordmark's height its name is unreadable. Give it roughly double so the
   two sit at the same optical weight side by side. */
.cs-channel-logo-stacked { height: 3.25rem; }

/* The channel's own screen, where the logo stands in for the page title. */
.cs-channel-logo-lg { height: 2.5rem; max-width: 15rem; }
.cs-channel-logo-lg.cs-channel-logo-stacked { height: 4.5rem; }

/* Channels with no artwork of their own (a plain iCal link) still need
   something to recognise, so they get a warm wordmark chip instead. */
.cs-channel-wordmark {
    display: inline-flex;
    align-items: center;
    height: 1.75rem;
    padding: 0 0.625rem;
    border-radius: 0.5rem;
    background: #f1f2f6;                   /* Sand */
    color: #181b21;
    font-weight: 700;
    font-size: 0.9375rem;
    letter-spacing: -0.01em;
    white-space: nowrap;                   /* a chip is one line, never a wrapped block */
}
.cs-channel-wordmark.cs-channel-logo-lg { height: 2.5rem; font-size: 1.125rem; padding: 0 0.875rem; }

/* ── Settings hub (/settings) ────────────────────────────────────
   A calm, scannable launcher: one branded icon per destination so an
   owner recognises where to go at a glance. Grandma-proof - big tap
   targets, 16px+ copy, and ONE consistent icon treatment (brand blue
   on a pale brand tint), never a rainbow of chips. The icon "d" paths
   live in Code/SettingsMenu.cs, shared with the sidebar accordion. */
.cs-settings-search { position: relative; margin-top: 1.25rem; }
/* The field itself is a standard .cs-input (radius, border, focus ring and all);
   this only adds clearance for the leading magnifier. */
.cs-settings-search input { padding-left: 3rem; }
.cs-settings-search svg {
    position: absolute;
    left: 1rem; top: 50%; transform: translateY(-50%);
    height: 1.25rem; width: 1.25rem;
    color: #9ba1b0; pointer-events: none;
}

.cs-settings-group { margin-top: 2rem; }
.cs-settings-heading {
    font-size: 1rem;
    font-weight: 600;
    color: #0f213f;
}

.cs-settings-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.875rem;
    margin-top: 0.875rem;
}
@media (min-width: 640px)  { .cs-settings-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .cs-settings-grid { grid-template-columns: repeat(3, 1fr); } }

/* Composed as `cs-card cs-card-link cs-settings-card` in the markup, so the
   border, shadow, hover lift and the global keyboard focus ring all come from
   the shared card components; this class adds the icon/body/chevron row and the
   menu-style way-finding accent. */
.cs-settings-card {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
    width: 100%;
    padding: 1.0625rem 1.125rem 1.0625rem 1.5rem;
    text-align: left;
}
/* Sunset Orange way-finding bar - the SAME accent the active sidebar item uses
   (.cs-nav-link-active::before), so the hub reads as one system with the menu. */
.cs-settings-card::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.8125rem;
    bottom: 0.8125rem;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: #f06436;
}
/* On hover the whole card lights up like a menu item coming active: brand tint
   plus brand-blue icon and title. */
.cs-settings-card:hover { background: #eef4fa; }
/* The search filter toggles Tailwind's .hidden; site.css loads after the
   Tailwind layer, so this 2-class rule must win over the flex display above or
   matched-out cards would stay visible. */
.cs-settings-card.hidden { display: none; }

/* The icon matches the sidebar menu icons: no chip, drawn in the same warm ink
   (currentColor), so the hub and the nav render the icon identically. */
.cs-settings-ico {
    flex: none;
    display: grid; place-items: start center;
    height: 1.75rem; width: 1.75rem;
    margin-top: 0.0625rem;
    color: #3a3f4a;
    transition: color .15s ease;
}
.cs-settings-ico svg { height: 1.5rem; width: 1.5rem; }
.cs-settings-card:hover .cs-settings-ico,
.cs-settings-card:hover .cs-settings-title { color: #16365a; }

.cs-settings-body { min-width: 0; flex: 1 1 auto; }
.cs-settings-title {
    display: block;
    font-size: 1.0625rem;
    font-weight: 600;
    color: #181b21;
    line-height: 1.3;
}
.cs-settings-desc {
    display: block;
    margin-top: 0.25rem;
    font-size: 1rem;
    color: #4e5461;
    line-height: 1.45;
}

.cs-settings-go {
    flex: none; align-self: center;
    height: 1.25rem; width: 1.25rem;
    color: #ced2dd;
    transition: color .15s ease, transform .15s ease;
}
.cs-settings-card:hover .cs-settings-go { color: #22568c; transform: translateX(2px); }

/* "Nothing matches that search" panel. */
.cs-settings-empty {
    margin-top: 2.5rem;
    border-radius: 0.75rem;
    border: 1px dashed #ced2dd;
    background: #fff;
    padding: 2rem;
    text-align: center;
}

/* ── Page container ──────────────────────────────────────────────
   The one gutter a screen gets. `_Layout`'s <main> already pads the
   content area, and every page then opened with its own
   `max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 sm:py-8` - so a phone
   paid the gutter twice. On a 402px iPhone that is 64px of nothing down
   the sides and 48px of nothing above the title, which is why a folded
   booking card came out 304px wide and wrapped "Fri 28 Aug to Mon 31
   Aug" onto two lines.

   `cs-page` owns the width, the gutter and the top rhythm, and <main>
   stands down when it holds one (the `:has` rule below). Desktop lands
   in exactly the same place as before; the phone gets its 64px back.

   Width comes from --cs-page-max so a narrower screen (a settings form,
   a single report) picks a modifier rather than hand-rolling a
   max-width beside it. The gutter uses env(safe-area-inset-*) so a
   landscape iPhone keeps its content clear of the notch. */
.cs-page {
    --cs-page-max: 80rem;                          /* list screens: was max-w-7xl */
    width: 100%;
    max-width: var(--cs-page-max);
    margin-inline: auto;
    padding-top: 1.5rem;
    padding-bottom: 1.5rem;
    padding-left: max(1rem, env(safe-area-inset-left));
    padding-right: max(1rem, env(safe-area-inset-right));
}
.cs-page-md { --cs-page-max: 64rem; }              /* was max-w-5xl */
.cs-page-lg { --cs-page-max: 72rem; }              /* was max-w-6xl */
.cs-page-sm { --cs-page-max: 48rem; }              /* one column of fields: was max-w-3xl */

/* A record screen fills the shell rail. `body.cs-chrome-top main` caps
   everything at 96rem already, so this is not "wider than the app": it is
   a page declining to draw a second, narrower box inside the first. Use it
   for a screen somebody works in (a booking, a guest), never for a form
   with one column of fields - a 1536px line length is unreadable. */
.cs-page-xl { --cs-page-max: 96rem; }

@media (min-width: 640px) {
    .cs-page {
        padding-top: 2rem;
        padding-bottom: 2rem;
        padding-left: max(1.5rem, env(safe-area-inset-left));
        padding-right: max(1.5rem, env(safe-area-inset-right));
    }
}
@media (min-width: 1024px) {
    .cs-page {
        padding-left: max(2rem, env(safe-area-inset-left));
        padding-right: max(2rem, env(safe-area-inset-right));
    }
}

/* <main> keeps its bottom padding - that is what holds content clear of
   the phone bottom bar - and hands the rest to the page container. */
body.cs-app main:has(> .cs-page) {
    padding-top: 0;
    padding-left: 0;
    padding-right: 0;
}

/* ── Page header ─────────────────────────────────────────────────
   Consistent title block at the top of every screen. */
.cs-page-header {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}
@media (min-width: 640px) {
    .cs-page-header {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }
}
.cs-page-title {
    font-family: "Poppins", "Segoe UI", system-ui, sans-serif;
    font-optical-sizing: auto;
    font-size: 1.875rem;
    font-weight: 700;
    color: #0f213f;
    line-height: 1.12;
    letter-spacing: -0.025em;
    /* Some titles are typed by the public (a guest's name on an open website message): an
       address or a run with no spaces breaks where it has to rather than pushing the page
       sideways. break-word, not anywhere, so an ordinary title still sizes itself by its words. */
    overflow-wrap: break-word;
}
.cs-page-sub   { margin-top: 0.25rem; color: #4e5461; }

/* ── Action bar ──────────────────────────────────────────────────
   THE home for Save / Cancel on every form.
   Desktop: right-aligned footer (primary on the right).
   Mobile : sticks to the bottom of the screen so Save is always
            reachable with a thumb - no hunting, grandma-proof. */
.cs-actionbar {
    display: flex;
    flex-direction: column-reverse;
    gap: 0.75rem;
    margin-top: 1.5rem;
}
.cs-actionbar .cs-btn { width: 100%; }

@media (min-width: 640px) {
    .cs-actionbar {
        flex-direction: row;
        align-items: center;
        justify-content: flex-end;
        gap: 0.75rem;
    }
    .cs-actionbar .cs-btn { width: auto; }
    /* When there's a destructive action it sits far left, away from Save. */
    .cs-actionbar .cs-actionbar-spacer { margin-right: auto; }
}

/* On small screens, pin the action bar to the bottom so the primary
   action is always one thumb-tap away. Opt in with .cs-actionbar-sticky. */
@media (max-width: 639px) {
    .cs-actionbar-sticky {
        position: sticky;
        bottom: 0;
        z-index: 20;
        margin-top: 1.5rem;
        margin-left: -1rem;
        margin-right: -1rem;
        padding: 0.875rem 1rem calc(0.875rem + env(safe-area-inset-bottom));
        background: rgba(250, 249, 246, .92);
        backdrop-filter: blur(8px);
        border-top: 1px solid #e4e6ed;
    }
}

/* ── Status pills / badges ───────────────────────────────────────── */
/* A status is a solid colour with the word on it, not a pale wash with the word
   printed faintly over the top. The tinted-chip-with-dark-text pattern is what
   every generated dashboard ships with, and at a glance down a list of forty
   bookings it disappears. A filled chip does not.

   Every fill clears 4.5:1 against white text, so the word is the signal and the
   colour is the reinforcement, which is the way round section 8 asks for.
   The radius is deliberate rather than a fully round pill: 6px reads as a
   deliberate object, and a stadium chip next to 10px inputs and 12px cards is
   the third radius in one row. */
.cs-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.22rem 0.6rem;
    border-radius: 0.375rem;
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: 0.005em;
    white-space: nowrap;
    color: #ffffff;
    background: #6c7280;
}
.cs-badge svg { opacity: .85; }
.cs-badge-brand   { background: #22568c; }
.cs-badge-neutral { background: #6c7280; }
.cs-badge-amber   { background: #92600a; }
.cs-badge-rose    { background: #b42318; }
.cs-badge-sky     { background: #2f6faf; }

/* ── Note timeline (guests and bookings) ────────────────────────────
   The running record on a guest or a booking: who wrote what, and when,
   newest at the top. Entries are never edited, so the list reads as a
   history rather than a notepad. A quiet blue spine ties the entries
   together; Delete only appears for owners and admins and stays low-key
   so nobody reaches for it by accident. Markup: Pages/Shared/_NoteTimeline.cshtml */
.cs-note-add { padding-bottom: 1.25rem; border-bottom: 1px solid #f1f2f6; }
.cs-note-empty {
    padding-top: 1.25rem;
    color: #6c7280;
    font-size: 1rem;
}

.cs-timeline {
    list-style: none;
    margin: 0;
    padding: 1.25rem 0 0;
}
.cs-timeline-item {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0 0 1.25rem 1.125rem;
}
/* The spine. It stops at the last entry so the list doesn't trail off. */
.cs-timeline-item::before {
    content: "";
    position: absolute;
    left: 0.3125rem;
    top: 0.75rem;
    bottom: -0.25rem;
    width: 2px;
    background: #e4e6ed;
}
.cs-timeline-item:last-child { padding-bottom: 0; }
.cs-timeline-item:last-child::before { display: none; }
.cs-timeline-dot {
    position: absolute;
    left: 0;
    top: 0.4375rem;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 9999px;
    background: #fff;
    border: 2px solid #4c8dcb;
}
.cs-timeline-body { flex: 1 1 auto; min-width: 0; }
.cs-timeline-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 0.9375rem;
}
.cs-timeline-author { font-weight: 700; color: #181b21; }
.cs-timeline-when { color: #6c7280; }
.cs-timeline-text {
    margin-top: 0.25rem;
    font-size: 1rem;
    line-height: 1.55;
    color: #3a3f4a;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.cs-timeline-actions { flex: 0 0 auto; }
.cs-timeline-delete {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border: none;
    border-radius: 0.5rem;
    background: transparent;
    color: #9ba1b0;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.cs-timeline-delete svg { width: 1.25rem; height: 1.25rem; }
.cs-timeline-delete:hover { background: #fff1f2; color: #b42318; }

/* ── Inventory cards (pitches / accommodation grid) ──────────────────
   A bespoke, branded tile - deliberately NOT a stock Tailwind
   `rounded-2xl border bg-white shadow` box. A quiet Sand header carries
   the code + status, the pitch-type colour is the one flash of accent as
   a hairline down the left edge, the name uses the display weight, and
   the footer separates a calm Edit from a low-key Delete. Everything sizes
   from the brand tokens so re-tuning the theme restyles these too. */
.cs-inv-grid {
    display: grid;
    grid-template-columns: repeat(1, minmax(0, 1fr));
    gap: 1rem;
}
@media (min-width: 640px)  { .cs-inv-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .cs-inv-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.cs-inv-card {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    border-radius: 0.75rem;
    border: 1px solid #e4e6ed;
    background: #fff;
    box-shadow: 0 1px 2px rgba(24, 27, 33, .04);
    overflow: hidden;
    transition: border-color .15s ease, box-shadow .15s ease, transform .12s ease;
}
.cs-inv-card:hover {
    border-color: #ced2dd;
    box-shadow: 0 14px 30px -16px rgba(15, 33, 63, .28);
    transform: translateY(-2px);
}
/* The pitch/accommodation type colour reads as a quiet spine, not a big block. */
.cs-inv-card__accent {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 4px;
    background: #9ba1b0;
}

/* Photo, or a warm branded placeholder when there isn't one. */
.cs-inv-card__media {
    height: 8.5rem;
    background: #f1f2f6;
    object-fit: cover;
    width: 100%;
    display: block;
}
.cs-inv-card__media--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(120% 140% at 100% 0%, rgba(76, 141, 203, .12), transparent 60%),
        linear-gradient(160deg, #f4f5f8 0%, #e9ebf1 100%);
    color: #aab0be;
}
.cs-inv-card__media--empty svg { width: 2.25rem; height: 2.25rem; }

.cs-inv-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.85rem 1.1rem 0.6rem 1.1rem;
}
.cs-inv-card__code {
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #7c8394;
}
.cs-inv-card__body { padding: 0 1.1rem 1rem 1.1rem; flex: 1 1 auto; }
.cs-inv-card__title {
    font-family: "Poppins", system-ui, sans-serif;
    font-size: 1.15rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: #0f213f;
    line-height: 1.25;
}
.cs-inv-card__meta {
    margin-top: 0.35rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.95rem;
    color: #6c7280;
}
.cs-inv-card__price {
    margin-top: 0.65rem;
    display: flex;
    align-items: baseline;
    gap: 0.35rem;
}
.cs-inv-card__price-amount {
    font-size: 1.25rem;
    font-weight: 700;
    color: #0f213f;
    font-variant-numeric: tabular-nums;
}
.cs-inv-card__price-unit { font-size: 0.9rem; color: #848a99; }
.cs-inv-card__tags {
    margin-top: 0.85rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.cs-inv-card__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0.75rem 0.6rem 1.1rem;
    border-top: 1px solid #f1f2f6;
    background: #f7f8fa;
}
.cs-inv-card__edit {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-height: 40px;
    padding: 0.4rem 0.9rem;
    border-radius: 0.5rem;
    font-weight: 600;
    color: #22568c;
    text-decoration: none;
}
.cs-inv-card__edit:hover { background: #eef4fa; }
.cs-inv-card__del {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0.4rem 0.75rem;
    border-radius: 0.5rem;
    font-weight: 600;
    color: #8e94a3;
    background: transparent;
    border: 0;
    cursor: pointer;
}
.cs-inv-card__del:hover { background: #fbecec; color: #b42318; }

/* ════════════════════════════════════════════════════════════════
   App chrome polish - sidebar, header, nav
   ════════════════════════════════════════════════════════════════ */

/* Warm, subtle paper backdrop behind the whole app. */
/* A light ground with the brand a couple of per cent into it, and white surfaces on
   top. Matched to the operator app: the wash across the top went with the parchment,
   because a tint nobody can name is decoration and section 7 does not allow a
   decorative gradient. What separates a card from the page is its border. */
body.cs-app { background: #f2f5f9; }

/* Sidebar gets a hairline brand edge + soft depth so it feels intentional. */
.cs-sidebar {
    background: #fff;
    border-right: 1px solid #e4e6ed;
    box-shadow: 1px 0 0 rgba(24, 27, 33, .02);
}

/* Sticky header lifts a touch once you scroll. */
.cs-header {
    background: rgba(255, 255, 255, .85);
    backdrop-filter: saturate(160%) blur(10px);
    border-bottom: 1px solid #e4e6ed;
}

/* Active nav item: brand tint + a left accent bar so the current
   section is unmistakable (helps non-tech users stay oriented). */
.cs-nav-link {
    position: relative;
    transition: background-color .15s ease, color .15s ease;
}
.cs-nav-link-active::before {
    content: "";
    position: absolute;
    left: -0.75rem;
    top: 0.5rem;
    bottom: 0.5rem;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: #f06436;   /* Sunset Orange - the active way-finding indicator */
}

/* ════════════════════════════════════════════════════════════════
   Horizontal top navigation (Ui:Navigation = "Horizontal")
   ----------------------------------------------------------------
   The branded app bar: a deep-blue canopy with the ridgeline
   from the CampSuite mark echoed as a whisper-quiet texture. Grouped
   drop-down menus (Xero/FreeAgent style), a context-aware "create"
   action and a global quick-create menu. Same destinations as the
   sidebar - only the chrome changes.
   ════════════════════════════════════════════════════════════════ */

.cs-topnav {
    position: sticky;
    top: 0;
    z-index: 30;
    color: #eef4fa;
    background:
        /* the brand ridgeline, barely-there, anchored to the bar's floor */
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='64' viewBox='0 0 480 64' fill='none'%3E%3Cpath d='M-8 50 L48 22 L84 42 L138 12 L196 50 L240 32 L288 50 L336 16 L384 40 L432 26 L488 50' stroke='%23eef4fa' stroke-opacity='0.045' stroke-width='2'/%3E%3C/svg%3E") repeat-x bottom left,
        linear-gradient(168deg, #183253 0%, #12253f 52%, #0f213f 100%);
    box-shadow:
        inset 0 -1px 0 rgba(238, 244, 250, .07),
        0 12px 32px -20px rgba(10, 24, 48, .65);
}

/* Full-height nav item wrapper so the active underline can sit on the
   bar's bottom edge, exactly where the eye expects it. */
.cs-topnav-item {
    position: relative;
    height: 100%;
    display: flex;
    align-items: center;
}
.cs-topnav-item.is-active::after {
    content: "";
    position: absolute;
    left: 0.625rem;
    right: 0.625rem;
    bottom: 0;
    height: 3px;
    border-radius: 3px 3px 0 0;
    background: #f06436;
}

.cs-topnav-link {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-height: 2.75rem;
    padding: 0 0.8125rem;
    border-radius: 0.625rem;
    border: none;
    background: transparent;
    font-size: 1rem;
    font-weight: 600;
    color: rgba(238, 244, 250, .82);
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}
.cs-topnav-link:hover { color: #fff; background: rgba(238, 244, 250, .09); }
.cs-topnav-link[aria-expanded="true"] { color: #fff; background: rgba(238, 244, 250, .13); }
.cs-topnav-item.is-active .cs-topnav-link { color: #fff; }
.cs-topnav-link:focus-visible {
    outline: 3px solid #f06436;
    outline-offset: -3px;
}
.cs-topnav-caret { transition: transform .18s ease; opacity: .7; }
.cs-topnav-link[aria-expanded="true"] .cs-topnav-caret { transform: rotate(180deg); }

/* Park switcher - a quiet glass pill on the canopy. */
.cs-topnav-park {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 1 auto;
    min-width: 6rem;   /* the park name may truncate but never vanishes */
    min-height: 2.75rem;
    max-width: 15rem;
    padding: 0.25rem 0.75rem;
    border-radius: 0.625rem;
    border: 1px solid rgba(238, 244, 250, .16);
    background: rgba(238, 244, 250, .06);
    color: #fff;
    font-size: 0.9375rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}
.cs-topnav-park:hover { background: rgba(238, 244, 250, .13); border-color: rgba(238, 244, 250, .28); }
.cs-topnav-park:focus-visible { outline: 3px solid #f06436; outline-offset: 2px; }
.cs-topnav-park-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The one always-there action - Take a booking - in Sunset Orange with
   deep-blue ink for contrast. Same label, same spot, on every page. */
.cs-topnav-cta {
    display: none;
    align-items: center;
    gap: 0.45rem;
    min-height: 2.75rem;
    padding: 0 1.125rem;
    border-radius: 0.625rem;
    background: #f06436;
    color: #0f213f;
    font-size: 0.9375rem;
    font-weight: 700;
    white-space: nowrap;
    text-decoration: none;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 2px 12px rgba(240, 100, 54, .35);
    transition: background-color .15s ease, transform .08s ease;
}
.cs-topnav-cta:hover { background: #e0561f; }
.cs-topnav-cta:active { transform: translateY(1px); }
.cs-topnav-cta:focus-visible { outline: 3px solid #eef4fa; outline-offset: 2px; }

@media (min-width: 768px) {
    .cs-topnav-cta { display: inline-flex; }
}

/* Drawer footer account block: a single quiet row that discloses the
   account actions on tap. Native details/summary - no JS to go wrong. */
.cs-drawer-account summary { list-style: none; }
.cs-drawer-account summary::-webkit-details-marker { display: none; }
.cs-drawer-account-row {
    display: flex; align-items: center; gap: 0.65rem;
    padding: 0.4rem 0.5rem; border-radius: 0.625rem; cursor: pointer;
}
.cs-drawer-account-row:hover { background: #f1f2f6; }
.cs-drawer-account-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    height: 2.1rem; width: 2.1rem; flex-shrink: 0; border-radius: 9999px;
    background: #eef4fa; color: #1b4472; font-size: 0.9rem; font-weight: 700;
}
.cs-drawer-account-caret { transition: transform .15s ease; }
.cs-drawer-account[open] .cs-drawer-account-caret { transform: rotate(180deg); }

/* The create button opens the booking-type chooser; the wrapper just
   anchors the drop-down panel. */
.cs-topnav-ctagroup { position: relative; display: flex; align-items: stretch; }
.cs-topnav-cta { border: none; cursor: pointer; }
.cs-topnav-ctagroup .cs-topnav-panel { top: calc(100% + 8px); }

/* Icon buttons on the bar (quick create, mobile menu). */
.cs-topnav-iconbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 2.75rem;
    width: 2.75rem;
    flex-shrink: 0;
    border-radius: 0.625rem;
    border: 1px solid rgba(238, 244, 250, .16);
    background: rgba(238, 244, 250, .06);
    color: #eef4fa;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}
.cs-topnav-iconbtn:hover { background: rgba(238, 244, 250, .13); border-color: rgba(238, 244, 250, .28); }
.cs-topnav-iconbtn:focus-visible { outline: 3px solid #f06436; outline-offset: 2px; }
.cs-topnav-iconbtn[aria-expanded="true"] { background: rgba(238, 244, 250, .16); }

/* Avatar (user menu trigger). Solid brand blue, light ring - no gradient. */
.cs-topnav-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 2.75rem;
    width: 2.75rem;
    flex-shrink: 0;
    border-radius: 9999px;
    border: none;
    background: #22568c;
    box-shadow: 0 0 0 2px rgba(238, 244, 250, .28);
    color: #fff;
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
    transition: box-shadow .15s ease;
}

/* The user menu lives in the bar on desktop; the drawer footer covers phones. */
.cs-topnav-user { display: none; }
@media (min-width: 1024px) {
    .cs-topnav-user { display: flex; align-items: center; }
}
.cs-topnav-avatar:hover,
.cs-topnav-avatar[aria-expanded="true"] { box-shadow: 0 0 0 3px rgba(238, 244, 250, .45); }
.cs-topnav-avatar:focus-visible { outline: 3px solid #f06436; outline-offset: 2px; }

/* Drop-down panels. Anchored to the item; springy but quick. */
.cs-topnav-panel {
    position: absolute;
    top: calc(100% - 6px);
    left: 0;
    z-index: 45;
    min-width: 16.5rem;
    max-width: min(34rem, calc(100vw - 1.5rem));
    padding: 0.5rem;
    border-radius: 0.75rem;
    background: #fff;
    border: 1px solid rgba(27, 24, 19, .08);
    box-shadow: 0 24px 48px -12px rgba(10, 24, 48, .3), 0 3px 10px rgba(10, 24, 48, .12);
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px) scale(.98);
    transform-origin: top left;
    transition: opacity .16s cubic-bezier(.16, 1, .3, 1),
                transform .16s cubic-bezier(.16, 1, .3, 1),
                visibility .16s;
}
.cs-menu-open > .cs-topnav-panel {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
}
.cs-topnav-panel-right { left: auto; right: 0; transform-origin: top right; }

/* Panels attached to the right-cluster buttons (quick create, user menu)
   hang just below their trigger rather than off the bar's floor. */
.cs-topnav-panel-below { top: calc(100% + 8px); }

.cs-topnav-brand { border-radius: 0.5rem; }
.cs-topnav-brand:focus-visible { outline: 3px solid #f06436; outline-offset: 3px; }

/* Brand lockup: the full CampSuite wordmark at every size on the top bar,
   including desktop. The links tighten (see below) rather than the logo
   dropping to the mark, so the brand name is always spelled out. */
.cs-topnav-logo-full { display: block; }
.cs-topnav-logo-mark { display: none; }

/* Narrow desktops (lg → xl): a gentle tighten so seven destinations, the
   park name and Take a booking fit without anything disappearing. */
@media (min-width: 1024px) and (max-width: 1279.98px) {
    .cs-topnav-link { padding: 0 0.5rem; font-size: 0.9375rem; }
    .cs-topnav-item.is-active::after { left: 0.5rem; right: 0.5rem; }
    .cs-topnav-park { min-width: 4.5rem; max-width: 9rem; padding: 0.25rem 0.5rem; }
    .cs-topnav-cta { padding: 0 0.875rem; font-size: 0.875rem; }
}
@media (min-width: 1280px) and (max-width: 1599.98px) {
    .cs-topnav-park { max-width: 12rem; }
}

/* Panel entries - big targets, plain-English labels. */
.cs-menu-heading {
    display: block;
    padding: 0.625rem 0.75rem 0.25rem;
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #6c7280;   /* ≥4.5:1 on white - headings stay readable, not decorative */
}
.cs-menu-item {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    min-height: 44px;
    padding: 0.55rem 0.75rem;
    border-radius: 0.625rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: #262a32;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color .12s ease, color .12s ease;
}
.cs-menu-item svg { width: 1.25rem; height: 1.25rem; flex-shrink: 0; color: #9ba1b0; transition: color .12s ease; }
.cs-menu-item:hover { background: #f1f2f6; color: #181b21; }
.cs-menu-item:hover svg { color: #4e5461; }
.cs-menu-item.is-active { background: #eef4fa; color: #1b4472; }
.cs-menu-item.is-active svg { color: #22568c; }
.cs-menu-item:focus-visible { outline: 3px solid #22568c; outline-offset: -3px; }
.cs-menu-divider { height: 1px; margin: 0.5rem 0.25rem; background: #f1f2f6; }

/* Dark brand panel for page heroes - the same deep-blue canopy and quiet
   ridgeline as the top bar, so the motif repeats instead of resorting to
   decorative gradient blobs. */
.cs-hero-canopy {
    color: #eef4fa;
    background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='64' viewBox='0 0 480 64' fill='none'%3E%3Cpath d='M-8 50 L48 22 L84 42 L138 12 L196 50 L240 32 L288 50 L336 16 L384 40 L432 26 L488 50' stroke='%23eef4fa' stroke-opacity='0.045' stroke-width='2'/%3E%3C/svg%3E") repeat-x bottom left,
        linear-gradient(168deg, #183253 0%, #12253f 52%, #0f213f 100%);
    box-shadow: inset 0 -1px 0 rgba(238, 244, 250, .07), 0 14px 32px -18px rgba(10, 24, 48, .5);
}

/* Content in horizontal mode is centred with a comfortable reading width. */
body.cs-chrome-top main {
    margin-left: auto;
    margin-right: auto;
    width: 100%;
    max-width: 96rem;
}

/* ════════════════════════════════════════════════════════════════
   Inventory list - view toggle, filter pills, grid + bulk edit
   ----------------------------------------------------------------
   Shared by the Pitches and Accommodation list screens. Card view is
   the friendly browse mode; grid view is the dense, spreadsheet-style
   mode for setting up and bulk-editing big parks (200+ pitches).
   Everything here is built mobile-first and stays grandma-proof: big
   tap targets, clear labels, the same patterns on phone and desktop.
   ════════════════════════════════════════════════════════════════ */

/* ── Segmented view toggle (Cards | Grid) ──────────────────────── */
/* ── Segmented control ───────────────────────────────────────────
   The one connected "pick a view" toggle: Cards / Grid, Today / Week /
   People. Active tab lifts onto a white card in brand blue. Scrolls
   sideways rather than wrapping when it runs out of room on a phone. */
.cs-segment {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem;
    border-radius: 0.625rem;
    background: #f1f2f6;
    border: 1px solid #e4e6ed;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.cs-segment::-webkit-scrollbar { display: none; }
.cs-segment-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: 40px;
    padding: 0.4rem 0.9rem;
    border-radius: 0.5rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: #5b6070;
    background: transparent;
    border: none;
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
    transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}
.cs-segment-btn:hover { color: #22568c; }
.cs-segment-btn.is-active {
    background: #fff;
    color: #22568c;
    box-shadow: 0 1px 2px rgba(24, 27, 33, .1);
}
.cs-segment-btn svg { width: 1.15rem; height: 1.15rem; flex-shrink: 0; }

/* ── Quick-filter pills (by type) ──────────────────────────────── */
.cs-pills {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.5rem;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    padding-bottom: 0.25rem;
    /* let the row bleed to the card edges so pills can scroll fully on mobile */
    margin: 0 -0.25rem;
    padding-left: 0.25rem;
    padding-right: 0.25rem;
}
@media (min-width: 768px) {
    .cs-pills { flex-wrap: wrap; overflow-x: visible; }
}
.cs-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 40px;
    padding: 0.4rem 0.9rem;
    border-radius: 9999px;
    font-size: 0.9375rem;
    font-weight: 600;
    color: #3a3f4a;
    background: #fff;
    border: 1.5px solid #e4e6ed;
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
    flex-shrink: 0;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.cs-pill:hover { border-color: #bec3cf; background: #f7f8fa; }
.cs-pill.is-active {
    background: #eef4fa;
    border-color: #22568c;
    color: #1b4472;
}
.cs-pill-dot {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 9999px;
    background: #9ba1b0;
    flex-shrink: 0;
}
.cs-pill-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.4rem;
    padding: 0 0.35rem;
    height: 1.4rem;
    border-radius: 9999px;
    background: rgba(27, 24, 19, .07);
    font-size: 0.8125rem;
    font-weight: 700;
    color: inherit;
}
.cs-pill.is-active .cs-pill-count { background: rgba(34, 86, 140, .14); }

/* ── Inventory grid (dense table that collapses to cards on phones) ─ */
.cs-itable {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.95rem;
}
.cs-itable thead th {
    position: sticky;
    /* Stick to the top of the table's own scroll wrapper, NOT 4rem down. The
       table sits inside an `overflow-x-auto` wrapper, and setting overflow on one
       axis makes the other compute to `auto` too, so that wrapper - not the page -
       is the sticky scroll container. A `top: 4rem` here was measured against the
       wrapper and shoved the header 4rem DOWN into the tbody, hiding the first
       pitch on desktop (mobile hides thead entirely, so it only showed there). */
    top: 0;
    z-index: 5;
    background: #fff;
    text-align: left;
    /* Sentence case at a size somebody can read, in the label grey. Tiny tracked
       capitals over every column are the stock Tailwind UI table head. */
    font-size: 0.875rem;
    font-weight: 600;
    color: #5b6274;
    padding: 0.7rem 0.75rem;
    border-bottom: 1px solid #e6e9ef;
    white-space: nowrap;
}
.cs-itable tbody td {
    padding: 0.7rem 0.75rem;
    border-bottom: 1px solid #edf0f4;
    color: #262a32;
    vertical-align: middle;
}
.cs-itable tbody tr.is-selected td { background: #eef4fa; }
.cs-itable tbody tr:hover td { background: #f7f8fa; }
.cs-itable tbody tr.is-selected:hover td { background: #e4eef8; }
.cs-itable-check { width: 3rem; text-align: center; padding-left: 0.25rem; padding-right: 0.25rem; }
/* The visible box stays tidy, but the wrapping label gives a comfortable 44px+
   tap target so it's easy to tick on a phone (grandma-proof). */
.cs-itable-checkwrap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.cs-itable-check input[type="checkbox"],
.cs-itable-group input[type="checkbox"] {
    width: 22px;
    height: 22px;
    border-radius: 6px;
    accent-color: #22568c;
    cursor: pointer;
}
.cs-itable-code {
    font-weight: 700;
    color: #181b21;
}
.cs-itable-name { color: #4e5461; }
.cs-itable-edit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 40px;
    padding: 0.35rem 0.9rem;
    border-radius: 0.5rem;
    font-weight: 600;
    color: #181b21;
    text-decoration: none;
}
.cs-itable-edit:hover { background: #f1f2f6; }

/* Phone layout: each row becomes a tappable card. The checkbox stays a
   big target up top-left, the rest of the fields wrap underneath with
   their column name as a small label so nothing is mysterious. */
@media (max-width: 767px) {
    .cs-itable, .cs-itable tbody, .cs-itable tr, .cs-itable td { display: block; width: 100%; }
    .cs-itable thead { display: none; }
    /* The rows are one white list ruled by hairlines, the way a phone shows a
       list, rather than a stack of separate bordered cards with a gap between
       each - which is what a generated table does when it runs out of width. */
    .cs-itable tbody {
        border: 1px solid #e6e9ef;
        border-radius: 0.75rem;
        background: #fff;
        overflow: hidden;
    }
    .cs-itable tbody tr {
        position: relative;
        background: #fff;
        padding: 0.9rem 0.95rem 0.9rem 3.75rem;
    }
    .cs-itable tbody tr + tr { border-top: 1px solid #edf0f4; }
    .cs-itable tbody tr.is-selected { background: #eef4fa; }
    .cs-itable tbody td {
        border: none;
        padding: 0.15rem 0;
        display: flex;
        gap: 0.5rem;
        align-items: baseline;
    }
    .cs-itable tbody tr.is-selected td { background: transparent; }
    .cs-itable tbody tr:hover td { background: transparent; }
    .cs-itable td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 6.5rem;
        font-size: 0.8125rem;
        font-weight: 600;
        color: #848a99;
    }
    /* The value takes whatever the label leaves, and is allowed to be
       narrower than its longest word. Without min-width:0 a flex item
       refuses to shrink below its content, so a long email address or a
       date range pushed the card wider than the screen instead of
       wrapping inside it - which is what put the card's right border off
       the edge of an iPhone. */
    .cs-itable tbody td > * {
        flex: 0 1 auto;
        min-width: 0;
    }
    /* A narrow phone cannot spare 104px of label. Below 420px the label
       gives a little back so the value keeps a readable column. */
    @media (max-width: 419px) {
        .cs-itable td[data-label]::before { flex: 0 0 5.5rem; }
    }
    /* `cs-itable-wide`: a cell whose value needs the whole card. An email
       address does not fit beside a label on any phone - it came out as
       "peter.brackenbury@exa / mple.com" - so its label goes above it and
       the value gets the full width. Use it sparingly: a value that fits
       beside its label should stay beside its label, or the cards stop
       scanning as a column of labelled facts. */
    .cs-itable td.cs-itable-wide {
        display: block;
        padding-top: 0.35rem;
    }
    .cs-itable td.cs-itable-wide::before {
        display: block;
        margin-bottom: 0.1rem;
    }
    /* checkbox floats into the reserved left gutter with a big tap target */
    .cs-itable td.cs-itable-check {
        position: absolute;
        left: 0.35rem;
        top: 0.5rem;
        width: auto;
        padding: 0;
    }
    .cs-itable td.cs-itable-check::before { content: none; }
    .cs-itable td.cs-itable-check input[type="checkbox"] { width: 26px; height: 26px; }
    .cs-itable-checkwrap { min-width: 48px; min-height: 48px; }
    /* the "Pitch" name cell reads as the card title */
    .cs-itable td.cs-itable-title { padding-bottom: 0.35rem; }
    .cs-itable td.cs-itable-title::before { content: none; }
    /* Folded into a card, the row action is the card's one button, so it
       looks like one: full width, bordered, a proper 48px target. As bare
       left-aligned text under the last value it read as another label. */
    .cs-itable td.cs-itable-actions { padding-top: 0.75rem; }
    .cs-itable td.cs-itable-actions::before { content: none; }
    .cs-itable-edit {
        width: 100%;
        min-height: 48px;
        padding: 0.5rem 1rem;
        border: 1.5px solid #e4e6ed;
        border-radius: 0.5rem;
        background: #f7f8fa;
    }
    .cs-itable-edit:active { background: #f1f2f6; }
}

/* A grid with no row ticks. The phone layout reserves a left gutter for the
   checkbox, so a list you only ever read (bookings) would otherwise sit in a
   card with an inch of nothing down one side. */
@media (max-width: 767px) {
    .cs-itable-nopick tbody tr { padding-left: 0.95rem; }
}

/* Figures line up under each other and never wrap mid-number. The heading needs
   its own rule: `.cs-itable thead th` sets text-align on its own and outranks a
   single class, so without this the column heading sits left of its own column. */
.cs-itable-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cs-itable thead th.cs-itable-num { text-align: right; }

/* Table headings in sentence case at reading size (cs-itable-plainhead), for a
   table an owner reads rather than works in all day: the calendar link screens.
   The small letterspaced capitals are a working grid's eyebrow; over "Copy this
   into Airbnb" they were 13px of grey an owner could not read. */
.cs-itable-plainhead thead th {
    font-size: 1rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    color: #262a32;
}
/* On a phone the headings become the labels in each row's card, so they keep
   the same reading size there. */
@media (max-width: 767px) {
    .cs-itable-plainhead td[data-label]::before { font-size: 1rem; color: #4e5461; }
}

/* A card that holds a cs-itable (cs-tablecard): a card on a laptop, where the
   table is one surface, and nothing at all on a phone, where the rows fold into a
   list that is its own white panel, and a card round it would be a card inside a card. */
@media (max-width: 767.98px) {
    .cs-tablecard { border: 0; background: transparent; box-shadow: none; overflow: visible; }
    .cs-tablecard > .cs-card-body { padding: 0; }
    .cs-tablecard > .cs-card-header { background: transparent; padding: 0 0 1rem; margin-bottom: 1rem; }
}
@media (max-width: 767px) {
    /* Folded into a card, a figure is a labelled value like any other -
       including being allowed to wrap. Left nowrap, "GBP 1,284.50" beside
       a 104px label was enough to push a card off the side of a phone. */
    .cs-itable-num { text-align: left; white-space: normal; }
}

/* ── Section headings inside a list (cs-itable) ────────────────────
   When a list is grouped ("A", "Stayed last year", "Been once"), the heading is a
   row of the table rather than a block above it, so the columns underneath stay
   lined up. On a phone, where the rows fold into cards, it goes back to being a
   plain heading above the cards it belongs to. */
.cs-itable tbody tr.cs-itable-group td {
    background: #f3f5f9;
    border-bottom: 1px solid #e6e9ef;
    padding: 0.5rem 0.75rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: #0f213f;
}
.cs-itable tbody tr.cs-itable-group:hover td { background: #f3f5f9; }
@media (max-width: 767px) {
    /* On a phone the heading is a band across the list it heads, the way a phone's
       own grouped lists are sectioned. */
    .cs-itable tbody tr.cs-itable-group {
        background: #f3f5f9;
        padding: 0.55rem 0.95rem;
    }
    .cs-itable tbody tr.cs-itable-group td {
        background: transparent;
        border: none;
        padding: 0;
        font-size: 1rem;
    }
    .cs-itable tbody tr.cs-itable-group td::before { content: none; }
}

/* ── A total under the rows it adds up (cs-itable-total) ───────────
   The last row of a report's table ("All parks"), on the heading's grey and in
   bold, so it reads as the sum of the rows above rather than as one more of them.
   A row of the tbody and not a tfoot, because the phone layout folds tbody rows
   into cards and would leave a tfoot as a table under them. On a phone it is the
   last card, on the same grey. */
.cs-itable tbody tr.cs-itable-total td,
.cs-itable tbody tr.cs-itable-total:hover td {
    background: #f7f8fa;
    font-weight: 700;
    color: #181b21;
}
@media (max-width: 767px) {
    .cs-itable tbody tr.cs-itable-total { background: #f7f8fa; }
}

/* ── Floating bulk-edit bar ────────────────────────────────────── */
.cs-bulkbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    transform: translateY(120%);
    transition: transform .22s ease;
    padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
    pointer-events: none;
}
.cs-bulkbar.is-active { transform: translateY(0); pointer-events: auto; }
.cs-bulkbar-inner {
    max-width: 64rem;
    margin: 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    background: #181b21;
    color: #fff;
    border-radius: 0.75rem;
    box-shadow: 0 12px 32px -8px rgba(0, 0, 0, .45);
    padding: 0.7rem 0.85rem;
}
.cs-bulkbar-count {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 700;
    font-size: 1rem;
    padding-left: 0.25rem;
    white-space: nowrap;
}
.cs-bulkbar-count .cs-bulkbar-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.8rem;
    height: 1.8rem;
    padding: 0 0.45rem;
    border-radius: 9999px;
    background: #22568c;
    font-size: 0.9375rem;
}
.cs-bulkbar select,
.cs-bulkbar input[type="text"] {
    min-height: 44px;
    border-radius: 0.5rem;
    border: 1.5px solid #3a352e;
    background: #262a32;
    color: #fff;
    padding: 0.45rem 0.75rem;
    font-size: 0.95rem;
}
.cs-bulkbar select:focus,
.cs-bulkbar input[type="text"]:focus {
    outline: none;
    border-color: #22568c;
    box-shadow: 0 0 0 3px rgba(34, 86, 140, .35);
}
.cs-bulkbar-field { flex: 1 1 22rem; min-width: 0; display: flex; gap: 0.5rem; align-items: center; }
.cs-bulkbar-field > [data-bulk-field] { flex: 0 1 auto; }
.cs-bulkbar-field [data-bulk-control] { flex: 1 1 auto; min-width: 0; display: inline-flex; }
.cs-bulkbar-field [data-bulk-control] > * { width: 100%; }
.cs-bulkbar-spacer { flex: 1 1 auto; }
.cs-bulkbar-apply {
    min-height: 44px;
    padding: 0.45rem 1.1rem;
    border-radius: 0.5rem;
    background: #22568c;
    color: #fff;
    font-weight: 700;
    border: none;
    cursor: pointer;
    white-space: nowrap;
}
.cs-bulkbar-apply:hover { background: #1b4472; }
.cs-bulkbar-apply:disabled { opacity: .5; cursor: not-allowed; }
.cs-bulkbar-clear {
    min-height: 44px;
    padding: 0.45rem 0.85rem;
    border-radius: 0.5rem;
    background: transparent;
    color: #ced2dd;
    font-weight: 600;
    border: 1.5px solid #3a352e;
    cursor: pointer;
    white-space: nowrap;
}
.cs-bulkbar-clear:hover { background: #262a32; color: #fff; }

@media (max-width: 639px) {
    .cs-bulkbar-inner { flex-direction: column; align-items: stretch; }
    .cs-bulkbar-field { flex-direction: column; align-items: stretch; }
    .cs-bulkbar-field > [data-bulk-field],
    .cs-bulkbar-field [data-bulk-control] { width: 100%; }
    .cs-bulkbar-row { display: flex; gap: 0.5rem; }
    .cs-bulkbar-row > * { flex: 1 1 0; }
    .cs-bulkbar-spacer { display: none; }
}


/* ================================================================
   Mobile bottom navigation (phones and small tablets, below lg)
   ----------------------------------------------------------------
   App-style bar for staff out on the park: Today, Diary, a raised
   "New" button (quick-action sheet), Guests and More (opens the
   existing full-menu drawer). Labels always visible, 48px+ targets,
   iPhone safe-area padding. Desktop is untouched: everything here
   is display:none at lg and up.
   ================================================================ */
.cs-bottomnav, .cs-sheet, .cs-sheet-backdrop { display: none; }

@media (max-width: 1023.98px) {
    .cs-bottomnav {
        display: flex;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 39;   /* under the drawer overlay (40) and drawer (50) */
        align-items: stretch;
        background: rgba(255, 255, 255, .97);
        border-top: 1px solid #e4e6ed;
        padding: 0.375rem 0.375rem calc(0.375rem + env(safe-area-inset-bottom));
        box-shadow: 0 -10px 28px -22px rgba(24, 27, 33, .5);
    }
    .cs-bottomnav-item,
    .cs-bottomnav-slot { flex: 1 1 0; min-width: 0; }
    .cs-bottomnav-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 0.125rem;
        min-height: 3.25rem;
        padding: 0.25rem 0;
        border: none;
        background: transparent;
        border-radius: 0.625rem;
        font-size: 0.6875rem;
        font-weight: 600;
        color: #4e5461;
        text-decoration: none;
        cursor: pointer;
    }
    .cs-bottomnav-item svg { width: 1.5rem; height: 1.5rem; }
    .cs-bottomnav-item.is-active { color: #f06436; }
    .cs-bottomnav-item:focus-visible { outline: 3px solid #22568c; outline-offset: -3px; }

    .cs-bottomnav-slot {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: flex-start;
    }
    .cs-bottomnav-new {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 3.25rem;
        height: 3.25rem;
        margin-top: -1.375rem;
        border: none;
        border-radius: 9999px;
        background: #f06436;   /* Sunset Orange - the booking/create action */
        color: #fff;
        cursor: pointer;
        box-shadow: 0 6px 16px rgba(240, 100, 54, .35), inset 0 1px 0 rgba(255, 255, 255, .18);
    }
    .cs-bottomnav-new svg { width: 1.625rem; height: 1.625rem; }
    .cs-bottomnav-new:active { transform: translateY(1px); }
    .cs-bottomnav-new:focus-visible { outline: 3px solid #f06436; outline-offset: 2px; }
    .cs-bottomnav-newlabel {
        font-size: 0.6875rem;
        font-weight: 600;
        color: #4e5461;
        margin-top: 0.125rem;
    }

    /* Quick-action sheet */
    .cs-sheet-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 44;
        background: rgba(27, 24, 19, .45);
        opacity: 0;
        visibility: hidden;
        transition: opacity .2s ease, visibility 0s linear .2s;
    }
    .cs-sheet-backdrop.is-open { opacity: 1; visibility: visible; transition: opacity .2s ease; }
    .cs-sheet {
        display: block;
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 45;
        background: #fff;
        border-radius: 1rem 1rem 0 0;
        padding: 0.5rem 0.75rem calc(0.75rem + env(safe-area-inset-bottom));
        box-shadow: 0 -18px 44px -20px rgba(24, 27, 33, .45);
        transform: translateY(105%);
        visibility: hidden;
        transition: transform .22s cubic-bezier(.16, 1, .3, 1), visibility 0s linear .25s;
    }
    .cs-sheet.is-open {
        transform: translateY(0);
        visibility: visible;
        transition: transform .22s cubic-bezier(.16, 1, .3, 1);
    }
    .cs-sheet-grip {
        width: 2.5rem;
        height: 0.3125rem;
        border-radius: 9999px;
        background: #e4e6ed;
        margin: 0.25rem auto 0.5rem;
    }
    .cs-sheet-item {
        display: flex;
        align-items: center;
        gap: 0.875rem;
        min-height: 3.25rem;
        padding: 0.5rem 0.75rem;
        border-radius: 0.625rem;
        font-size: 1.0625rem;
        font-weight: 600;
        color: #181b21;
        text-decoration: none;
    }
    .cs-sheet-item svg { width: 1.5rem; height: 1.5rem; color: #22568c; flex-shrink: 0; }
    .cs-sheet-item:active { background: #f1f2f6; }
    .cs-sheet-item:focus-visible { outline: 3px solid #22568c; outline-offset: -3px; }
    .cs-sheet-form { padding: 0.25rem 0.75rem 0.5rem; }
    .cs-sheet-form .cs-label { font-size: 1.0625rem; }
    .cs-sheet-cancel {
        display: block;
        width: 100%;
        min-height: 3rem;
        margin-top: 0.375rem;
        border: none;
        border-radius: 0.625rem;
        background: #f1f2f6;
        color: #3a3f4a;
        font-size: 1rem;
        font-weight: 600;
        cursor: pointer;
    }

    /* The top bar's quick-create button duplicates the bottom "New" button
       on phones; keep just the one, and give the park name the extra room. */
    .cs-topnav [aria-label="Create new"] { display: none; }

    /* The help launcher must never cover a dialog, sheet or drawer. */
    .cs-app:has(.cs-modal-overlay.cs-open) .csh-launcher,
    .cs-app:has(#cs-mobile.cs-open) .csh-launcher,
    .cs-app:has(.cs-sheet.is-open) .csh-launcher,
    .cs-app:has(#cs-jobmodal:not(.hidden)) .csh-launcher,
    .cs-app:has(#cs-parks-modal:not(.hidden)) .csh-launcher {
        display: none;
    }

    /* Compact, icon-only launcher on phones so it covers less content. */
    .cs-app .csh-launcher {
        height: 52px;
        min-width: 52px;
        width: 52px;
        padding: 0;
        justify-content: center;
    }
    .cs-app .csh-launcher .csh-launcher-label { display: none; }

    /* Keep existing fixed and sticky elements clear of the bar. */
    body.cs-app main { padding-bottom: calc(5.25rem + env(safe-area-inset-bottom)); }
    .cs-actionbar-sticky { bottom: calc(4.25rem + env(safe-area-inset-bottom)); }
    .cs-bulkbar { bottom: calc(4.25rem + env(safe-area-inset-bottom)); }
    .cs-app .csh-launcher { bottom: calc(5rem + env(safe-area-inset-bottom)); }
    .cs-app .csh-panel { bottom: calc(9.75rem + env(safe-area-inset-bottom)); }
    .cs-app .cs-selection-hint { bottom: calc(6rem + env(safe-area-inset-bottom)); }
}

/* ── Print: strip the app chrome so reports & invoices print clean ── */
@media (max-width: 639.98px) {
    .cs-app:has(.cs-actionbar-sticky) .csh-launcher { display: none; }
}

@media print {
    aside,
    header,
    #cs-overlay,
    #cs-mobile,
    .cs-bottomnav,
    .cs-sheet,
    .cs-sheet-backdrop,
    .no-print {
        display: none !important;
    }

    body { background: #ffffff !important; }
    main, #main { padding: 0 !important; }
    .print-full { max-width: none !important; }
    a[href]:after { content: ""; } /* don't append URLs */
}

/* ================================================================
   Booking quick view - the shared modal component
   (Pages/Shared/_BookingQuickView.cshtml + cs-booking-quickview.js).
   These rules mirror the Diary's page-local modal styles so the
   component renders identically on any page; the Diary still carries
   its own copies for its create/blocked/out-of-season modals - keep
   the two in step if either changes.
   ================================================================ */

    /* The booking states, filled to match .cs-badge, the same as the operator app.
       Draft is the one outline: it is the absence of a state rather than one of
       them, and an empty chip says that in a way a fifth colour cannot. */
    .cs-badge-confirmed  { background: #22568c; color: #ffffff; }
    .cs-badge-checkedin  { background: #2f6faf; color: #ffffff; }
    .cs-badge-checkedout { background: #6c7280; color: #ffffff; }
    .cs-badge-cancelled  { background: #b42318; color: #ffffff; }
    .cs-badge-draft {
        background: #ffffff;
        color: #4e5461;
        box-shadow: inset 0 0 0 1px #ced2dd;
    }

    .cs-modal-overlay {
        position: fixed; inset: 0;
        background: rgba(15, 23, 42, .45); backdrop-filter: blur(4px);
        z-index: 100; display: flex; align-items: center; justify-content: center;
        opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
    }
    .cs-modal-overlay.cs-open { opacity: 1; pointer-events: all; }
    .cs-modal {
        background: #fff; border-radius: 16px;
        box-shadow: 0 24px 48px rgba(0,0,0,.18);
        width: 100%; max-height: 90vh; overflow-y: auto;
        transform: translateY(12px) scale(.97); transition: transform 0.2s ease; margin: 16px;
    }
    .cs-modal-overlay.cs-open .cs-modal { transform: translateY(0) scale(1); }
    .cs-modal-head {
        display: flex; align-items: center; justify-content: space-between;
        padding: 20px 24px 16px; border-bottom: 1px solid #f1f2f6;
    }
    .cs-modal-head h2 { font-size: 18px; font-weight: 700; color: #181b21; margin: 0; }
    .cs-modal-body { padding: 20px 24px 24px; }
    .cs-modal-close {
        width: 36px; height: 36px; border-radius: 10px; border: none;
        background: #f1f2f6; cursor: pointer;
        display: flex; align-items: center; justify-content: center;
        color: #6c7280; font-size: 18px; transition: background 0.15s;
    }
    .cs-modal-close:hover { background: #e4e6ed; }

    /* ── Form ──────────────────────────────────────────────────── */

    .cs-detail-row {
        display: flex; justify-content: space-between; padding: 10px 0;
        border-bottom: 1px solid #f1f2f6; font-size: 14px;
    }
    .cs-detail-row:last-child { border-bottom: none; }
    .cs-detail-label { color: #6c7280; font-weight: 500; }
    .cs-detail-value { color: #181b21; font-weight: 600; text-align: right; }

    /* ── Blocked guest alert ────────────────────────────────────
       The one way "this guest is blocked" is said, wherever a booking is
       taken or opened: diary create modal, booking quick view, booking
       screen. Big words, rose tint, an icon as well as the colour. ── */
    .cs-blocked-alert {
        display: flex; align-items: flex-start; gap: 12px;
        padding: 14px 16px; margin-bottom: 16px;
        border-radius: 12px; border: 1.5px solid #fecdd3; background: #fff1f2;
        color: #9f1239;
    }
    .cs-blocked-alert-icon { width: 26px; height: 26px; flex-shrink: 0; }
    .cs-blocked-alert-title { font-size: 17px; font-weight: 700; line-height: 1.25; }
    .cs-blocked-alert-body { margin-top: 3px; font-size: 15px; line-height: 1.4; }
    .cs-blocked-alert-reason { margin-top: 6px; font-size: 15px; line-height: 1.4; }
    .cs-blocked-alert-reason span { font-weight: 700; }

    /* ── Selection toast ───────────────────────────────────────── */
    .cs-selection-hint {
        position: fixed; bottom: 24px; left: 50%;
        transform: translateX(-50%) translateY(80px);
        background: #181b21; color: #fff; padding: 12px 24px; border-radius: 12px;
        font-size: 14px; font-weight: 600;
        box-shadow: 0 8px 24px rgba(0,0,0,.25);
        z-index: 90; transition: transform 0.25s cubic-bezier(.4,0,.2,1), opacity 0.25s;
        opacity: 0; pointer-events: none; white-space: nowrap;
    }
    .cs-selection-hint.cs-visible { transform: translateX(-50%) translateY(0); opacity: 1; pointer-events: all; }

    /* ── Deep-link hint (from the Today screen / mobile quick-action sheet).
       Unlike the selection hint this stays visible on phones, and sits above
       the mobile bottom bar. ── */

    .cs-quick-actions {
        display: flex; gap: 8px; margin-top: 16px; padding-top: 16px;
        border-top: 1px solid #f1f2f6;
    }
    .cs-quick-action {
        flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
        padding: 10px 12px; border-radius: 10px;
        border: 1.5px solid #e4e6ed; background: #fff;
        color: #3a3f4a; font-size: 13px; font-weight: 600;
        cursor: pointer; transition: all 0.15s; text-decoration: none;
    }
    .cs-quick-action:hover { background: #eef4fa; border-color: #22568c; color: #22568c; }
    .cs-quick-action svg { flex-shrink: 0; }
    .cs-quick-action-call { color: #22568c; border-color: #b4d0e9; background: #eef4fa; }
    .cs-quick-action-call:hover { background: #d7e6f4; border-color: #22568c; }
    .cs-quick-action-email { color: #3a5f7e; border-color: #c2d4e3; background: #ecf2f7; }
    .cs-quick-action-email:hover { background: #dbe7ef; border-color: #3a5f7e; }
    .cs-quick-action-text { color: #6d5384; border-color: #d8cde5; background: #f6f4f9; }
    .cs-quick-action-text:hover { background: #ebe6f2; border-color: #6d5384; }
    .cs-quick-action-disabled { opacity: 0.4; pointer-events: none; cursor: not-allowed; }

    /* ── Balance & status actions in view modal ─────────────── */
    .cs-balance-box {
        display: flex; align-items: center; justify-content: space-between;
        padding: 12px 14px; border-radius: 10px; margin-top: 12px;
        font-size: 14px;
    }
    .cs-balance-paid { background: #eef4fa; border: 1.5px solid #b4d0e9; }
    .cs-balance-owed { background: #fffbeb; border: 1.5px solid #fcd34d; }
    .cs-balance-label { font-weight: 600; color: #4e5461; }
    .cs-balance-amount { font-weight: 800; font-size: 18px; }
    .cs-balance-amount-paid { color: #22568c; }
    .cs-balance-amount-owed { color: #d97706; }
    .cs-balance-detail { font-size: 12px; color: #6c7280; margin-top: 2px; }

    .cs-status-actions {
        display: flex; gap: 8px; margin-top: 12px;
    }
    .cs-btn-checkin {
        flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
        padding: 12px 16px; border-radius: 10px; border: none;
        background: #3a5f7e; color: #fff; font-size: 14px; font-weight: 700;
        cursor: pointer; transition: background 0.15s;
    }
    .cs-btn-checkin:hover { background: #324f68; }
    .cs-btn-checkin:disabled { opacity: 0.5; cursor: not-allowed; }
    .cs-btn-checkout {
        flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
        padding: 12px 16px; border-radius: 10px; border: none;
        background: #6d5384; color: #fff; font-size: 14px; font-weight: 700;
        cursor: pointer; transition: background 0.15s;
    }
    .cs-btn-checkout:hover { background: #5b456d; }
    .cs-btn-checkout:disabled { opacity: 0.5; cursor: not-allowed; }
    .cs-btn-extendstay {
        flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
        padding: 12px 16px; border-radius: 10px; border: 1px solid #b4d0e9;
        background: #eef4fa; color: #1b4472; font-size: 14px; font-weight: 700;
        cursor: pointer; transition: background 0.15s;
    }
    .cs-btn-extendstay:hover { background: #d7e6f4; }

    /* ── Guest info pill in view modal ─────────────────────── */

    /* ── Extend-a-stay panel (quick view modal) ────────────────── */
    .cs-extend-stepper {
        display: flex; align-items: center; justify-content: space-between;
        gap: 12px; margin-top: 4px;
    }
    .cs-extend-stepbtn {
        width: 52px; height: 52px; flex-shrink: 0;
        border-radius: 10px; border: 1px solid #ced2dd; background: #fff;
        font-size: 26px; font-weight: 600; color: #22568c; cursor: pointer;
        transition: background-color .15s ease;
    }
    .cs-extend-stepbtn:hover { background: #eef4fa; }
    .cs-extend-stepbtn:disabled { color: #c3c8d3; cursor: default; background: #fff; }
    .cs-extend-count { font-size: 17px; font-weight: 700; color: #181b21; text-align: center; }
    .cs-extend-newdate { margin-top: 10px; font-size: 14px; font-weight: 600; color: #4a505d; text-align: center; }
    .cs-extend-note {
        margin-top: 12px; padding: 10px 14px; border-radius: 10px;
        font-size: 14px; font-weight: 600;
    }
    .cs-extend-note-ok { background: #eef4fa; border: 1px solid #b4d0e9; color: #1b4472; }
    .cs-extend-note-bad { background: #fff1f2; border: 1px solid #fecdd3; color: #9f1239; }
    .cs-extend-note-wait { background: #f7f8fa; border: 1px solid #e4e6ed; color: #6c7280; }

@media (max-width: 767px) {
    .cs-modal { margin: 8px; border-radius: 14px; max-height: 95vh; }
    .cs-modal-head { padding: 16px 18px 12px; }
    .cs-modal-body { padding: 16px 18px 20px; }
}

/* ================================================================
   Day tip (`cs-daytip`) - "tell me everything about this square"
   ----------------------------------------------------------------
   The one detail panel for a dense board: the diary's pitch nights,
   booking bars, date columns and row labels. On a desktop it opens
   under the pointer (or keyboard focus) as a small card that never
   eats a click; on a phone the identical markup slides up as a
   bottom sheet with a close button, because a phone has no hover.

   Driven by wwwroot/js/cs-daytip.js. The host page owns the words
   (it knows the domain), this owns the look. Never hand-roll a
   second hover panel - extend this one.
   ================================================================ */
.cs-daytip {
    position: fixed;
    top: 0; left: 0;
    z-index: 95;              /* over sticky grid headers, under modals (100) */
    width: 360px;
    max-width: calc(100vw - 20px);
    opacity: 0;
    visibility: hidden;
    transform: translateY(4px);
    transition: opacity .12s ease, transform .12s ease, visibility 0s linear .12s;
    pointer-events: none;     /* the board underneath stays clickable */
}
.cs-daytip.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition: opacity .12s ease, transform .12s ease;
}
.cs-daytip-panel {
    position: relative;
    padding: 12px 14px;
    border: 1px solid #e4e6ed;
    border-radius: 12px;
    background: #fff;
    box-shadow: 0 2px 6px rgba(24, 27, 33, .06), 0 14px 34px -12px rgba(24, 27, 33, .32);
    color: #181b21;
    font-size: 16px;
    line-height: 1.4;
    text-align: left;
    /* On a short laptop window a full booking can be taller than the screen.
       Cap it so the guest's name is never the bit that gets pushed off. */
    box-sizing: border-box;
    max-height: calc(100vh - 20px);
    overflow: hidden;
}

/* The pointer, pinned under the square the tip belongs to. */
.cs-daytip-panel::after {
    content: '';
    position: absolute;
    left: var(--cs-daytip-arrow, 50%);
    width: 10px; height: 10px;
    margin-left: -5px;
    background: #fff;
    border: 1px solid #e4e6ed;
    transform: rotate(45deg);
}
.cs-daytip-below .cs-daytip-panel::after { top: -6px; border-right: 0; border-bottom: 0; }
.cs-daytip-above .cs-daytip-panel::after { bottom: -6px; border-left: 0; border-top: 0; }
/* Squeezed against a screen edge the panel is no longer touching its square,
   so the pointer would be aiming at nothing. */
.cs-daytip-noarrow .cs-daytip-panel::after { display: none; }

/* ── Head: what am I looking at ─────────────────────────────────── */
.cs-daytip-head { display: flex; align-items: flex-start; gap: 9px; }
.cs-daytip-swatch {
    width: 10px; height: 10px; margin-top: 6px;
    border-radius: 3px; flex-shrink: 0;
}
.cs-daytip-heading { display: block; flex: 1; min-width: 0; }
.cs-daytip-title {
    display: block;
    font-size: 18px; font-weight: 700; line-height: 1.2;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cs-daytip-sub { display: block; margin-top: 2px; font-size: 15px; color: #6c7280; }
.cs-daytip-head .cs-badge { flex-shrink: 0; margin-top: 1px; }

/* ── Headline: the one-line answer, tinted by state (§8 map) ────── */
.cs-daytip-headline {
    display: flex; align-items: center; gap: 8px;
    margin-top: 10px; padding: 9px 11px;
    border-radius: 9px;
    font-size: 17px; font-weight: 700;
}
.cs-daytip-headline svg { width: 20px; height: 20px; flex-shrink: 0; }
.cs-daytip-free { background: #eef4fa; border: 1px solid #b4d0e9; color: #1b4472; }
.cs-daytip-busy { background: #f7f5f0; border: 1px solid #e4e6ed; color: #3a3f4a; }
.cs-daytip-warn { background: #fff7ed; border: 1px solid #fed7aa; color: #9a3412; }
.cs-daytip-stop { background: #fff1f2; border: 1px solid #fecdd3; color: #9f1239; }

/* ── Facts: the shared detail rows, tightened for a small panel ── */
.cs-daytip-rows { margin-top: 8px; }
.cs-daytip-rows .cs-detail-row {
    gap: 14px; padding: 6px 0; font-size: 16px;
    align-items: baseline;
}
.cs-daytip-rows .cs-detail-label { white-space: nowrap; }
.cs-daytip-rows .cs-detail-value { font-weight: 700; }

/* ── How full: a plain bar, because a number alone hides the shape ── */
.cs-daytip-meter {
    height: 8px; margin-top: 10px;
    border-radius: 9999px; background: #f1f2f6; overflow: hidden;
}
.cs-daytip-meter > span {
    display: block; height: 100%;
    border-radius: 9999px; background: #22568c;
}

/* ── Chips: the unit's own facts (hookup, occupancy, dogs, size) ── */
.cs-daytip-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
.cs-daytip-chip {
    display: inline-flex; align-items: center;
    padding: 3px 9px; border-radius: 9999px;
    border: 1px solid #e4e6ed; background: #f7f8fa;
    font-size: 14px; font-weight: 600; color: #4e5461;
}
.cs-daytip-chip-off { color: #9ba1b0; background: #fff; }

/* ── Note: a warning or an aside, same tints as the headline ────── */
.cs-daytip-note {
    margin-top: 9px; padding: 8px 11px;
    border-radius: 9px; font-size: 15px; font-weight: 600;
}

/* ── Foot: what happens if you click ───────────────────────────── */
.cs-daytip-foot {
    display: flex; align-items: center; gap: 6px;
    margin-top: 11px; padding-top: 9px;
    border-top: 1px solid #f1f2f6;
    font-size: 15px; font-weight: 600; color: #22568c;
}
.cs-daytip-foot svg { width: 16px; height: 16px; flex-shrink: 0; }

/* ── Sheet mode (phones and any touch-only screen) ───────────────
   Same content, but it comes up from the bottom, takes taps and
   closes with a real 48px button instead of by moving the mouse. */
.cs-daytip-backdrop {
    position: fixed; inset: 0; z-index: 94;
    background: rgba(27, 24, 19, .45);
    opacity: 0; visibility: hidden;
    transition: opacity .2s ease, visibility 0s linear .2s;
}
.cs-daytip-backdrop.is-open {
    opacity: 1; visibility: visible;
    transition: opacity .2s ease;
}
.cs-daytip.is-sheet {
    top: auto; bottom: 0; left: 0; right: 0;
    width: auto; max-width: none;
    transform: translateY(105%);
    pointer-events: auto;
    transition: transform .22s cubic-bezier(.16, 1, .3, 1), visibility 0s linear .25s;
}
.cs-daytip.is-sheet.is-open {
    opacity: 1; transform: translateY(0);
    transition: transform .22s cubic-bezier(.16, 1, .3, 1);
}
.cs-daytip.is-sheet .cs-daytip-panel {
    max-height: 82vh; overflow-y: auto;
    padding: 6px 18px calc(16px + env(safe-area-inset-bottom));
    border: 0; border-radius: 16px 16px 0 0;
    box-shadow: 0 -18px 44px -20px rgba(24, 27, 33, .45);
    font-size: 16px;
}
.cs-daytip.is-sheet .cs-daytip-panel::after { display: none; }
.cs-daytip.is-sheet .cs-daytip-title { font-size: 20px; white-space: normal; }
.cs-daytip.is-sheet .cs-daytip-sub { font-size: 16px; }
.cs-daytip.is-sheet .cs-daytip-headline { font-size: 18px; padding: 11px 13px; }
.cs-daytip.is-sheet .cs-daytip-rows .cs-detail-row { padding: 9px 0; font-size: 17px; }
.cs-daytip.is-sheet .cs-daytip-chip { font-size: 15px; padding: 5px 11px; }
.cs-daytip.is-sheet .cs-daytip-note,
.cs-daytip.is-sheet .cs-daytip-foot { font-size: 16px; }
.cs-daytip-grip { display: none; }
.cs-daytip.is-sheet .cs-daytip-grip {
    display: block;
    width: 2.5rem; height: 0.3125rem;
    margin: 4px auto 10px;
    border-radius: 9999px; background: #e4e6ed;
}
.cs-daytip-done {
    display: none; width: 100%; min-height: 48px;
    margin-top: 14px; border: 0; border-radius: 10px;
    background: #f1f2f6; color: #3a3f4a;
    font-size: 16px; font-weight: 600; cursor: pointer;
}
.cs-daytip.is-sheet .cs-daytip-done { display: block; }

/* Nothing should sit on top of an open sheet. */
.cs-app:has(.cs-daytip.is-sheet.is-open) .csh-launcher { display: none; }

@media print { .cs-daytip, .cs-daytip-backdrop { display: none !important; } }

/* ════════════════════════════════════════════════════════════════
   Re-taken from Campsuite.Web/wwwroot/css/site.css, November 2026
   ----------------------------------------------------------------
   The furniture a guest's booking and their list of jobs are built from,
   which this sheet had never carried. Each block below is copied unchanged
   from the operator sheet, comments and all, and DESIGN.md section 13 lists
   every one. A fix to one copy belongs in the other.
   ════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════
   List and record furniture
   ----------------------------------------------------------------
   The toolbar, the empty state, the toast, the section heading, the
   headline figures and the key/value panel. DESIGN.md §12 already
   recorded these as general furniture that had ended up written only
   into the admin and portal stylesheets; they are the operator app's
   too, so they live here under the same names and the three copies
   stay in step until the sheets are merged.
   ════════════════════════════════════════════════════════════════ */

/* ── Toolbar ─────────────────────────────────────────────────────
   The soft panel above a list holding search, filters and pills, so a
   list screen is one panel and a table rather than three stacked white
   boxes. */
.cs-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    padding: 0.9rem 1rem;
    border-radius: 0.75rem;
    border: 1px solid #e4e6ed;
    background: #fff;
    margin-bottom: 1.25rem;
}
.cs-toolbar-grow { flex: 1 1 14rem; min-width: 0; }
.cs-toolbar-field { flex: 0 0 auto; }
.cs-toolbar-field .cs-label { font-size: 0.8125rem; margin-bottom: 0.25rem; }
.cs-toolbar .cs-input { min-height: 44px; padding-top: 0.5rem; padding-bottom: 0.5rem; }
.cs-toolbar-check {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    padding: 0 0.25rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: #3a3f4a;
    cursor: pointer;
}
/* min-width:0 for the same reason as .cs-pills: a flex item will not shrink
   below its content unless told to, so a row holding a long scroller would
   otherwise stretch the toolbar and take the page sideways with it. */
.cs-toolbar-row { flex: 1 1 100%; min-width: 0; display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }

/* ── Search field ────────────────────────────────────────────────
   An input with a leading magnifier. The wrapper only adds the icon;
   the field itself is a plain .cs-input. Not to be confused with
   .cs-search-results / .cs-search-item, which are the type-ahead's
   dropdown: a type-ahead box wears .cs-typeahead and .cs-search
   together. */
.cs-search { position: relative; }
.cs-search input { padding-left: 2.85rem; }
.cs-search svg {
    position: absolute;
    left: 0.95rem; top: 50%; transform: translateY(-50%);
    height: 1.15rem; width: 1.15rem;
    color: #9ba1b0; pointer-events: none;
}

/* ── Empty state ─────────────────────────────────────────────────
   The one way a list says "nothing here yet": a title, one line, and up
   to two actions. Words on the surface it sits on, with no box of its own:
   the dashed drop-zone frame it used to wear, usually inside a card, was a
   third frame round a sentence saying there was nothing to frame. */
.cs-empty {
    padding: 3rem 1.5rem;
    text-align: center;
}
.cs-empty-title { font-size: 1.125rem; font-weight: 600; color: #181b21; }
.cs-empty-body { margin: 0.35rem auto 0; max-width: 28rem; font-size: 1rem; line-height: 1.5; color: #5b6070; }
.cs-empty-actions { margin-top: 1.25rem; display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; }

/* ── Toast (the "that worked" line after a POST) ──────────────────
   One class, three tones from the §8 state map. */
.cs-toast {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.85rem 1rem;
    border-radius: 0.625rem;
    border: 1px solid #b4d0e9;
    background: #eef4fa;
    color: #1b4472;
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 1.25rem;
}
.cs-toast svg { width: 1.25rem; height: 1.25rem; flex: none; margin-top: 0.1rem; }
.cs-toast-warn  { border-color: #f3dda2; background: #fef8e7; color: #92600a; }
.cs-toast-error { border-color: #f4c9c4; background: #fef3f2; color: #b42318; }

/* ── Section heading inside a page (above a table or a panel) ─────
   A block heading on a long page. Not the same thing as .cs-section,
   the tiny uppercase eyebrow inside the booking quick view. */
.cs-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 2rem 0 0.875rem;
}
.cs-section-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 1.125rem;
    font-weight: 600;
    color: #0f213f;
    letter-spacing: -0.01em;
}
.cs-section-sub { font-size: 1rem; color: #6c7280; margin-top: 0.1rem; }

/* ── Headline figures (cs-stats / cs-stat) ───────────────────────
   The row of numbers at the top of a record or a report. One quiet
   state colour on the figure per the §8 map, and
   tabular numerals so a row of them lines up like a ledger. An <a>
   version lifts on hover. */
.cs-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 1px;
    border: 1px solid #e6e9ef;
    border-radius: 0.75rem;
    background: #e6e9ef;
    overflow: hidden;
}

/* The figures are one strip, ruled into cells by hairlines like the head of a
   ledger page: one panel holding the numbers, not a row of separate bordered
   tiles, which is the stock dashboard every template opens on. Two to a row on a
   phone (an odd one out takes the whole row) and one row from 768px. No coloured
   rule across the top and no tiny letterspaced capitals: the state colour lives on
   the figure, which is the part it is about. */
.cs-stat {
    position: relative;
    display: block;
    flex: 1 1 calc(50% - 1px);
    min-width: 0;
    padding: 0.95rem 1.1rem 1.05rem;
    background: #fff;
    text-decoration: none;
}
.cs-stats-3 > .cs-stat { flex-basis: 100%; }
@media (min-width: 768px) {
    .cs-stat,
    .cs-stats-3 > .cs-stat { flex: 1 1 0; }
}
a.cs-stat { transition: background-color .15s ease; }
a.cs-stat:hover { background: #f5f8fc; }
.cs-stat-label {
    display: block;
    font-size: 0.875rem;
    font-weight: 500;
    color: #5b6274;
}
.cs-stat-value {
    display: block;
    margin-top: 0.25rem;
    font-family: "Poppins", system-ui, sans-serif;
    /* Two tiles across a phone is about 140px of room, and a tile holds a name as often
       as it holds a number, so the figure gives a little ground on a small screen and
       none at all from a laptop up. */
    font-size: clamp(1.375rem, 1.1rem + 1.1vw, 1.75rem);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.02em;
    /* The tile clips, so a name longer than its track would otherwise be cut off
       mid-word with nothing to say so. break-word rather than anywhere: it breaks at
       the sensible places first and only splits a word that genuinely cannot fit, and
       when it has to split one, hyphens put it where a dictionary would rather than
       between any two letters. Wrap rather than ellipsis, because the tile has no fixed
       height and this is the screen somebody opened in order to read the name. */
    overflow-wrap: break-word;
    hyphens: auto;
    color: #0f213f;
}
.cs-stat-sub { display: block; margin-top: 0.25rem; font-size: 0.9375rem; color: #6c7280; }

/* The state colour, per the section 8 map, on the figure itself. Tint a tile only
   where the number means something is owed or overdue: a row where every tile is a
   different colour is a row nobody reads. Colour is never the only signal - the
   label beside it says the same thing in words. */
/* Brand and sky are a figure's ordinary deep blue: three blues in one strip, none of
   them a state, was a row of colours that meant nothing. */
.cs-stat-brand  .cs-stat-value { color: #0f213f; }
.cs-stat-sky    .cs-stat-value { color: #0f213f; }
.cs-stat-amber  .cs-stat-value { color: #92600a; }
.cs-stat-rose   .cs-stat-value { color: #b42318; }
.cs-stat-action .cs-stat-value { color: #bd3f18; }

/* ── Key/value facts (a read-only record panel) ──────────────────
   Two columns on a desktop, stacked on a phone, with a hairline
   between rows instead of yet another set of boxes. Add
   .cs-facts-stack where the panel sits in a narrow sticky rail and a
   second column would squeeze both. */
.cs-facts { display: grid; grid-template-columns: 1fr; }
@media (min-width: 640px) { .cs-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1.5rem; } }
.cs-facts-stack { grid-template-columns: 1fr !important; }
.cs-fact {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.55rem 0;
    border-bottom: 1px solid #f1f2f6;
    font-size: 0.9375rem;
}
.cs-fact-key { color: #6c7280; flex: none; }
.cs-fact-val { color: #181b21; font-weight: 600; text-align: right; overflow-wrap: anywhere; }
.cs-fact-val a { color: #22568c; }

/* ── A card's own commands (cs-cardtools) ────────────────────────
   The commands for what one card on a record shows, under its facts:
   the everyday ones from the left, and the sharp one in a trailing
   cs-cardtools-end, kept apart at the far end the way the record bar
   keeps Archive in a group of its own. It wraps on the card's own width,
   never a viewport breakpoint, and is drawn out by the commands' own
   padding so their words line up with the card's. */
.cs-cardtools { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; margin: 0 -0.7rem; }
.cs-cardtools-end { margin-left: auto; }
/* A command longer than a narrow card (a 24rem rail, a phone) wraps its words, as one in a
   notice does, rather than running off the card's edge. */
.cs-cardtools .cs-btn { white-space: normal; text-align: left; max-width: 100%; }

/* ════════════════════════════════════════════════════════════════
   The record screen (cs-record, cs-recordbar, cs-addrow)
   ----------------------------------------------------------------
   A booking or a guest is one thing somebody works on, not a form they
   fill in once, so it gets its own shape: the substance in the main
   column, the facts and the state in a rail that stays put while you
   scroll, and the commands in a bar across the top where they are the
   same on every record.

   One markup, two layouts. Everything below is a breakpoint on a single
   set of elements - never a phone copy and a desktop copy of the same
   field, which doubles the id surface and the server binding surface
   and eventually disagrees with itself.

   The step is 1024px, the same one the navigation collapses at, so the
   whole app changes shape once rather than three times.
   ════════════════════════════════════════════════════════════════ */

.cs-record {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
    align-items: start;
}
@media (min-width: 1024px) {
    /* minmax(0, 1fr) and not 1fr: a grid track will not shrink below its
       content otherwise, and one wide table in the main column would push
       the rail off the screen. */
    .cs-record { grid-template-columns: minmax(0, 1fr) 24rem; gap: 1.5rem; }
    /* 8.5rem, and every part of it is load bearing: the 4rem top bar, the command bar
       pinned underneath it (a 40px button plus its padding and hairlines, so a shade
       under 4rem), and a little air. Pinning the rail at 4rem plus air would park it
       behind the bar, which is opaque, and take the top of the rail's first card with
       it. If the bar ever wraps to a second row on a narrow laptop the rail loses about
       24px to it; measuring the bar would need script, and a record screen is not worth
       script. */
    .cs-record-side { position: sticky; top: 8.5rem; }
}
.cs-record-main,
.cs-record-side { min-width: 0; display: flex; flex-direction: column; gap: 1.25rem; }

/* A record-shaped screen with no command bar under the top bar (the
   Channels hub) pins its rail 3.5rem higher. Pinned at the record's 8.5rem
   it would leave a hand's width of nothing above the rail on every scroll. */
@media (min-width: 1024px) {
    .cs-record-nobar .cs-record-side { top: 5rem; }
}

/* A rail too tall to pin (Reviews: where the reviews come from, and how the park
   answers them, beside a long list). Pinned, its last card only came into view at
   the foot of the page; it scrolls with the page instead. */
@media (min-width: 1024px) {
    .cs-record-unpinned .cs-record-side { position: static; }
}

/* Inside the main column: cards that belong beside each other go two-up
   once there is genuinely room, so a wide screen is not one tall ribbon
   of full-width boxes. */
.cs-record-cols { display: grid; grid-template-columns: 1fr; gap: 1.25rem; align-items: start; }
@media (min-width: 1280px) {
    .cs-record-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Command bar (cs-recordbar) ──────────────────────────────────
   The commands for the record, in one place, in the same order on every
   record. It replaces buttons scattered through the page: an owner
   learns the bar once.

   Below 1024px it is a strip that scrolls sideways like .cs-pills, and
   it is deliberately NOT sticky - the phone bottom bar owns the bottom
   edge and a second pinned bar eats a 664px viewport. Above it, it pins
   under the top bar at z-index 20: below .cs-topnav (30) and below every
   dropdown, sheet, day tip and modal, so it can never cover a dialog. */
.cs-recordbar {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.4rem 0.5rem;
    /* 10px, and one box rather than nine. The commands inside no longer carry
       their own borders, so this hairline is the only geometry on the bar - which
       is the point. A bordered panel full of bordered capsules is the shape the
       brief calls out: rounded rectangles inside rounded rectangles. */
    border-radius: 0.625rem;
    border: 1px solid #e4e6ed;
    background: #fff;
    margin-bottom: 1.25rem;
}

/* The commands live in their own scroller, and the overflow fold sits outside it.
   That split is the whole reason this element exists: `overflow-x: auto` makes
   `overflow-y` compute to auto as well, so a bar that scrolled its own contents
   would clip the fold's dropdown against its own bottom edge on a phone. It also
   takes the free space, which is what pushes the fold to the right without a
   spacer. */
.cs-recordbar-scroll {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}
.cs-recordbar-scroll::-webkit-scrollbar { display: none; }

/* "There is more this way." A row of commands that ends flush at the edge of a
   phone looks like a row that has finished, so an owner never swipes and never
   finds Delete. The fade is painted by cs-scroller.js only on the side that has
   something behind it, and clears the moment you reach that end.

   A mask rather than a gradient overlay: the buttons under it stay clickable, and
   it works over the tinted ground and over white without knowing which it is on.
   Not decoration - it is the only thing telling somebody the row moves - so it is
   the one place a soft edge earns its keep under section 7. */
.cs-scroller-end   { mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent 100%); }
.cs-scroller-start { mask-image: linear-gradient(to left,  #000 calc(100% - 2.5rem), transparent 100%); }
.cs-scroller-start.cs-scroller-end {
    mask-image: linear-gradient(to right, transparent 0, #000 2.5rem, #000 calc(100% - 2.5rem), transparent 100%);
}

/* Both ends are only ever an affordance for a pointer that cannot see a scrollbar.
   Above the record breakpoint the row wraps instead of scrolling, so there is
   nothing to fade and a mask would only clip a wrapped second line. */
@media (min-width: 1024px) {
    .cs-scroller-start, .cs-scroller-end, .cs-scroller-start.cs-scroller-end { mask-image: none; }
}
.cs-recordbar-scroll > * { flex: none; }
.cs-recordbar .cs-btn { min-height: 40px; white-space: nowrap; }
.cs-recordbar form { display: contents; }

/* A cluster of related commands, set off by a hairline rather than by a
   gap nobody reads as a grouping. */
.cs-recordbar-group {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding-left: 0.5rem;
    margin-left: 0.35rem;
    border-left: 1px solid #e4e6ed;
}
.cs-recordbar-group:first-child { padding-left: 0; margin-left: 0; border-left: 0; }

/* Every leaf in the bar holds its own width. The forms are display:contents, so the
   buttons are the flex items at whatever level they sit; without this they shrink
   under their own nowrap labels inside the scroller and the text runs out of the
   button rather than the row scrolling. */
.cs-recordbar .cs-btn { flex: none; }

/* Every command wears its picture. A toolbar somebody uses forty times a day is
   scanned by shape long before it is read, which is why Dynamics and Salesforce
   both draw one, and why a bar of identical text buttons is slower than the
   scattered buttons it replaced. The glyph is the CampSuite brand set - a
   currentColor line drawing with one Sunset Orange element - so a command is the
   same picture here as in the menu that got you to the screen. cs-btn-command
   sizes it; this only catches the buttons on the bar that are not commands. */
.cs-recordbar .cs-btn > svg {
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
}

/* The destructive end of the bar wears cs-btn-command-danger, which lives with
   the rest of the button taxonomy rather than here: quiet until you go near it,
   red when you do, and available to any toolbar rather than only to this one.
   It still reads as its own cluster because of the hairline before it, the way a
   Dynamics bar sets its last group apart. */

@media (min-width: 1024px) {
    .cs-recordbar {
        position: sticky;
        top: 4rem;
        z-index: 20;
        box-shadow: 0 8px 20px -18px rgba(24, 27, 33, .5);
    }
    /* There is room now, so the commands wrap onto a second line rather than
       hiding behind a scroll a mouse has no easy way to drive. */
    .cs-recordbar-scroll {
        flex-wrap: wrap;
        row-gap: 0.5rem;
        overflow-x: visible;
    }
}

/* Printing a record should print the record, not its buttons. */
@media print { .cs-recordbar { display: none; } }

/* ── Coming soon (cs-soon, _ComingSoon) ─────────────────────────────────────
   A feature still being built, told to the park plainly: the canopy with what it
   is and a picture of what it will make for them, drawn with their own park's
   name; three numbered steps (numbers, never icon chips); one honest line; and
   what already works today, as settings hub cards. The one Sunset Orange on the
   page is the "Coming soon" chip. */
.cs-soon-hero {
    display: grid; gap: 2rem; align-items: center;
    padding: 2rem 1.5rem; border-radius: 0.75rem; overflow: hidden;
}
@media (min-width: 1024px) {
    .cs-soon-hero { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); padding: 3rem; gap: 3rem; }
}
.cs-soon-kicker { display: flex; flex-wrap: wrap; align-items: center; gap: 0.625rem; margin: 0 0 1rem; font-size: 0.9375rem; font-weight: 600; color: rgba(238, 244, 250, .82); }
.cs-soon-chip { display: inline-flex; padding: 0.1875rem 0.625rem; border-radius: 0.375rem; background: #f06436; color: #0f213f; font-size: 0.8125rem; font-weight: 700; }
.cs-soon-title { margin: 0; font-size: clamp(1.875rem, 1.2rem + 2.4vw, 2.875rem); line-height: 1.12; font-weight: 700; color: #fff; letter-spacing: -0.01em; }
.cs-soon-lead { margin: 1.25rem 0 0; max-width: 38rem; font-size: 1.125rem; line-height: 1.55; color: rgba(238, 244, 250, .86); }
.cs-soon-preview { margin: 0; }

.cs-soon-mock { display: flex; flex-direction: column; gap: 0.75rem; max-width: 26rem; margin-inline: auto; }
.cs-soon-mocklabel { display: inline-flex; align-items: center; gap: 0.375rem; margin: 0; font-size: 0.8125rem; font-weight: 600; color: #eef4fa; }
.cs-soon-mocklabel svg { width: 1rem; height: 1rem; }
.cs-soon-post {
    border-radius: 0.75rem; background: #fff; color: #262a32;
    box-shadow: 0 24px 48px -16px rgba(5, 12, 26, .55);
}
.cs-soon-post { overflow: hidden; }
.cs-soon-posthead { display: flex; align-items: center; gap: 0.625rem; padding: 0.875rem 1rem; }
.cs-soon-postface { display: inline-flex; align-items: center; justify-content: center; width: 2.25rem; height: 2.25rem; border-radius: 9999px; background: #22568c; color: #fff; font-weight: 700; }
.cs-soon-postname { font-weight: 700; font-size: 0.9375rem; }
.cs-soon-postphoto { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
.cs-soon-postbody { margin: 0; padding: 0.875rem 1rem 0.5rem; font-size: 0.9375rem; line-height: 1.5; }
.cs-soon-postbtn { display: flex; justify-content: center; margin: 0.25rem 1rem 1rem; padding: 0.625rem; border-radius: 0.5rem; background: #eef4fa; color: #1b4472; font-weight: 700; font-size: 0.9375rem; }

.cs-soon-how { margin-top: 2.5rem; }
.cs-soon-steps { display: grid; gap: 1.5rem; margin: 1rem 0 0; padding: 0; list-style: none; }
@media (min-width: 768px) { .cs-soon-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem; } }
.cs-soon-step { padding-top: 1rem; border-top: 2px solid #e6e9ef; }
.cs-soon-num { display: block; font-size: 2rem; font-weight: 700; line-height: 1; color: #22568c; }
.cs-soon-steptitle { margin: 0.75rem 0 0; font-size: 1.125rem; font-weight: 700; color: #0f213f; }
.cs-soon-steptext { margin: 0.375rem 0 0; font-size: 1rem; line-height: 1.55; color: #414652; }
.cs-soon-honest { margin: 1.75rem 0 0; max-width: 46rem; font-size: 0.9375rem; color: #6c7280; }


/* ================================================================
   A list of jobs to go and do (cs-tasklist)
   ================================================================
   A run of linked rows inside a card, where each row is a thing to
   go and deal with rather than a record to read: the guided jobs on
   the sample-data screen are the first, and any "here is what needs
   your attention, in order" list is the next.

   Deliberately quieter than cs-setup-next, which belongs to the
   onboarding chrome and carries a large brand icon: this sits inside
   an ordinary cs-card on an ordinary screen, so it is a title, a
   sentence and a chevron, with a hairline between rows rather than a
   border round each. Nothing here is orange - a list where every row
   shouts is a list nobody reads.
   ================================================================ */

.cs-tasklist { display: block; }

.cs-tasklist-item {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1rem 1.25rem;
    color: inherit;
    text-decoration: none;
    transition: background-color .12s ease;
}
.cs-tasklist-item + .cs-tasklist-item { border-top: 1px solid #eef1f6; }

@media (hover: hover) {
    .cs-tasklist-item:hover { background: #f7f8fa; }
}
.cs-tasklist-item:focus-visible { outline: 3px solid rgba(34, 86, 140, .45); outline-offset: -3px; }

.cs-tasklist-body { flex: 1 1 auto; min-width: 0; }

.cs-tasklist-title {
    display: block;
    font-size: 1rem;
    font-weight: 600;
    color: #181b21;
    line-height: 1.4;
}

.cs-tasklist-detail {
    display: block;
    margin-top: 0.25rem;
    font-size: 1rem;
    color: #4e5461;
    line-height: 1.5;
}

.cs-tasklist-go {
    flex: 0 0 auto;
    margin-top: 0.25rem;
    width: 1.25rem;
    height: 1.25rem;
    color: #9aa1ad;
}

@media (pointer: coarse) {
    .cs-tasklist-item { min-height: 48px; }
}

/* ── Things in a list, each with its own tools (`cs-rowlist`) ──
   A page of a website, a link in a menu, a page waiting in Recently deleted: its name and a line
   about it on the left, its commands on the right, and a hairline between rows rather than a
   box round each. The tools wrap under the name by their own width, never by a breakpoint, so
   the row is right in a card of any width. A row can carry a fold of its own under it
   (a cs-disclose, its contents in a cs-rowlist-fold). */
.cs-rowlist { margin: 0; padding: 0; list-style: none; }
.cs-rowlist-item { padding: 0.85rem 0; }
.cs-rowlist-item + .cs-rowlist-item { border-top: 1px solid #eef1f6; }
.cs-rowlist-item:first-child { padding-top: 0.25rem; }
.cs-rowlist-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.75rem; }
.cs-rowlist-words { flex: 1 1 14rem; min-width: 0; }
.cs-rowlist-name { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.5rem; margin: 0; font-size: 1rem; font-weight: 600; color: #0f213f; overflow-wrap: anywhere; }
.cs-rowlist-sub { display: block; margin-top: 0.1rem; color: #6c7280; overflow-wrap: anywhere; }
.cs-rowlist-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; margin-right: -0.5rem; }
.cs-rowlist-tools form { display: inline; }
.cs-rowlist-item > .cs-disclose { margin-top: 0.25rem; }
.cs-rowlist-fold { margin-top: 0.5rem; padding: 1rem; border-radius: 0.625rem; background: #f7f8fa; }
/* The add row under a list: a hairline above it, like the rows it adds to. */
.cs-rowlist-add { margin-top: 0.75rem; padding-top: 1rem; border-top: 1px solid #eef1f6; }
/* A row that hangs off the one above it (a follow-up question under the question it follows):
   set in, with a rule down its edge, so it reads as part of the row above at any width. */
.cs-rowlist-follow { margin-left: 1.25rem; padding-left: 1rem; border-left: 2px solid #e3e7ee; }
.cs-rowlist-item + .cs-rowlist-follow { border-top: 0; }


/* ── The signed-out pages (cs-auth-*, _AuthLayout) ──────────────────
   Sign in, sign up, a forgotten password, a reset link, an invitation: one frame, so
   the journey reads as one place. The form is the brand's own furniture (cs-input,
   cs-btn-primary, cs-notice, cs-link); this block only lays it out and draws the photo.

   Phone: the form first, on white, and the campsite as a short band underneath with
   its one line, so the task is never pushed below the fold by a picture. From 1024px
   (the record breakpoint) the photo takes the left of the screen and stays put while
   the form scrolls. One set of markup; nothing moves between the two except the order. */
/* margin: 0 undoes the 60px every body is given for a footer these pages do not have. */
.cs-auth { min-height: 100vh; margin: 0; background: #fff; color: #181b21; }
.cs-auth-shell { display: flex; flex-direction: column; min-height: 100vh; }
.cs-auth-main {
    flex: 1 0 auto;
    display: flex;
    justify-content: center;
    padding: max(1rem, env(safe-area-inset-top)) 1rem 2rem;
}
.cs-auth-column { width: 100%; max-width: 28rem; display: flex; flex-direction: column; }
.cs-auth-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 2rem;
}
.cs-auth-logo { display: block; border-radius: 4px; }
.cs-auth-logo img { display: block; height: 2.5rem; width: auto; }
.cs-auth-logo:focus-visible { outline: 3px solid #22568c; outline-offset: 4px; }
.cs-auth-body { flex: 1 0 auto; }

/* The page's own heading: the display weight of the one family, deep blue. */
.cs-auth-title {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: #0f213f;
}
.cs-auth-lede { margin: 0.5rem 0 0; font-size: 1.0625rem; color: #414652; }
.cs-auth-lede + .cs-auth-lede { margin-top: 0.75rem; }
/* The address a message went to, so somebody can see at once whether they typed it right. */
.cs-auth-address { font-weight: 600; color: #0f213f; overflow-wrap: anywhere; }
/* The one picture on a status screen (sent, expired, done). Drawn plainly, never in a chip. */
.cs-auth-glyph { display: block; width: 2.5rem; height: 2.5rem; margin-bottom: 1rem; color: #22568c; }
.cs-auth-glyph-problem { color: #b42318; }

.cs-auth-notice { margin-top: 1.5rem; }
.cs-auth-notice ul { margin: 0.25rem 0 0; padding-left: 1.1rem; list-style: disc; }
.cs-auth-notice .validation-summary-valid { display: none; }

.cs-auth-form { display: flex; flex-direction: column; gap: 1.125rem; margin-top: 1.75rem; }
.cs-auth-form .cs-label { margin-bottom: 0.375rem; }
.cs-auth-form .cs-btn-primary { margin-top: 0.25rem; }
.cs-auth-form .cs-hint { margin-top: 0; }
.cs-auth-form .cs-hint + .cs-auth-error { margin-top: 0.25rem; }
/* An address the page already knows (an invitation's), shown but not for changing. */
.cs-auth-form .cs-input[readonly] { background: #f7f8fa; color: #4e5461; box-shadow: none; }
.cs-auth-error { display: block; margin-top: 0.375rem; font-size: 1rem; color: #b42318; }
.cs-auth-error:empty,
.cs-auth-error[hidden] { display: none; }
.cs-auth-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.25rem 1rem;
}
.cs-auth-check {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    min-height: 44px;
    padding-top: 0.6rem;
    font-size: 1rem;
    color: #414652;
    cursor: pointer;
    user-select: none;
}
.cs-auth-check input {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    margin-top: 0.1rem;
    accent-color: #22568c;
}
.cs-auth-check input:focus-visible { outline: 3px solid #22568c; outline-offset: 2px; }
.cs-auth-row .cs-auth-check { align-items: center; padding-top: 0; }
/* A button that reads as a link, inside a sentence (the terms on sign-up). */
.cs-auth-check button.cs-link { padding: 0; border: 0; background: none; font: inherit; font-weight: 600; cursor: pointer; }

/* A password box with its Show button inside the right-hand end. The button is drawn by
   cs-auth.js, so with no script there is simply a password box. */
.cs-auth-secret { position: relative; }
.cs-auth-secret .cs-input { padding-right: 5.5rem; }
.cs-auth-reveal {
    position: absolute;
    top: 50%;
    right: 0.3rem;
    transform: translateY(-50%);
    min-height: 40px;
    min-width: 4rem;
    padding: 0 0.75rem;
    border: 0;
    border-radius: 0.375rem;
    background: none;
    font: inherit;
    font-size: 0.9375rem;
    font-weight: 600;
    color: #22568c;
    cursor: pointer;
}
.cs-auth-reveal:hover { background: #eef4fa; }
.cs-auth-reveal:focus-visible { outline: 3px solid #22568c; outline-offset: -3px; }

/* What comes after the form: "New to CampSuite?", "Back to sign in". */
.cs-auth-alt { margin: 1.25rem 0 0; text-align: center; font-size: 1rem; color: #414652; }
.cs-auth-after {
    margin-top: 1.75rem;
    padding-top: 1.25rem;
    border-top: 1px solid #e4e6ed;
    text-align: center;
}
.cs-auth-after .cs-auth-alt { margin-top: 0; }
.cs-auth-after .cs-auth-alt + .cs-auth-alt { margin-top: 0.75rem; }
.cs-auth-foot {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 2.5rem;
    text-align: center;
    font-size: 0.9375rem;
    color: #6c7280;
}
.cs-auth-foot p { margin: 0; }

/* The photo, and the one line it carries. The scrim is there for the words, not for
   decoration: white type needs a dark ground under it whatever the sky is doing. */
.cs-auth-photo {
    position: relative;
    min-height: 13rem;
    overflow: hidden;
    background: #0f213f;
    color: #fff;
}
.cs-auth-photo img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 78% 62%;   /* keeps the motorhome in a narrow crop */
}
.cs-auth-photo::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(15, 33, 63, .9) 0%, rgba(15, 33, 63, .45) 40%, rgba(15, 33, 63, 0) 72%);
}
.cs-auth-photo-copy {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    height: 100%;
    min-height: inherit;
    padding: 1.5rem 1rem calc(1.5rem + env(safe-area-inset-bottom));
}
.cs-auth-photo-copy p { margin: 0; }
.cs-auth-eyebrow {
    display: none;
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #eef4fa;
}
/* The one touch of Sunset Orange on the panel: a short rule, the brand's active mark. */
.cs-auth-eyebrow::before {
    content: "";
    display: block;
    width: 2.25rem;
    height: 3px;
    margin-bottom: 0.75rem;
    border-radius: 2px;
    background: #f06436;
}
.cs-auth-photo-title {
    max-width: 20ch;
    text-wrap: balance;
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -0.02em;
}
.cs-auth-photo-sub,
.cs-auth-photo-note { display: none; }

@media (min-width: 640px) {
    .cs-auth-main { padding: 2rem 1.5rem 2.5rem; }
    .cs-auth-title { font-size: 2rem; }
    .cs-auth-logo img { height: 3rem; }
}

@media (min-width: 1024px) {
    .cs-auth-shell {
        display: grid;
        grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    }
    .cs-auth-photo {
        grid-column: 1;
        grid-row: 1;
        position: sticky;
        top: 0;
        height: 100vh;
    }
    .cs-auth-main { grid-column: 2; grid-row: 1; padding: 2.5rem 3rem; }
    .cs-auth-column { min-height: calc(100vh - 5rem); }
    .cs-auth-body { display: flex; flex-direction: column; justify-content: center; }
    .cs-auth-photo-copy { padding: 3rem; }
    .cs-auth-eyebrow { display: block; }
    .cs-auth-photo-title { margin-top: 0.75rem; font-size: 3rem; }
    .cs-auth-photo-sub { display: block; margin-top: 1rem; font-size: 1.25rem; color: #eef4fa; max-width: 32rem; }
    .cs-auth-photo-note { display: block; margin-top: 1.25rem; font-size: 0.9375rem; color: rgba(238, 244, 250, .8); }
}


/* =====================================================================
   CampSuite controls: one sheet for switches, choice controls, tabs,
   navigation, links and commands.

   Built from the four family finals (toggles, choices, tabs, links) with
   every cross-family fix applied. It is the LAST section of site.css on
   purpose: it restyles the classes and markup the console already ships and
   wins over the earlier rules it names by coming after them. Rules marked
   BRIDGE reach markup that has not yet moved onto the shared classes; they
   go once that markup migrates, and the earlier rules each section names
   can then be deleted.

   ONE OWNER PER SELECTOR
     cs-switch, cs-ed-switch, bare on/off checkboxes, cs-jobtick ... 1 Switches
     cs-segment (views), cs-segchip, cs-pills, cs-radiocard,
     cs-unitchip, picture tiles, grid furniture ..................... 2 Choices
     tab rows (cs-tabs, the cs-segment rows that are really tabs,
     Take a booking's kinds), rail, drawer, mega panel, top bar,
     bottom bar, record bar layout ................................... 3 Tabs
     cs-link, cs-btn-link, record and contact links, the way back,
     crumbs, whole-row links ......................................... 4 Links
     cs-btn-command and the record bar's buttons ..................... 5 Commands
     the "more this way" cue on every sideways scroller .............. 6 Cue

   DECISIONS (to copy into DESIGN.md as one table)
     Chosen, in a segment: a FILLED Primary Blue cell, white words, the
       same weight as its neighbours. An outline only ever means focus.
     Chosen, as a separate thing (chip, tile, card): a 2px Primary Blue
       edge plus a mark. ROUND mark = pick one, SQUARE tick box = pick
       several, both 22px. Words Deep Blue, weight never changes.
     Tabs: Deep Blue words at 700 (tracking -0.016em, so nothing shifts)
       and a 3px Primary Blue bar. The only control whose weight changes.
     Where you are on light ground (rail, drawer, mega panel, bottom bar):
       Deep Blue words and the same 3px Primary Blue bar.
     Phone segments: two answers share the row; three or more views
       become a list with a trailing tick; three or more answers become
       tiles with a drawn radio. The Job sheet person filter wraps as chips.
     Sibling pages are tabs, through the _Tabs link variant: Email
       templates System / Custom, Closures, Recently deleted, Team and
       access, Website pages. Translations: one _LanguageTabs partial
       (picker on a phone, tabs on a desk). Inbox filters (Reviews,
       Messages, Social comments) are cs-pills through one _InboxFilter.
       Spaces "Archived" is a cs-viewpick view. VAT display is a
       radiogroup segment. Take a booking's kinds are tabs.
     Pick several picture tiles (pitch form, space form, pitch type,
       unit question) all move to cs-unitchips / cs-unitchip with
       checkbox inputs. The Job sheet frequency is choice tiles
       (cs-choicetiles grid-cols-1 sm:grid-cols-2); "Runs all year" is a
       cs-switch with the months in a cs-switch-panel.
     ARIA, exactly three contracts for a segment: links with
       aria-current="page"; a radiogroup of real radios; buttons with
       aria-pressed for an in-place view switch with no URL (the map,
       Visual | HTML).
     The way back: one cs-backlink above the title, worded as the parent
       ("Bookings", "Pitches", "Accommodation", "Settings"), 48px on
       touch. cs-crumbs only for trails three or more deep.
     Focus: one colour, #22568C. Three shapes: outside at 2px for a
       control, inside at 3px for a whole row, the filled capsule for a
       word in a sentence. On the navy top bar the ring is white.
     Disabled, everywhere: label grey words (#5B6274), a #B4BAC6 edge,
       cursor not-allowed, and the reason in a one-line cs-hint.
     Counts, everywhere: cs-count. #434956, regular weight, the size of
       its word, no brackets, no bubble ("Filters 1").
     Radius scale: 6px small marks (tick box, capsule); 8px chips,
       cells, buttons, tiles; 10px tracks and inputs; 12px cards.
     Orange: the Take a booking CTA, the top bar marker and the bottom
       bar New key. Nowhere else, not even inside a glyph.
   ===================================================================== */


/* =====================================================================
   0. TOKENS
   To live in site.css :root and cs-theme.js. The family names below
   (--cc-, --tb-, --sw-, --csl-) are aliases so each section reads as
   its family wrote it; they go when the sheet folds in.
   ===================================================================== */
:root {
    /* Brand */
    --cs-ink: #0F213F;               /* Deep Blue */
    --cs-blue: #22568C;              /* Primary Blue: 7.6:1 on white, 6.9:1 on paper */
    --cs-blue-dark: #1B4472;
    --cs-body: #262A32;
    --cs-label: #5B6274;             /* 6.1:1 on white */
    --cs-count: #434956;             /* every count: 9:1 on white */
    --cs-paper: #F2F5F9;
    --cs-error: #B42318;

    /* Edges: three greys and no others */
    --cs-edge: #868E9E;              /* 3.3:1 on white: every component boundary, tab rule, track, chevron, unchosen chip / tile / card edge */
    --cs-edge-strong: #6F7585;       /* 4.6:1: switch off edge, empty radio and tick rings, hover edge */
    --cs-hair: #E6E9EF;              /* decorative dividers only */
    --cs-disabled-edge: #B4BAC6;     /* disabled, exempt from 1.4.11 */

    /* Selected: one block for all four families */
    --cs-selected-edge: #22568C;
    --cs-selected-ink: #0F213F;
    --cs-selected-bar: #22568C;
    --cs-selected-fill: #22568C;
    --cs-selected-fill-ink: #FFFFFF;
    --cs-selected-fill-count: #DCE6F2;   /* 6.0:1 on the fill */

    /* Focus: one colour, one weight */
    --cs-focus: #22568C;
    --cs-ring: 3px solid #22568C;

    /* Radius scale */
    --cs-r-mark: 6px;
    --cs-r-chip: 8px;
    --cs-r-track: 10px;
    --cs-r-card: 12px;

    /* Surfaces under the pointer */
    --cs-wash: rgba(15, 33, 63, 0.06);
    --cs-press: rgba(15, 33, 63, 0.11);

    /* Target height: 44px with a mouse, 48px under a finger */
    --cs-h: 44px;

    /* Marks */
    --cs-tick-white: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5.5 10.3l3 3 6-6.6' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --cs-check-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M4.5 10.5l3.6 3.6 7.4-7.8' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --cs-chev-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 2.25 8.25 6 4.5 9.75'/%3E%3C/svg%3E");
    /* The one "more this way" cue: a Primary Blue chevron on a solid patch */
    --cs-cue-w: 2.25rem;
    --cs-cue-r: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M7.5 4.5 13 10l-5.5 5.5' fill='none' stroke='%2322568c' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --cs-cue-l: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M12.5 4.5 7 10l5.5 5.5' fill='none' stroke='%2322568c' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");

    /* --- Family aliases --- */
    --cc-ink: var(--cs-selected-ink);
    --cc-blue: var(--cs-blue);
    --cc-text: var(--cs-body);
    --cc-label: var(--cs-label);
    --cc-ring: var(--cs-edge-strong);
    --cc-edge: var(--cs-edge);
    --cc-hair: var(--cs-hair);
    --cc-paper: var(--cs-paper);
    --cc-chosen: inset 0 0 0 1px var(--cs-selected-edge);   /* with a 1px blue border: a 2px edge that never shifts layout */
    --cc-t: 160ms;
    --cc-ease: cubic-bezier(0.25, 0.1, 0.25, 1);

    --tb-ink: var(--cs-ink);
    --tb-blue: var(--cs-blue);
    --tb-body: var(--cs-body);
    --tb-label: var(--cs-label);
    --tb-paper: var(--cs-paper);
    --tb-rule: var(--cs-edge);
    --tb-tint: #E6EEF7;
    --tb-ease: cubic-bezier(.25, .1, .25, 1);
    --tb-warn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.6 2.6 20h18.8L12 3.6z' fill='none' stroke='%23000' stroke-width='2' stroke-linejoin='round'/%3E%3Cpath d='M12 9.6v4.8' stroke='%23000' stroke-width='2.2' stroke-linecap='round'/%3E%3Ccircle cx='12' cy='17.2' r='1.3'/%3E%3C/svg%3E");

    --csl-tint: var(--cs-blue);
    --csl-ink-pressed: var(--cs-ink);
    --csl-ink: var(--cs-body);
    --csl-label: var(--cs-label);
    --csl-hair: var(--cs-hair);
    --csl-paper: var(--cs-paper);
    --csl-press-wash: rgba(34, 86, 140, 0.12);
    --csl-ul-rest: 1px;
    --csl-ul-hover: 2px;
    --csl-ul-offset: 0.24em;
    --csl-ul-colour: color-mix(in srgb, currentColor 70%, transparent);
    --csl-ring: var(--cs-ring);
    --csl-ease: cubic-bezier(0.25, 0.1, 0.25, 1);
    --csl-chev: var(--cs-chev-mask);
    --csl-back: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 12H4.4m0 0 5.4-5.4M4.4 12l5.4 5.4'/%3E%3C/svg%3E");
    --csl-out: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.75 8.25 8.5 3.5M4.5 3.25h4.25V7.5'/%3E%3C/svg%3E");
    --csl-mail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5.5' width='18' height='13' rx='2'/%3E%3Cpath d='m3.75 7.25 8.25 5.75 8.25-5.75'/%3E%3C/svg%3E");
    --csl-phone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.6 3.75H6.25a2 2 0 0 0-2 2.2 15.8 15.8 0 0 0 13.8 13.8 2 2 0 0 0 2.2-2v-2.35a1.25 1.25 0 0 0-.9-1.2l-2.6-.75a1.25 1.25 0 0 0-1.25.35l-.95 1a11.3 11.3 0 0 1-4.95-4.95l1-.95a1.25 1.25 0 0 0 .35-1.25l-.75-2.6a1.25 1.25 0 0 0-1.2-.9Z'/%3E%3C/svg%3E");
    /* Row command glyphs, single colour: body ink at rest, Primary Blue
       dark under the pointer. BRIDGE until _HomeOrganiser passes its <svg>. */
    --csl-cmd-pay: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23262a32' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.8' y='2.8' width='10' height='18.4' rx='2.2'/%3E%3Cpath d='M7.8 18h2M16.6 9.2a4 4 0 0 1 0 5.6M19.2 6.8a7.4 7.4 0 0 1 0 10.4'/%3E%3C/svg%3E");
    --csl-cmd-pay-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231b4472' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.8' y='2.8' width='10' height='18.4' rx='2.2'/%3E%3Cpath d='M7.8 18h2M16.6 9.2a4 4 0 0 1 0 5.6M19.2 6.8a7.4 7.4 0 0 1 0 10.4'/%3E%3C/svg%3E");
    --csl-cmd-call: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23262a32' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.1 3.9 10 8.1l-1.9 1.5a11.4 11.4 0 0 0 5.3 5.3l1.5-1.9 4.2 1.9v3a1.9 1.9 0 0 1-2.1 1.9A16.4 16.4 0 0 1 3.2 6a1.9 1.9 0 0 1 1.9-2.1z'/%3E%3Cpath d='M15.6 4.2a5.6 5.6 0 0 1 4.2 4.2M14.9 7.4a2.6 2.6 0 0 1 1.9 1.9'/%3E%3C/svg%3E");
    --csl-cmd-call-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231b4472' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.1 3.9 10 8.1l-1.9 1.5a11.4 11.4 0 0 0 5.3 5.3l1.5-1.9 4.2 1.9v3a1.9 1.9 0 0 1-2.1 1.9A16.4 16.4 0 0 1 3.2 6a1.9 1.9 0 0 1 1.9-2.1z'/%3E%3Cpath d='M15.6 4.2a5.6 5.6 0 0 1 4.2 4.2M14.9 7.4a2.6 2.6 0 0 1 1.9 1.9'/%3E%3C/svg%3E");
    --csl-cmd-view: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23262a32' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='5.6' width='17' height='14' rx='2.2'/%3E%3Cpath d='M3.5 10h17M9.4 10v9.6M8.2 3.4h4.6'/%3E%3C/svg%3E");
    --csl-cmd-view-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231b4472' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='5.6' width='17' height='14' rx='2.2'/%3E%3Cpath d='M3.5 10h17M9.4 10v9.6M8.2 3.4h4.6'/%3E%3C/svg%3E");
    --csl-cmd-edit: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23262a32' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17.6 6.4 7.9 16.1l-4 1.1 1.1-4 9.7-9.7M14.7 3.5l2.4-2.4a1.9 1.9 0 0 1 2.7 2.7l-2.2 2.6M12.6 20.3h7.9'/%3E%3C/svg%3E");
    --csl-cmd-edit-hover: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231b4472' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17.6 6.4 7.9 16.1l-4 1.1 1.1-4 9.7-9.7M14.7 3.5l2.4-2.4a1.9 1.9 0 0 1 2.7 2.7l-2.2 2.6M12.6 20.3h7.9'/%3E%3C/svg%3E");

    /* Switch geometry (touch first) */
    --sw-w: 3.25rem;
    --sw-h: 2rem;
    --sw-knob: 1.75rem;
    --sw-inset: 0.125rem;
    --sw-press: 2.125rem;
    --sw-ink: var(--cs-body);
    --sw-grey: var(--cs-label);
    --sw-hair: var(--cs-hair);
    --sw-paper: var(--cs-paper);
    --sw-on: var(--cs-blue);
    --sw-on-hover: #1F4C7E;
    --sw-off-fill: #EDF0F4;
    --sw-off-fill-hover: #DFE3EA;
    --sw-edge: var(--cs-edge-strong);
    --sw-edge-hover: var(--cs-label);
    --sw-edge-w: 1.5px;
    --sw-dis-edge: var(--cs-disabled-edge);
    --sw-dis-on: #A7BBD1;
    --sw-knob-shadow: 0 1px 1px rgba(15, 33, 63, 0.10), 0 2px 6px rgba(15, 33, 63, 0.22);
    --sw-knob-shadow-off: 0 1px 2px rgba(15, 33, 63, 0.14);
    --sw-row-max: 42rem;
    --sw-over: calc((var(--sw-h) - 1.5rem) / 2);
    --sw-ease: cubic-bezier(0.25, 0.8, 0.35, 1);
    --sw-time: 180ms;
    --sw-pad: 1rem;
    /* Name to hint. 8px, so a row with a hint is still a 48px target
       under a finger (16 + 24 + 8) and 44px with a mouse (12 + 24 + 8). */
    --sw-gap: 0.5rem;
}
@media (pointer: coarse) {
    :root { --cs-h: 48px; }
}
@media (hover: hover) and (pointer: fine) and (min-width: 640px) {
    :root {
        --sw-pad: 0.75rem;
        --sw-w: 3rem;
        --sw-h: 1.75rem;
        --sw-knob: 1.5rem;
        --sw-press: 1.875rem;
    }
}

/* Brand glyphs keep their one Sunset Orange element everywhere: navy (or
   white on the top bar) with orange is the brand set. --cs-ico-fill lets a
   glyph fill its first outline (the bottom bar's current item); custom
   properties inherit into <use> clones. */
symbol > [fill="none"]:first-child { fill: var(--cs-ico-fill, none); }


/* =====================================================================
   4. LINKS
   Blue words go somewhere: Primary Blue at rest, Deep Blue under the
   pointer and pressed. Five roles, one geometry each. One underline
   geometry, one focus ring.
   ===================================================================== */

/* ---------------------------------------------------------------------
   4a. THE LINK INSIDE A SENTENCE (cs-link)
   REPLACES site.css .cs-link (1186-1193), .cs-auth-check button.cs-link,
   .cs-verdict a, .cs-card-deep a:not([class]); cs-map-chrome.css
   .csm-credit a (1035), .csm-imagery-credit a (668).
   --------------------------------------------------------------------- */
.cs-link,
.cs-btn-link:not(.cs-btn),
.cs-hint a:not([class]),
.cs-notice-body a:not([class]),
.cs-verdict a,
a[class~="text-emerald-700"],
a[class~="text-brand-700"],
p a[class~="underline"] {
    color: var(--csl-tint);
    font: inherit;
    font-weight: 500;
    text-decoration-line: underline;
    text-decoration-thickness: var(--csl-ul-rest);
    text-decoration-color: var(--csl-ul-colour);
    text-underline-offset: var(--csl-ul-offset);
    text-decoration-skip-ink: auto;
    border-radius: var(--cs-r-mark);
    overflow-wrap: anywhere;
    -webkit-tap-highlight-color: transparent;
    transition: color 0.15s var(--csl-ease), text-decoration-color 0.15s var(--csl-ease), text-decoration-thickness 0.15s var(--csl-ease), background-color 0.15s var(--csl-ease);
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}
.cs-link:visited { color: var(--csl-tint); }
@media (hover: hover) {
    .cs-link:hover,
    .cs-btn-link:not(.cs-btn):hover,
    .cs-hint a:not([class]):hover,
    .cs-notice-body a:not([class]):hover,
    .cs-verdict a:hover,
    a[class~="text-emerald-700"]:hover,
    a[class~="text-brand-700"]:hover,
    p a[class~="underline"]:hover {
        color: var(--csl-ink-pressed);
        text-decoration-line: underline;
        text-decoration-thickness: var(--csl-ul-hover);
        text-decoration-color: currentColor;
    }
}
.cs-link:active,
.cs-btn-link:not(.cs-btn):active,
.cs-hint a:not([class]):active,
.cs-notice-body a:not([class]):active,
.cs-verdict a:active,
a[class~="text-emerald-700"]:active,
a[class~="text-brand-700"]:active,
p a[class~="underline"]:active {
    color: var(--csl-ink-pressed);
    text-decoration-line: underline;
    text-decoration-thickness: var(--csl-ul-hover);
    text-decoration-color: currentColor;
    background-color: var(--csl-press-wash);
    transition-duration: 0s;
}
/* Focus inside a sentence: the capsule. White words on solid Primary
   Blue with a 3px corner; its 1px bleed is given back by a negative
   margin, so nothing moves. */
.cs-link:focus-visible,
.cs-btn-link:not(.cs-btn):focus-visible,
.cs-hint a:not([class]):focus-visible,
.cs-notice-body a:not([class]):focus-visible,
.cs-verdict a:focus-visible,
a[class~="text-emerald-700"]:focus-visible,
a[class~="text-brand-700"]:focus-visible,
p a[class~="underline"]:focus-visible {
    outline: 0;
    color: #FFFFFF;
    background-color: var(--csl-tint);
    text-decoration-color: transparent;
    border-radius: 3px;
    padding-inline: 1px;
    margin-inline: -1px;
    transition: none;
}
.cs-link.block:focus-visible,
.cs-itable .cs-link:focus-visible,
a.cs-link:has(> .cs-channelname):focus-visible {
    color: var(--csl-tint);
    background-color: transparent;
    padding-inline: 0;
    margin-inline: 0;
    outline: var(--csl-ring);
    outline-offset: 2px;
}
.cs-hint:has(a),
.cs-notice-body:has(a),
p:has(> .cs-link) { line-height: 1.5; }
.cs-auth-check button.cs-link { font-weight: 500; padding: 0; }
.cs-link.block,
.cs-itable .cs-link { font-size: max(1em, 1rem); }
p.text-sm:has(> a.cs-link, > a[class~="underline"], > a[class~="text-emerald-700"]),
#csBlockedModal p.text-sm { font-size: 1rem; line-height: 1.5; }
label[for] > span > span.text-emerald-700:first-child {
    color: var(--csl-tint);
    font-weight: 600;
    text-decoration-line: underline;
    text-decoration-thickness: var(--csl-ul-rest);
    text-decoration-color: var(--csl-ul-colour);
    text-underline-offset: var(--csl-ul-offset);
}
@media (hover: hover) {
    label[for]:hover > span > span.text-emerald-700:first-child { color: var(--csl-ink-pressed); text-decoration-thickness: var(--csl-ul-hover); text-decoration-color: currentColor; }
}
label:has(> input.sr-only:focus-visible),
label:has(+ input.sr-only:focus-visible) { outline: var(--csl-ring); outline-offset: 2px; }
.cs-verdict a { color: var(--csl-tint); }
.cs-card-deep a:not([class]) {
    color: #FFFFFF;
    text-decoration-thickness: var(--csl-ul-rest);
    text-underline-offset: var(--csl-ul-offset);
    text-decoration-color: rgba(255, 255, 255, 0.7);
}
.cs-card-deep a:not([class]):hover { text-decoration-thickness: var(--csl-ul-hover); text-decoration-color: #FFFFFF; }
.cs-card-deep a:not([class]):focus-visible { outline: 0; background: #FFFFFF; color: var(--cs-ink); border-radius: 3px; padding-inline: 1px; margin-inline: -1px; text-decoration-color: transparent; }

/* ---------------------------------------------------------------------
   4b. THE STANDALONE TEXT ACTION (cs-btn cs-btn-link)
   REPLACES site.css .cs-btn-link and variants (1161-1171, 1206-1217),
   .cs-notice-body > .cs-btn-link (1791), .cs-section-head > .cs-btn-link,
   .cs-home-rest .cs-btn-link (8479-8482), .cs-widgetpreview-more
   (9757-9759), .cs-mega-footlink (3913-3918), .cs-preview-open
   (8314-8324), .cs-setup-change (6959-6972), the page-local
   .cs-price-override.
   Apple's "Learn more >": 16px semibold tint, a trailing chevron when it
   goes somewhere, an up-right arrow when it leaves CampSuite. 44 / 48px
   target built from padding and handed back by negative margins.
   --------------------------------------------------------------------- */
.cs-btn.cs-btn-link,
.cs-btn-link.cs-btn {
    --csl-hit: 44px;
    --csl-pad-x: 14px;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.3em;
    min-height: 0;
    padding: calc((var(--csl-hit) - 1.25em) / 2) var(--csl-pad-x);
    margin-inline: calc(var(--csl-pad-x) * -1);
    border: 0;
    border-radius: var(--cs-r-chip);
    background: transparent;
    color: var(--csl-tint);
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.25;
    text-align: left;
    text-decoration: none;
    white-space: normal;
    transform: none;
    transition: color 0.15s var(--csl-ease);
}
@media (pointer: coarse) {
    .cs-btn.cs-btn-link { --csl-hit: 48px; }
}
@media (min-width: 640px) and (pointer: fine) {
    .cs-btn.cs-btn-link { min-height: 0; padding: calc((var(--csl-hit) - 1.25em) / 2) var(--csl-pad-x); }
}
@media (hover: hover) {
    .cs-btn.cs-btn-link:hover {
        color: var(--csl-ink-pressed);
        background: transparent;
        text-decoration-line: underline;
        text-decoration-thickness: var(--csl-ul-hover);
        text-underline-offset: var(--csl-ul-offset);
    }
}
.cs-btn.cs-btn-link:active {
    color: var(--csl-ink-pressed);
    text-decoration-line: underline;
    text-decoration-thickness: var(--csl-ul-hover);
    text-underline-offset: var(--csl-ul-offset);
    transform: none;
    transition-duration: 0s;
}
.cs-btn.cs-btn-link:focus-visible {
    outline: var(--csl-ring);
    outline-offset: calc((var(--csl-hit) - 1.25em) / -2 + 3px);
    border-radius: calc((var(--csl-hit) - 1.25em) / 2 + 1px);
}
.cs-btn.cs-btn-link > svg { flex: none; width: 1.125rem; height: 1.125rem; }
a.cs-btn.cs-btn-link:not(:has(> svg))::after,
span.cs-btn.cs-btn-link::after,
.cs-mega-footlink::after,
.cs-preview-open::after {
    content: "";
    flex: none;
    width: 0.75em;
    height: 0.75em;
    margin-left: -0.05em;
    background-color: currentColor;
    -webkit-mask: var(--csl-chev) center / contain no-repeat;
            mask: var(--csl-chev) center / contain no-repeat;
}
a[target="_blank"][href]:is(.cs-link, .cs-btn, .cs-rowlink, .cs-itable-code, .cs-recordlink)::after,
:is(.cs-hint, .cs-notice-body, .cs-verdict, p) > a[target="_blank"]:not([class])::after {
    content: "" / " (opens in a new tab)";
    display: inline-block;
    flex: none;
    width: 0.75em;
    height: 0.75em;
    margin-left: 0.2em;
    vertical-align: -0.02em;
    background-color: currentColor;
    -webkit-mask: var(--csl-out) center / contain no-repeat;
            mask: var(--csl-out) center / contain no-repeat;
}
a[target="_blank"]:has(.sr-only)::after { content: ""; }
a[target="_blank"].cs-btn-command::after { margin-left: 0; width: 0.6875em; height: 0.6875em; }
.cs-notice-body > .cs-btn-link { margin-left: calc(var(--csl-pad-x) * -1); font-size: 1rem; }
.cs-btn.cs-btn-link:disabled,
.cs-btn.cs-btn-link[aria-disabled="true"],
.cs-link[aria-disabled="true"] {
    color: var(--csl-label);
    text-decoration: none;
    cursor: not-allowed;
}
.cs-link[aria-current="page"],
.cs-btn.cs-btn-link[aria-current="page"] {
    color: var(--csl-ink);
    font-weight: 600;
    text-decoration: none;
    cursor: default;
}

/* ---------------------------------------------------------------------
   4d. WHOLE-ROW LINKS. The row is the one target: paper under the
   pointer, the hairline grey pressed, a #868E9E chevron when it carries
   no action word, and the solid ring drawn inside the row.
   REPLACES site.css the translucent row rings (1445, 1856, 1904, 4086,
   6878, 6922, 6972, 7037, 7120, 8423-8426, 8603, 8726, 9416, 9555, 10943),
   the #F7F8FA row hovers and the #CED2DD / #9AA1AD row chevrons.
   --------------------------------------------------------------------- */
@media (hover: hover) {
    a.cs-home-row:hover,
    button.cs-home-row:hover { background: var(--csl-paper); }
    a.cs-home-row:hover .cs-btn-link,
    a.cs-tally-item:hover .cs-btn-link {
        color: var(--csl-ink-pressed);
        text-decoration-line: underline;
        text-decoration-thickness: var(--csl-ul-hover);
        text-underline-offset: var(--csl-ul-offset);
    }
}
a.cs-home-row:active,
button.cs-home-row:active { background: var(--csl-hair); transition: none; }
a.cs-home-row,
button.cs-home-row { transition: background-color 0.15s var(--csl-ease); }
a.cs-home-row:not(:has(.cs-btn-link))::after {
    content: "";
    flex: none;
    align-self: center;
    width: 0.75rem;
    height: 0.75rem;
    margin-left: -0.25rem;
    background-color: var(--cs-edge);
    -webkit-mask: var(--csl-chev) center / contain no-repeat;
            mask: var(--csl-chev) center / contain no-repeat;
}
a.cs-home-row:focus-visible,
button.cs-home-row:focus-visible,
a.cs-jobrow-main:focus-visible,
a.cs-daystrip-day:focus-visible,
.cs-tasklist-item:focus-visible,
a.cs-synccell:focus-visible,
button.cs-synccell:focus-visible,
.cs-emailrow:focus-visible,
.cs-fold-summary:focus-visible,
.cs-setup-fold > summary:focus-visible,
.cs-setup-next:focus-visible,
.cs-pitchgroup-toggle:focus-visible {
    outline: var(--csl-ring);
    outline-offset: -3px;
    border-radius: var(--cs-r-card);
}
a.cs-tally-item:focus-visible,
.cs-setup-back:focus-visible,
.cs-guestlang > summary:focus-visible,
.cs-setup-more > summary:focus-visible,
.cs-jobfold > summary:focus-visible {
    outline: var(--csl-ring);
    outline-offset: 2px;
    border-radius: var(--cs-r-mark);
}
a.cs-tally-item .cs-tally-label {
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    color: var(--csl-tint);
}
a.cs-tally-item .cs-tally-label::after {
    content: "";
    flex: none;
    width: 0.75em;
    height: 0.75em;
    background-color: currentColor;
    -webkit-mask: var(--csl-chev) center / contain no-repeat;
            mask: var(--csl-chev) center / contain no-repeat;
}
@media (hover: hover) {
    a.cs-tally-item:hover .cs-tally-label {
        color: var(--csl-ink-pressed);
        text-decoration-line: underline;
        text-decoration-thickness: var(--csl-ul-hover);
        text-underline-offset: var(--csl-ul-offset);
    }
}
a.cs-tally-item:active .cs-tally-label { color: var(--csl-ink-pressed); }
.cs-settings-go,
.cs-emailitem-chev,
.cs-tasklist-go,
.cs-jobrow-go { color: var(--cs-edge); }
@media (hover: hover) {
    .cs-settings-card:hover .cs-settings-go,
    a:hover > .cs-emailitem-chev,
    .cs-tasklist-item:hover > .cs-tasklist-go,
    a.cs-jobrow-main:hover .cs-jobrow-go { color: var(--csl-tint); }
    .cs-tasklist-item:hover,
    a.cs-jobrow-main:hover { background: var(--csl-paper); }
}
.cs-tasklist-item:active,
a.cs-jobrow-main:active { background: var(--csl-hair); transition: none; }
.cs-tasklist-item:focus-visible > .cs-tasklist-go,
a.cs-jobrow-main:focus-visible .cs-jobrow-go { color: var(--csl-tint); }
.cs-settings-grid > .cs-settings-card:active { background: var(--csl-hair); transition: none; }
.cs-settings-grid > .cs-settings-card:focus-visible {
    outline: var(--csl-ring);
    outline-offset: -3px;
    border-radius: var(--cs-r-card);
    z-index: 1;
}
.cs-settings-card:focus-visible .cs-settings-go { color: var(--csl-tint); }

/* ---------------------------------------------------------------------
   4e. THE RECORD LINK: the name or reference that opens a record
   (cs-recordlink when folded in).
   REPLACES site.css a.cs-itable-code (4780-4796), a.cs-org-title
   (8569-8570), a.cs-essentials-next-name (8691-8692), a.cs-inv-card__code
   (3282-3295), .cs-fact-val a (2204).
   --------------------------------------------------------------------- */
a.cs-itable-code,
a.cs-org-title,
a.cs-essentials-next-name,
a.cs-inv-card__code,
a.cs-recordlink,
.cs-fact-val a:not([class]),
.cs-preview-val a:not([class]),
.cs-itable td a:not([class]),
a.cs-rowlink:not([href^="mailto:"]):not([href^="tel:"]):not([href^="sms:"]) {
    color: var(--csl-tint);
    font-weight: 600;
    text-decoration: none;
    text-transform: none;
    letter-spacing: normal;
    border-radius: var(--cs-r-mark);
    -webkit-tap-highlight-color: transparent;
    transition: color 0.15s var(--csl-ease);
}
a.cs-itable-code,
a.cs-inv-card__code,
a.cs-org-title,
a.cs-recordlink,
.cs-itable td a:not([class]),
.cs-fact-val a:not([class]),
.cs-preview-val a:not([class]) { font-size: 1rem; }
a.cs-itable-code,
a.cs-inv-card__code,
a.cs-recordlink {
    position: relative;
    display: inline-block;
    --csl-hit: 44px;
}
a.cs-itable-code::before,
a.cs-inv-card__code::before,
a.cs-recordlink::before {
    content: "";
    position: absolute;
    left: -0.25rem;
    right: -0.25rem;
    top: min(0px, calc((100% - var(--csl-hit)) / 2));
    bottom: min(0px, calc((100% - var(--csl-hit)) / 2));
    z-index: 1;
}
@media (pointer: coarse) {
    a.cs-itable-code,
    a.cs-inv-card__code,
    a.cs-recordlink { --csl-hit: 48px; }
}
@media (hover: hover) {
    a.cs-itable-code:hover,
    a.cs-org-title:hover,
    a.cs-essentials-next-name:hover,
    a.cs-inv-card__code:hover,
    a.cs-recordlink:hover,
    .cs-fact-val a:not([class]):hover,
    .cs-preview-val a:not([class]):hover,
    .cs-itable td a:not([class]):hover .cs-channelname-text,
    a.cs-rowlink:not([href^="mailto:"]):not([href^="tel:"]):not([href^="sms:"]):hover,
    .cs-itable tbody tr:hover a.cs-itable-code {
        color: var(--csl-ink-pressed);
        text-decoration-line: underline;
        text-decoration-thickness: var(--csl-ul-hover);
        text-underline-offset: var(--csl-ul-offset);
    }
    .cs-itable tbody tr:hover td a:not([class]) { color: var(--csl-ink-pressed); }
    .cs-itable tbody tr:hover td a:not([class]) .cs-channelname-text {
        text-decoration-line: underline;
        text-decoration-thickness: var(--csl-ul-hover);
        text-underline-offset: var(--csl-ul-offset);
    }
}
a.cs-itable-code:active,
a.cs-org-title:active,
a.cs-essentials-next-name:active,
a.cs-inv-card__code:active,
a.cs-recordlink:active,
.cs-fact-val a:not([class]):active,
.cs-itable td a:not([class]):active,
a.cs-rowlink:not([href^="mailto:"]):not([href^="tel:"]):not([href^="sms:"]):active {
    color: var(--csl-ink-pressed);
    background-color: var(--csl-press-wash);
    transition: none;
}
a.cs-itable-code:focus-visible,
a.cs-org-title:focus-visible,
a.cs-essentials-next-name:focus-visible,
a.cs-inv-card__code:focus-visible,
a.cs-recordlink:focus-visible,
.cs-fact-val a:not([class]):not([href^="mailto:"]):not([href^="tel:"]):focus-visible,
.cs-preview-val a:not([class]):not([href^="mailto:"]):not([href^="tel:"]):focus-visible,
a.cs-rowlink:not([href^="mailto:"]):not([href^="tel:"]):not([href^="sms:"]):not(:has(> svg)):focus-visible {
    outline: 0;
    color: #FFFFFF;
    background-color: var(--csl-tint);
    text-decoration: none;
    border-radius: 3px;
    padding-inline: 2px;
    margin-inline: -2px;
    transition: none;
}
.cs-itable td a:not([class]):focus-visible {
    outline: var(--csl-ring);
    outline-offset: 2px;
    border-radius: var(--cs-r-mark);
}
@media (hover: hover) and (min-width: 768px) {
    .cs-itable tbody tr:has(a.cs-itable-code, td a:not([class])):hover td { background: var(--csl-paper); }
}

/* ---------------------------------------------------------------------
   4f. THE CONTACT LINK: an email address or phone number.
   REPLACES site.css .cs-rowlink (5010-5015).
   --------------------------------------------------------------------- */
a.cs-rowlink[href^="mailto:"],
a.cs-rowlink[href^="tel:"],
a.cs-rowlink[href^="sms:"],
.cs-fact-val a[href^="mailto:"]:not([class]),
.cs-fact-val a[href^="tel:"]:not([class]),
.cs-preview-val a[href^="mailto:"]:not([class]),
.cs-preview-val a[href^="tel:"]:not([class]) {
    --csl-hit: 44px;
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    max-width: 100%;
    min-height: 0;
    padding: 0;
    color: var(--csl-tint);
    font-size: 1rem;
    font-weight: 500;
    text-decoration: none;
    overflow-wrap: anywhere;
    border-radius: var(--cs-r-mark);
    -webkit-tap-highlight-color: transparent;
    transition: color 0.15s var(--csl-ease);
}
a.cs-rowlink[href^="mailto:"]::before,
a.cs-rowlink[href^="tel:"]::before,
a.cs-rowlink[href^="sms:"]::before,
.cs-fact-val a[href^="mailto:"]:not([class])::before,
.cs-fact-val a[href^="tel:"]:not([class])::before,
.cs-preview-val a[href^="mailto:"]:not([class])::before,
.cs-preview-val a[href^="tel:"]:not([class])::before {
    content: "";
    flex: none;
    width: 1.0625em;
    height: 1.0625em;
    background-color: currentColor;
    -webkit-mask: var(--csl-mail) center / contain no-repeat;
            mask: var(--csl-mail) center / contain no-repeat;
}
a.cs-rowlink[href^="tel:"]::before,
a.cs-rowlink[href^="sms:"]::before,
.cs-fact-val a[href^="tel:"]:not([class])::before,
.cs-preview-val a[href^="tel:"]:not([class])::before {
    -webkit-mask-image: var(--csl-phone);
            mask-image: var(--csl-phone);
}
@media (hover: hover) {
    a.cs-rowlink[href^="mailto:"]:hover,
    a.cs-rowlink[href^="tel:"]:hover,
    a.cs-rowlink[href^="sms:"]:hover,
    .cs-fact-val a[href^="mailto:"]:not([class]):hover,
    .cs-fact-val a[href^="tel:"]:not([class]):hover {
        color: var(--csl-ink-pressed);
        text-decoration-line: underline;
        text-decoration-thickness: var(--csl-ul-hover);
        text-underline-offset: var(--csl-ul-offset);
    }
}
a.cs-rowlink[href^="mailto:"]:active,
a.cs-rowlink[href^="tel:"]:active,
a.cs-rowlink[href^="sms:"]:active { color: var(--csl-ink-pressed); background-color: var(--csl-press-wash); transition: none; }
a.cs-rowlink[href^="mailto:"]::after,
a.cs-rowlink[href^="tel:"]::after,
a.cs-rowlink[href^="sms:"]::after,
.cs-fact-val a[href^="mailto:"]:not([class])::after,
.cs-fact-val a[href^="tel:"]:not([class])::after,
.cs-preview-val a[href^="mailto:"]:not([class])::after,
.cs-preview-val a[href^="tel:"]:not([class])::after {
    content: "";
    position: absolute;
    left: -0.25rem;
    right: -0.25rem;
    top: min(0px, calc((100% - var(--csl-hit)) / 2));
    bottom: min(0px, calc((100% - var(--csl-hit)) / 2));
}
@media (pointer: coarse) {
    a.cs-rowlink[href^="mailto:"],
    a.cs-rowlink[href^="tel:"],
    a.cs-rowlink[href^="sms:"],
    .cs-fact-val a[href^="mailto:"]:not([class]),
    .cs-fact-val a[href^="tel:"]:not([class]),
    .cs-preview-val a[href^="mailto:"]:not([class]),
    .cs-preview-val a[href^="tel:"]:not([class]) { --csl-hit: 48px; }
}
a.cs-rowlink[href^="mailto:"]:focus-visible,
a.cs-rowlink[href^="tel:"]:focus-visible,
a.cs-rowlink[href^="sms:"]:focus-visible,
.cs-fact-val a[href^="mailto:"]:not([class]):focus-visible,
.cs-fact-val a[href^="tel:"]:not([class]):focus-visible {
    outline: var(--csl-ring);
    outline-offset: 2px;
    border-radius: var(--cs-r-mark);
}
.cs-rowlink.justify-end { justify-content: flex-end; }
@media (max-width: 767px) {
    .cs-rowlink { min-height: 0; }
}
.cs-fact { font-size: 1rem; }

/* ---------------------------------------------------------------------
   4g. THE WAY BACK (cs-backlink): "<- Bookings", above the title, worded
   as the parent. Found today by the brand back arrow (#cs-cmd-back)
   whatever class the anchor wears.
   REPLACES site.css .cs-setup-back (7021-7037) and the back-link use of
   .cs-btn-link.
   --------------------------------------------------------------------- */
a.cs-backlink,
a.cs-btn:has(> svg:first-child > use[href="#cs-cmd-back"]),
.cs-page-header a.cs-rowlink:first-child:has(> svg:first-child),
.cs-setup-back,
a.inline-flex.text-slate-500:has(> svg path[d="M15 19l-7-7 7-7"]) {
    --csl-hit: 44px;
    --csl-pad-x: 14px;
    display: inline-flex;
    align-items: center;
    gap: 0.375em;
    min-height: 0;
    padding: calc((var(--csl-hit) - 1.25em) / 2) var(--csl-pad-x);
    line-height: 1.25;
    border: 0;
    background: transparent;
    color: var(--csl-tint);
    font-size: 1rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    border-radius: var(--cs-r-chip);
    transform: none;
    margin-left: calc(var(--csl-pad-x) * -1 - 2.65px);
    margin-right: calc(var(--csl-pad-x) * -1);
}
@media (pointer: coarse) {
    a.cs-backlink,
    a.cs-btn:has(> svg:first-child > use[href="#cs-cmd-back"]),
    .cs-page-header a.cs-rowlink:first-child:has(> svg:first-child),
    .cs-setup-back,
    a.inline-flex.text-slate-500:has(> svg path[d="M15 19l-7-7 7-7"]) { --csl-hit: 48px; }
}
a.cs-btn:has(> svg:first-child > use[href="#cs-cmd-back"]) > svg {
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
    color: currentColor;
    transition: transform 0.15s var(--csl-ease);
}
.cs-page-header a.cs-rowlink:first-child:has(> svg:first-child) > svg,
.cs-setup-back > svg,
a.inline-flex.text-slate-500:has(> svg path[d="M15 19l-7-7 7-7"]) > svg { display: none; }
.cs-page-header a.cs-rowlink:first-child:has(> svg:first-child)::before,
.cs-setup-back::before,
a.inline-flex.text-slate-500:has(> svg path[d="M15 19l-7-7 7-7"])::before {
    content: "";
    flex: none;
    width: 1.125rem;
    height: 1.125rem;
    background-color: currentColor;
    -webkit-mask: var(--csl-back) center / contain no-repeat;
            mask: var(--csl-back) center / contain no-repeat;
}
@media (hover: hover) {
    a.cs-backlink:hover,
    a.cs-btn:has(> svg:first-child > use[href="#cs-cmd-back"]):hover,
    .cs-page-header a.cs-rowlink:first-child:has(> svg:first-child):hover,
    .cs-setup-back:hover,
    a.inline-flex.text-slate-500:has(> svg path[d="M15 19l-7-7 7-7"]):hover {
        color: var(--csl-ink-pressed);
        background: transparent;
        text-decoration-line: underline;
        text-decoration-thickness: var(--csl-ul-hover);
        text-underline-offset: var(--csl-ul-offset);
    }
    a.cs-btn:has(> svg:first-child > use[href="#cs-cmd-back"]):hover > svg { transform: translateX(-2px); }
}
a.cs-backlink:active,
a.cs-btn:has(> svg:first-child > use[href="#cs-cmd-back"]):active,
.cs-page-header a.cs-rowlink:first-child:has(> svg:first-child):active,
.cs-setup-back:active,
a.inline-flex.text-slate-500:has(> svg path[d="M15 19l-7-7 7-7"]):active {
    color: var(--csl-ink-pressed);
    background: transparent;
    text-decoration-line: underline;
    text-decoration-thickness: var(--csl-ul-hover);
    text-underline-offset: var(--csl-ul-offset);
    transition-duration: 0s;
}
a.cs-backlink:focus-visible,
a.cs-btn:has(> svg:first-child > use[href="#cs-cmd-back"]):focus-visible,
.cs-page-header a.cs-rowlink:first-child:has(> svg:first-child):focus-visible,
.cs-setup-back:focus-visible,
a.inline-flex.text-slate-500:has(> svg path[d="M15 19l-7-7 7-7"]):focus-visible {
    outline: var(--csl-ring);
    outline-offset: calc((var(--csl-hit) - 1.25em) / -2 + 3px);
    border-radius: calc((var(--csl-hit) - 1.25em) / 2 + 1px);
}

/* =====================================================================
   5. COMMANDS (cs-btn-command): a picture and a verb. 16px words, 44px
   with a mouse and 48px under a finger, the 8px corner of every other
   button, the outside 2px Primary Blue ring, and a single-colour glyph.
   REPLACES site.css .cs-btn-command and -danger sizes (1067-1123, 1208-
   1216), .cs-recordbar .cs-btn (2896), .cs-itable-edit (4785-4796).
   Anchors that only take you to another screen ("Common jobs", "Manage",
   "Full profile", "Your invoices") are cs-btn-link in the migration list.
   ===================================================================== */
.cs-btn-command.cs-btn-command,
.cs-btn-command-danger.cs-btn-command-danger,
.cs-recordbar .cs-btn.cs-btn,
.cs-itable-edit.cs-itable-edit {
    min-height: var(--cs-h);
    padding: 0.4rem 0.75rem;
    border-radius: var(--cs-r-chip);
    font-size: 1rem;
    font-weight: 600;
    gap: 0.5rem;
}
.cs-btn-command.cs-btn-command:focus-visible,
.cs-btn-command-danger.cs-btn-command-danger:focus-visible,
.cs-itable-edit.cs-itable-edit:focus-visible { outline: var(--cs-ring); outline-offset: 2px; }
/* Inside a scroller (the record bar under 1024px) the ring is drawn
   inside, so the scroller's overflow cannot shave it. */
@media (max-width: 1023.98px) {
    .cs-recordbar-scroll .cs-btn:focus-visible { outline-offset: -3px; }
}
/* The other buttons that sat at 40 / 15px. */
.cs-btn-sm.cs-btn-sm { min-height: var(--cs-h); font-size: 1rem; border-radius: var(--cs-r-chip); }
.cs-btn-icon.cs-btn-icon { min-height: var(--cs-h); min-width: var(--cs-h); border-radius: var(--cs-r-chip); }


/* ---------------------------------------------------------------------
   3b. THE RECORD BAR'S LAYOUT
   REPLACES site.css .cs-recordbar-scroll / .cs-recordbar-group phone
   behaviour (2861-2915) and the desktop wrap rule (2937-2950).
   Desk: the groups pour their commands into the bar's own line, so the
   bar wraps or it fits, never both and clipped; each group's hairline is
   its own 1px item. Phone: the bar scrolls with the shared cue, except
   where a tab row opens the screen straight under it, where it wraps so
   two sideways scrollers never stack.
   --------------------------------------------------------------------- */
@media (max-width: 639px) {
    .cs-recordbar:has(
        + .cs-record > .cs-record-main > :first-child .cs-tabs,
        + .cs-record > .cs-record-main > .cs-segment[role="tablist"]:first-child > a[role="tab"],
        + .cs-record > .cs-record-main > :first-child > .cs-segment[role="tablist"]:first-child > a[role="tab"]
    ) .cs-recordbar-scroll.cs-recordbar-scroll {
        flex-wrap: wrap;
        column-gap: 0.75rem;
        row-gap: 0.25rem;
        overflow-x: visible;
        -webkit-mask-image: none;
        mask-image: none;
    }
    .cs-recordbar:has(
        + .cs-record > .cs-record-main > :first-child .cs-tabs,
        + .cs-record > .cs-record-main > .cs-segment[role="tablist"]:first-child > a[role="tab"],
        + .cs-record > .cs-record-main > :first-child > .cs-segment[role="tablist"]:first-child > a[role="tab"]
    ) .cs-recordbar-scroll > .cs-recordbar-group.cs-recordbar-group {
        flex: 0 1 auto;
        min-width: 0;
        flex-wrap: wrap;
        row-gap: 0.25rem;
        margin-left: 0;
        padding-left: 0;
        border-left: 0;
    }
}
@media (min-width: 1024px) {
    .cs-recordbar-scroll > .cs-recordbar-group.cs-recordbar-group { display: contents; }
    .cs-recordbar-scroll > .cs-recordbar-group.cs-recordbar-group:not(:first-child)::before {
        content: "";
        flex: none;
        align-self: center;
        width: 1px;
        height: 1.5rem;
        margin: 0 0.375rem;
        background: var(--cs-hair);
    }
}

/* ---------------------------------------------------------------------
   3c. NAVIGATION LISTS: the settings rail, the phone drawer, the sidebar
   and the mega panel. Where you are: Deep Blue words at 600, a pale
   Primary Blue ground and the 3px Primary Blue bar inside the row's edge.
   REPLACES site.css .cs-railnav-* (2783-2828), .cs-nav-link (3446-3459),
   .cs-mega-* (3883-3917).
   --------------------------------------------------------------------- */
.cs-railnav-link.cs-railnav-link,
.cs-nav-link.cs-nav-link,
.cs-mega-item.cs-mega-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 44px;
    padding: 0.5rem 0.75rem;
    border-radius: var(--cs-r-chip);
    background: transparent;
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.3;
    color: #3A3F4A;
    text-decoration: none;
    transition: background-color .15s var(--tb-ease), color .15s var(--tb-ease);
}
@media (pointer: coarse) {
    .cs-railnav-link.cs-railnav-link,
    .cs-nav-link.cs-nav-link { min-height: 48px; }
}
.cs-mega-item.cs-mega-item { align-items: flex-start; padding: 0.625rem 0.75rem; }
.cs-railnav-link.cs-railnav-link svg,
.cs-nav-link.cs-nav-link svg,
.cs-mega-item.cs-mega-item .cs-mega-ico { color: var(--tb-label); }
.cs-railnav-link.cs-railnav-link:hover,
.cs-nav-link.cs-nav-link:hover,
.cs-mega-item.cs-mega-item:hover {
    background: #F3F4F7;
    color: var(--tb-ink);
}
.cs-railnav-link.cs-railnav-link[aria-current="page"],
.cs-nav-link.cs-nav-link.cs-nav-link-active,
.cs-mega-item.cs-mega-item.is-active {
    background: var(--tb-tint);
    color: var(--cs-selected-ink);
    font-weight: 600;
}
.cs-railnav-link.cs-railnav-link[aria-current="page"] svg,
.cs-nav-link.cs-nav-link.cs-nav-link-active svg,
.cs-mega-item.cs-mega-item.is-active .cs-mega-ico { color: var(--cs-blue); }
.cs-mega-item.cs-mega-item.is-active .cs-mega-title { color: var(--cs-selected-ink); }
.cs-railnav-link.cs-railnav-link[aria-current="page"]::before,
.cs-nav-link.cs-nav-link.cs-nav-link-active::before,
.cs-mega-item.cs-mega-item.is-active::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.5rem;
    bottom: 0.5rem;
    width: 3px;
    border-radius: 0;
    background: var(--cs-selected-bar);
}
.cs-railnav-link.cs-railnav-link:focus-visible,
.cs-nav-link.cs-nav-link:focus-visible,
.cs-mega-item.cs-mega-item:focus-visible {
    outline: var(--cs-ring);
    outline-offset: -3px;
}

/* =====================================================================
   6. THE "MORE THIS WAY" CUE (cs-scroller-cue): one cue for every
   sideways scroller. A solid patch of the ground the scroller sits on,
   with a Primary Blue chevron and a hairline on its inner edge, shown by
   cs-scroller.js's cs-scroller-start / cs-scroller-end classes. Tab rows
   draw it in 3a; the record bar and any opted-in scroller draw it here.
   ===================================================================== */
@media (max-width: 1023.98px) {
    .cs-recordbar:has(> .cs-recordbar-scroll.cs-scroller-end)::after,
    .cs-scroller-cue.cs-scroller-end::after {
        content: "";
        flex: none;
        align-self: stretch;
        width: var(--cs-cue-w);
        margin-left: -0.25rem;
        background: var(--tb-ground, #FFFFFF) var(--cs-cue-r) center / 1.25rem 1.25rem no-repeat;
        box-shadow: inset 1px 0 0 var(--cs-hair);
        pointer-events: none;
    }
}


/* Counts: one class, cs-count (cs-segment-count, cs-pill-count and
   cs-gridbtn-count alias it during the migration). A number after its
   word at the word's size, regular weight, #434956. No brackets, no
   bubble: "Filters 1". */
.cs-count,
.cs-segment-count,
.cs-pill-count,
.cs-gridbtn-count {
    display: inline;
    min-width: 0;
    height: auto;
    padding: 0;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    font: inherit;
    font-size: 1em;
    font-weight: 400;
    line-height: inherit;
    letter-spacing: 0;
    font-variant-numeric: tabular-nums;
    color: var(--cs-count);
}
.cs-gridbtn-count::before,
.cs-gridbtn-count::after { content: none; }


/* ════════════════════════════════════════════════════════════════
   Customer portal (Campsuite.WebPublicPortal) - portal-only classes
   ----------------------------------------------------------------
   Everything above this line comes from Campsuite.Web/wwwroot/css/site.css,
   copied verbatim so the portal is the same product to look at: the base of
   it is the September 2026 copy, and the blocks DESIGN.md section 13 lists
   were taken again from the operator sheet in November 2026 (the Deep Blue
   primary and the button taxonomy, the white notice, cards, the page ladder,
   the record and its command bar, the list furniture, the job list, the
   signed-out frame and the controls sheet's links and commands). That
   duplication is deliberate and is the arrangement DESIGN.md section 12
   records for the admin console: a fix to one stylesheet must be applied to
   the others until they are built from one shared source. Only classes the
   portal alone needs belong below this line, and each one is documented in
   DESIGN.md section 13.
   ════════════════════════════════════════════════════════════════ */

/* The portal wears a deep-blue top bar, so its content uses the width the
   same way the operator app does under body.cs-chrome-top. Same rule, own
   flag, because the portal has no Ui:Navigation setting to switch. */
body.cs-portal main {
    margin-left: auto;
    margin-right: auto;
    width: 100%;
    max-width: 96rem;
}

/* A quiet sign-off under the content: where to read the privacy notice and
   who to email. Desktop only - a phone ends in the bottom bar, and a second
   row of links above it is just something to mis-tap. */
.cs-portal-footer { display: none; }

@media (min-width: 1024px) {
    .cs-portal-footer {
        display: block;
        margin-top: 2rem;
        padding: 1.5rem 1rem 2rem;
        border-top: 1px solid #e4e6ed;
        background: #ffffff;
    }
}

.cs-portal-footer-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.5rem;
    width: 100%;
    max-width: 96rem;
    margin: 0 auto;
    padding: 0 0.5rem;
    color: #6c7280;
    font-size: 1rem;
}

.cs-portal-footer-link {
    color: #22568c;
    font-weight: 600;
    text-decoration: none;
    border-radius: 6px;
}

.cs-portal-footer-link:hover { text-decoration: underline; }
.cs-portal-footer-link:focus-visible { outline: 3px solid #22568c; outline-offset: 3px; }

/* ── The guest's own pages ──────────────────────────────────────
   The few layout pieces Home, the booking and Parks share, kept as classes
   so the three pages do not each type the same utility string slightly
   differently. Everything they hold is a cs-* component from above: cards,
   facts, badges, the job list, the record and its command bar. */

/* Home: the next stay beside what needs doing, on a desk; one column, next
   stay first, on a phone. A lone block takes the whole width. */
.cs-portal-lead { display: grid; gap: 1.5rem; align-items: start; }
@media (min-width: 1024px) {
    .cs-portal-lead:has(> section + section) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* The heading that names the one card under it ("Your next stay", "To do"). */
.cs-portal-blockhead { margin: 0 0 0.75rem; }

/* Booking cards in a list: one column on a phone, two from 640px, three from 1280px. */
.cs-portal-cards { display: grid; gap: 1rem; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 640px) { .cs-portal-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .cs-portal-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* The dates and nights under a card's park name. */
.cs-portal-cardline { margin-top: 0.625rem; font-size: 1rem; color: #262a32; }

/* How long there is to go: the calendar glyph and the words, in the deeper
   step of the link blue. Words, so the colour is never the only signal. */
.cs-portal-countdown {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
    font-size: 1rem;
    font-weight: 600;
    color: #1b4472;
}
.cs-portal-countdown svg { flex: none; width: 1.25rem; height: 1.25rem; }
.cs-portal-countdown-lg { display: flex; margin-top: 0.875rem; font-size: 1.125rem; }
.cs-portal-countdown-lg svg { width: 1.5rem; height: 1.5rem; }

/* The booking's state in one wrapping line: status, the balance badge, when
   it is due, how long to go. */
.cs-portal-moneyline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    margin-top: 1rem;
}
.cs-portal-moneyline .cs-portal-countdown { margin-top: 0; }
.cs-portal-due { font-size: 1rem; color: #4e5461; }

/* A small heading inside a card: Extras, When you arrive, When you leave. */
.cs-portal-subhead { margin: 1.25rem 0 0.25rem; font-size: 1rem; font-weight: 600; color: #0f213f; }
.space-y-4 > div > .cs-portal-subhead:first-child { margin-top: 0; }

/* The park's own words (arrival instructions, a notice, a bank note), with
   the line breaks the park typed kept. */
.cs-portal-prose {
    white-space: pre-line;
    overflow-wrap: anywhere;
    font-size: 1rem;
    line-height: 1.55;
    color: #262a32;
}

/* A booking's payments: a cs-itable sitting straight in its card, so the card
   is the frame. The first and last columns line up with the card's own
   padding, and on a phone the folded rows lose the frame cs-itable gives them
   when it stands alone. */
.cs-card > .cs-portal-ledger thead th:first-child,
.cs-card > .cs-portal-ledger tbody td:first-child { padding-left: 1.25rem; }
.cs-card > .cs-portal-ledger thead th:last-child,
.cs-card > .cs-portal-ledger tbody td:last-child { padding-right: 1.25rem; }
@media (max-width: 767px) {
    .cs-card > .cs-portal-ledger tbody {
        border: 0;
        border-top: 1px solid #edf0f4;
        border-radius: 0;
    }
    .cs-card > .cs-portal-ledger tbody tr { padding-left: 1.25rem; padding-right: 1.25rem; }
    .cs-card > .cs-portal-ledger tbody td:first-child,
    .cs-card > .cs-portal-ledger tbody td:last-child { padding-left: 0; padding-right: 0; }
}

/* An amount still owed, in the state map's rose, always beside words that say so. */
.cs-portal-owed { color: #b42318; }

/* A command in the record bar holds its own sr-only words ("Call Meadow Bank", "(opens in a
   new tab)"). An sr-only span is absolutely positioned, and with no positioned ancestor its
   box is laid out against the page rather than the bar, so on a phone the words of the
   commands scrolled out of sight pushed the whole page 200px sideways. Each command is the
   box its own words sit in, so the bar's scroller clips them with the command. */
.cs-recordbar-scroll .cs-btn { position: relative; }

/* How to reach a park: its phone and email as cs-rowlink, one under the other,
   or side by side in a Parks row. */
.cs-portal-contact {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}
.cs-portal-contact-row { flex-direction: row; flex-wrap: wrap; gap: 0.25rem 1.5rem; }
.cs-portal-address {
    display: flex;
    flex-direction: column;
    font-style: normal;
    font-size: 1rem;
    line-height: 1.5;
    color: #262a32;
}

/* Under a park's name on Parks: the next stay, then how to reach the park. It sits in the
   row's words, so the tools stay level with the name on a desk and wrap under the whole
   row on a phone. */
.cs-rowlist-head:has(.cs-portal-rowdetail) { align-items: flex-start; }
.cs-portal-rowdetail {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
    font-size: 1rem;
    color: #262a32;
}

/* Who is signed in, at the head of the account menu and the foot of the
   drawer: the first name they gave, then the address they sign in with. */
.cs-portal-who-name,
.cs-portal-who-email {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 1rem;
}
.cs-portal-who-name { font-weight: 600; color: #0f213f; }
.cs-portal-who-email { color: #5b6274; }

/* Signed out (the privacy notice, a 404), the top bar's one action is Sign in,
   and it shows at every width rather than only where the operator CTA would. */
.cs-topnav-cta.cs-portal-signin { display: inline-flex; }

/* The signed-out frame's panel, drawn in plain Deep Blue rather than on the
   operator's campsite photograph. With no photograph there is nothing for the
   scrim to darken, so it goes, and the panel's three lines take their own
   spacing and the 16px floor (the operator's lines sit on the photograph's
   eyebrow, which the portal does not draw). */
.cs-auth-canopy::after { content: none; }
.cs-auth-canopy .cs-auth-photo-sub { margin-top: 1rem; }
.cs-auth-canopy .cs-auth-photo-note { margin-top: 1.25rem; font-size: 1rem; }

/* ── The "coming soon" page (Pages/ComingSoon) ──────────────────
   The house cs-soon shape, standing alone with no chrome while the portal is
   switched off. Only what the shape needs to stand without a top bar: its own
   paper, the lockup on the canopy, the illustrative card, and a paragraph at
   reading size. */
body.cs-soonpage { min-height: 100vh; margin: 0; background: #f2f5f9; color: #262a32; }
.cs-soonpage-logo { display: block; height: 2.25rem; width: auto; margin-bottom: 1.75rem; }
.cs-soonpage-card { max-width: 26rem; margin-inline: auto; padding: 1.25rem; color: #262a32; }
.cs-soonpage-cardtitle { margin: 0 0 0.5rem; font-size: 1.125rem; font-weight: 600; color: #0f213f; }
.cs-soonpage-text { margin: 0.75rem 0 0; max-width: 46rem; font-size: 1rem; line-height: 1.55; color: #414652; }

/* ── Validation messages ─────────────────────────────────────────
   ASP.NET stamps `field-validation-error` on a <span asp-validation-for>
   the moment the field is refused (and jQuery unobtrusive does the same in
   the browser), so the look belongs here rather than re-typed as a utility
   string on every field. Six portal pages were carrying two different
   strings for the same message; this is the one.

   Sized like body copy, not at 15px: someone who has just been turned away
   by a form is the last reader who should be given smaller words. The base
   rule above sets 0.9375rem for the operator app, so this overrides it for
   the portal only. */
.field-validation-error {
    display: block;
    margin-top: 0.375rem;
    font-size: 1rem;
    font-weight: 600;
    color: #b42318;
}

/* An untriggered message span still renders, so hide it rather than let it
   push the next field down by its own margin. */
.field-validation-valid { display: none; }

/* A model-level summary is always shown inside a cs-toast (see the sign-in,
   sign-up, reset and profile pages), so it takes the toast's tone and only
   needs its list furniture stripped and its weight dropped back to the
   reading weight under the toast's bold lead line. */
.cs-toast .validation-summary-errors { font-weight: 400; }
.cs-toast .validation-summary-errors ul { list-style: none; margin: 0; padding: 0; }
.cs-toast .validation-summary-errors li + li { margin-top: 0.25rem; }
