/* ==========================================================================
   The Hydro — storefront
   --------------------------------------------------------------------------
   Everything is scoped under .inn-sf so the plugin never leaks styles into the
   theme, and every colour/shape decision reads from the custom properties
   emitted by inn_brand_css_vars() (see includes/inn-brand.php). To re-skin,
   change the tokens — not this file.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Foundation
   -------------------------------------------------------------------------- */

.inn-sf {
    /* THE SENTINEL. Nothing reads this as a value — it is read for its
       presence, by the staff-only check in storefront.js, to answer one
       question the page cannot otherwise ask: did this stylesheet arrive?

       It has to be declared in THIS FILE and nowhere else. The brand tokens
       land on the same selector through wp_add_inline_style(), and an inline
       <style> block still prints when the <link> beside it 404s — so a token
       would report success on a page that has no stylesheet at all, which is
       the one answer that must never be wrong. */
    --inn-sf-css: 1;

    box-sizing: border-box;
    max-width: var(--inn-maxw);
    margin-inline: auto;
    padding-inline: clamp(16px, 4vw, 32px);
    color: var(--inn-ink);
    font-family: var(--inn-font-body);
    line-height: 1.6;
}

.inn-sf *,
.inn-sf *::before,
.inn-sf *::after { box-sizing: inherit; }

.inn-sf img { max-width: 100%; height: auto; display: block; }

/* THE hidden ATTRIBUTE HAS TO WIN, and by default it does not.
   ---------------------------------------------------------------------------
   The browser's own rule is `[hidden] { display: none }` at the lowest possible
   weight, so any author rule that sets `display` on the same element beats it —
   and a component that lays itself out with `display: flex` is doing exactly
   that. The element then carries `hidden`, reads as hidden to a screen reader,
   is skipped by the tab order, and is drawn on the page anyway.

   Four elements were in that state: the voucher's "added to your basket" strip,
   which showed as an empty green bar before anything was added; the recipient's
   email field, which showed while "Email the voucher to them" was unticked; the
   search box's clear button, with nothing to clear; and the registration card's
   copy-link field. Each had the same one-line cause and would have needed the
   same one-line fix four times over.

   One rule instead, scoped to what this plugin renders — including the detail
   dialog, which is moved to <body> and so is not inside .inn-sf. !important
   because `hidden` is a statement that the element is not there, and nothing
   about layout should be able to argue with it. */
.inn-sf [hidden],
.inn-dlg [hidden],
.inn-dlg[hidden] { display: none !important; }

/* THE STATE SPECIFICITY RULE, and why every state below names its class twice.
   ---------------------------------------------------------------------------
   Elementor's kit stylesheet styles the bare elements of the page. It emits
   rules shaped like `.elementor-kit-7 a:hover` and `.elementor-kit-7
   button:hover`, in the site's accent colour — one class, one pseudo-class and
   one type, which is specificity (0,2,1).

   A state written here the obvious way, `.inn-sf-btn:hover`, is one class and
   one pseudo-class: (0,2,0). It loses. So every hover and every press on every
   link and button this plugin renders was painted the theme's accent pink on a
   navy storefront — and the resting colours all looked right, because the kit
   only styles the STATES. That is what makes this one hard to see: the page is
   correct until somebody touches it.

   Naming the class twice — `.inn-sf-btn.inn-sf-btn:hover` — matches exactly the
   same elements at (0,3,0), which no kit rule of that shape can reach. It is
   used instead of !important because the site still has to be able to win (see
   the hooks below), and instead of scoping under `.inn-sf` because two of these
   components are moved to <body> at runtime — the detail dialog and the toast
   host — and are then outside it. That is not hypothetical: the dialog's close
   button and the quantity stepper each carry an older, local version of this
   comment, written the two times this was found one component at a time.

   THE BUDGET IS ONE CLASS ABOVE THE KIT. If something ever outranks (0,3,0) — a
   WooCommerce theme's `.woocommerce a.button:hover` is (0,3,1) and would — the
   answer is the hooks below, not a third class. Read the browser's matched-rules
   list first: the rule that wins is evidence, and a third class is a guess.

   HOW THE SITE RE-SKINS A STATE WITHOUT TOUCHING THIS FILE. Every colour the
   button states set resolves through an `--inn-btn-*` custom property that this
   stylesheet never declares — only reads, with the plugin's own value as the
   var() fallback. Nothing here competes for those names, so a declaration
   anywhere else wins at any specificity, with no !important:

       .ButtonFancyGold { --inn-btn-hover-bg: #B8945A; --inn-btn-hover-bd: #B8945A; }

   Every dark blue button this plugin renders carries `.ButtonFancyGold` for
   exactly that purpose, and this file deliberately says nothing else about it.
   The full list of hooks is in documentation/interactive-states.md. */

.inn-sf.inn-sf :focus-visible {
    outline: 2px solid var(--inn-brand);
    outline-offset: 3px;
    border-radius: var(--inn-radius-sm);
}

/* Links inside copy that we render but do not write — a unit description, the
   indemnity wording, the staff funnel on an empty grid, the no-JavaScript route
   to the closed tab. They are the one clickable thing on these pages with no
   class of their own, so the container is what gets named twice. */
.inn-unit-prose.inn-unit-prose a,
.inn-sf-notice.inn-sf-notice a,
.inn-sf-empty.inn-sf-empty a,
.inn-sf-defer.inn-sf-defer a,
.inn-reg-waiver.inn-reg-waiver a {
    color: var(--inn-brand);
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: color .16s ease;
}
.inn-unit-prose.inn-unit-prose a:hover,
.inn-unit-prose.inn-unit-prose a:focus-visible,
.inn-sf-notice.inn-sf-notice a:hover,
.inn-sf-notice.inn-sf-notice a:focus-visible,
.inn-sf-empty.inn-sf-empty a:hover,
.inn-sf-empty.inn-sf-empty a:focus-visible,
.inn-sf-defer.inn-sf-defer a:hover,
.inn-sf-defer.inn-sf-defer a:focus-visible,
.inn-reg-waiver.inn-reg-waiver a:hover,
.inn-reg-waiver.inn-reg-waiver a:focus-visible { color: var(--inn-brand-dark); }
.inn-unit-prose.inn-unit-prose a:active,
.inn-sf-notice.inn-sf-notice a:active,
.inn-sf-empty.inn-sf-empty a:active,
.inn-sf-defer.inn-sf-defer a:active,
.inn-reg-waiver.inn-reg-waiver a:active { color: var(--inn-accent-dark); }

/* Typography ------------------------------------------------------------- */

.inn-sf h1, .inn-sf h2, .inn-sf h3, .inn-sf h4 {
    font-family: var(--inn-font-display);
    font-weight: var(--inn-display-weight);
    letter-spacing: var(--inn-display-space);
    color: var(--inn-ink);
    margin: 0 0 .4em;
    line-height: 1.18;
}

.inn-sf-pagehead {
    text-align: center;
    max-width: 720px;
    margin: clamp(24px, 5vw, 56px) auto clamp(20px, 4vw, 36px);
}

.inn-sf-pagetitle { font-size: clamp(2rem, 1.4rem + 2.4vw, 3.1rem); margin-bottom: .3em; }

.inn-sf-pagesub {
    font-size: clamp(1rem, .96rem + .25vw, 1.15rem);
    color: var(--inn-ink-soft);
    margin: 0;
}

.inn-sf-pagesub + .inn-sf-pagesub {
    margin-top: .85em;
}

.inn-sf-eyebrow {
    display: inline-block;
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: var(--inn-eyebrow-space);
    color: var(--inn-accent);
    margin-bottom: .6em;
}

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

.inn-sf-btn {
    --_bg: var(--inn-brand);
    --_fg: #fff;
    --_bd: var(--inn-brand);
    /* The state colours, per variant. They are declared here and read once, by
       the two state rules below, so that a variant only has to say how it
       differs — and so there is exactly one place the site's own hooks are
       consulted. A variant that says nothing inherits the navy button's. */
    --_bg-hover:  var(--inn-brand-dark);
    --_fg-hover:  #fff;
    --_bd-hover:  var(--inn-brand-dark);
    --_bg-active: var(--inn-brand-dark);
    --_fg-active: #fff;
    --_bd-active: var(--inn-brand-dark);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 14px 26px;
    min-height: 46px;
    border: 1px solid var(--_bd);
    border-radius: var(--inn-radius-btn);
    background: var(--_bg);
    color: var(--_fg);
    font-family: var(--inn-font-display);
    font-weight: var(--inn-btn-weight);
    font-size: .85rem;
    letter-spacing: var(--inn-btn-space);
    text-transform: var(--inn-btn-transform);
    line-height: 1.1;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background .18s ease, color .18s ease, border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}

/* Hover and focus are deliberately the same picture: somebody on a keyboard
   gets the colour change as well as the ring, so the button they are about to
   press is as obvious as the one under a cursor. */
.inn-sf-btn.inn-sf-btn:hover,
.inn-sf-btn.inn-sf-btn:focus-visible {
    background: var(--inn-btn-hover-bg, var(--_bg-hover));
    color: var(--inn-btn-hover-fg, var(--_fg-hover));
    border-color: var(--inn-btn-hover-bd, var(--_bd-hover));
    box-shadow: var(--inn-shadow);
}

/* Pressed, and it has to be visible on a phone. There is no hover on a touch
   screen, so this is the only feedback between the tap and the page changing —
   and this storefront is used at a till and in a car park. */
.inn-sf-btn.inn-sf-btn:active {
    background: var(--inn-btn-active-bg, var(--_bg-active));
    color: var(--inn-btn-active-fg, var(--_fg-active));
    border-color: var(--inn-btn-active-bd, var(--_bd-active));
    box-shadow: none;
    transform: translateY(1px);
}

/* Each variant states only its own state colours. They land on the same
   custom properties as the base rule at the same specificity, and win by
   coming later — which is how --_bg has always worked here. */
.inn-sf-btn--ghost {
    --_bg: transparent;
    --_fg: var(--inn-brand);
    --_bd: var(--inn-line-strong);
    --_bg-hover:  var(--inn-brand-soft);
    --_fg-hover:  var(--inn-brand-dark);
    --_bd-hover:  var(--inn-brand);
    --_bg-active: var(--inn-brand-soft);
    --_fg-active: var(--inn-brand-dark);
    --_bd-active: var(--inn-brand-dark);
}

.inn-sf-btn--accent {
    --_bg: var(--inn-accent);
    --_bd: var(--inn-accent);
    --_bg-hover:  var(--inn-accent-dark);
    --_bd-hover:  var(--inn-accent-dark);
    --_bg-active: var(--inn-accent-dark);
    --_bd-active: var(--inn-accent-dark);
}

.inn-sf-btn--quiet {
    --_bg: transparent;
    --_fg: var(--inn-ink-soft);
    --_bd: transparent;
    --_bg-hover:  var(--inn-sand);
    --_fg-hover:  var(--inn-ink);
    --_bd-hover:  transparent;
    /* A press has to be a different colour from a hover, not the same one
       again — which is what it was, because --inn-sand and --inn-accent-soft
       are the same cream. This is the token that exists for the difference. */
    --_bg-active: var(--inn-sand-dark);
    --_fg-active: var(--inn-ink);
    --_bd-active: transparent;
    min-height: 38px;
    padding: 8px 14px;
    font-family: var(--inn-font-body);
    font-weight: 500;
    font-size: .88rem;
    letter-spacing: 0;
    text-transform: none;
}
/* The quiet button is the one that must not lift off the page — it sits beside
   a real one and the point of it is that it is not competing. Later in the file
   than the shared states and at the same (0,3,0), so it takes the shadow back. */
.inn-sf-btn--quiet.inn-sf-btn--quiet:hover,
.inn-sf-btn--quiet.inn-sf-btn--quiet:focus-visible,
.inn-sf-btn--quiet.inn-sf-btn--quiet:active { box-shadow: none; }

.inn-sf-btn--block { width: 100%; }
.inn-sf-btn--sm { min-height: 38px; padding: 10px 18px; font-size: .76rem; }

.inn-sf-btn.inn-sf-btn[disabled],
.inn-sf-btn.inn-sf-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; box-shadow: none; }

/* A button that cannot be pressed must not answer to being pressed. The states
   above are (0,3,0) and an attribute counts in the same column, so these are
   (0,4,0) and put the resting colours back — otherwise "Add to cart" on a
   sold-out product lit up and moved under the thumb, which reads as a purchase.
   `transform: none` matters most: the press is the part that lies. */
.inn-sf-btn.inn-sf-btn[disabled]:hover,
.inn-sf-btn.inn-sf-btn[disabled]:active,
.inn-sf-btn.inn-sf-btn[disabled]:focus-visible,
.inn-sf-btn.inn-sf-btn[aria-disabled="true"]:hover,
.inn-sf-btn.inn-sf-btn[aria-disabled="true"]:active,
.inn-sf-btn.inn-sf-btn[aria-disabled="true"]:focus-visible {
    background: var(--_bg);
    color: var(--_fg);
    border-color: var(--_bd);
    box-shadow: none;
    transform: none;
}

/* Form controls ---------------------------------------------------------- */

.inn-sf-field { display: flex; flex-direction: column; gap: 6px; }

.inn-sf-label {
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--inn-ink-faint);
}

/* A theme rule such as input[type="text"] is (0,1,1). One class is (0,1,0)
   and loses, so the text fields on the arrival form were painted #666 by the
   theme while the selects — which that rule does not name — kept --inn-line
   and looked switched off. Naming the class twice is (0,2,0), which beats
   both that rule and .elementor-kit-7 select (also 0,1,1). The element is
   deliberately not in the selector: .inn-search .inn-sf-input is (0,2,0) and
   comes later to set the search field's padding, and an element here would
   take that padding back. The border is the colour the text fields already
   wear. --inn-line stays the hairline used for cards and rules. */
.inn-sf-input.inn-sf-input,
.inn-sf-select.inn-sf-select {
    width: 100%;
    min-height: 46px;
    padding: 10px 14px;
    border: 1px solid var(--inn-control, #666666);
    border-radius: var(--inn-radius-sm);
    background-color: var(--inn-surface);
    color: var(--inn-ink);
    font: inherit;
    font-size: .95rem;
    transition: border-color .18s ease, box-shadow .18s ease;
}

.inn-sf-select.inn-sf-select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-right: 38px;
    background-color: var(--inn-surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235A6660' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px;
    color: var(--inn-ink);
    cursor: pointer;
    text-overflow: ellipsis;
}

.inn-sf-input.inn-sf-input:focus,
.inn-sf-select.inn-sf-select:focus {
    outline: none;
    border-color: var(--inn-brand);
    background-color: var(--inn-surface);
    color: var(--inn-ink);
    box-shadow: 0 0 0 3px var(--inn-brand-soft);
}

/* Hover used to move the edge to --inn-line-strong, which is lighter than
   the #666 the theme already paints. On a select that had just been brought
   up to match, that hover put the grey back. The edge goes darker, and the
   fill and the ink are restated because a kit select:hover sets both and a
   state that claims the fill without the ink hands the ink back. */
.inn-sf-input.inn-sf-input:hover:not(:focus),
.inn-sf-select.inn-sf-select:hover:not(:focus) {
    border-color: var(--inn-ink-soft);
    background-color: var(--inn-surface);
    color: var(--inn-ink);
}

.inn-sf-input::placeholder { color: var(--inn-ink-faint); }

/* --------------------------------------------------------------------------
   2. Tab bar
   -------------------------------------------------------------------------- */

.inn-sf-tabbar {
    position: relative;
    display: flex;
    gap: clamp(8px, 3vw, 32px);
    justify-content: center;
    border-bottom: 1px solid var(--inn-line);
    margin-bottom: clamp(20px, 4vw, 36px);
}

.inn-sf-tab {
    position: relative;
    appearance: none;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: 14px 8px 16px;
    font-family: var(--inn-font-display);
    font-size: clamp(1rem, .95rem + .5vw, 1.35rem);
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--inn-ink-faint);
    cursor: pointer;
    white-space: nowrap;
    transition: color .2s ease, border-color .2s ease;
}

.inn-sf-tab.inn-sf-tab:hover,
.inn-sf-tab.inn-sf-tab:focus-visible { color: var(--inn-ink); border-bottom-color: var(--inn-line-strong); }
.inn-sf-tab.inn-sf-tab:active { color: var(--inn-brand-dark); border-bottom-color: var(--inn-brand-dark); }

/* Last, and one class above the states, because the open tab stays the open tab
   while the cursor is on it. A tab that changes colour on hover to say "you are
   not here" is the opposite of what the bar is for. */
.inn-sf-tab.inn-sf-tab.is-active,
.inn-sf-tab.inn-sf-tab.is-active:hover,
.inn-sf-tab.inn-sf-tab.is-active:focus-visible {
    color: var(--inn-brand);
    border-bottom-color: var(--inn-brand);
}

.inn-sf-panel { animation: inn-sf-fade .28s ease both; }
.inn-sf-panel[hidden] { display: none; }

@keyframes inn-sf-fade {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

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

/* --------------------------------------------------------------------------
   3. Shared layout pieces
   -------------------------------------------------------------------------- */

.inn-sf-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
    gap: clamp(16px, 2.4vw, 28px);
    align-items: stretch;
}

.inn-sf-empty {
    grid-column: 1 / -1;
    padding: clamp(32px, 7vw, 64px) 24px;
    border: 1px dashed var(--inn-line-strong);
    border-radius: var(--inn-radius);
    background: var(--inn-canvas);
    color: var(--inn-ink-soft);
    text-align: center;
}

.inn-sf-empty strong { display: block; color: var(--inn-ink); font-size: 1.1rem; margin-bottom: .4em; }

/* The staff-only account of which stage emptied the grid. Set apart from
   the visitor's sentence above it so nobody mistakes one for the other,
   and monospaced because it is a row of numbers to be read, not prose. */
/* Staff only: the browser is showing fewer rooms than the server rendered.
   Deliberately loud — a card silently missing from a grid that looks complete
   is the failure nobody reports. */
.inn-sf-shortfall {
    margin: .5em 0 1em;
    padding: .7em 1em;
    border-left: 3px solid var(--inn-line-strong);
    background: var(--inn-canvas);
    color: var(--inn-ink-soft);
    font-size: .85rem;
    line-height: 1.6;
}

.inn-sf-empty-why {
    display: block;
    margin-top: 1.25em;
    padding-top: 1em;
    border-top: 1px dashed var(--inn-line-strong);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .8rem;
    line-height: 1.7;
    text-align: left;
    opacity: .85;
}

/* The stand-in for a tab that has not been built yet. Only the open tab is
   rendered server-side; this is what the other one holds until it is asked
   for. The link is the whole point of it — without JavaScript, and to a
   crawler, it is a real route to the same tab rendered in full — so it is
   styled to be read, and only hidden once a fetch is actually under way. */
.inn-sf-defer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 160px;
    padding: clamp(24px, 6vw, 48px) 24px;
    color: var(--inn-ink-soft);
    text-align: center;
}

.inn-sf-defer-loading { display: inline-flex; align-items: center; gap: 10px; }
.inn-sf-defer-loading[hidden] { display: none; }
.inn-sf-defer-link { margin: 0; }
.inn-sf-defer[data-loading="1"] .inn-sf-defer-link { display: none; }

/* A card fetching the detail it was not rendered with. One small request on a
   deliberate click, so this only has to say "heard you", not entertain. */
.inn-prod.is-busy { opacity: .7; }

.inn-sf-notice {
    padding: 14px 18px;
    border-radius: var(--inn-radius-sm);
    border: 1px solid var(--inn-line);
    background: var(--inn-canvas);
    color: var(--inn-ink-soft);
    font-size: .92rem;
    margin-bottom: 20px;
}
.inn-sf-notice--warn     { background: var(--inn-notice-soft);   border-color: #E8DCB8; color: var(--inn-notice); }
.inn-sf-notice--negative { background: var(--inn-negative-soft); border-color: #F0CFC7; color: var(--inn-negative); }
.inn-sf-notice--positive { background: var(--inn-positive-soft); border-color: #C9E3D6; color: var(--inn-positive); }

.inn-sf-count {
    font-size: .86rem;
    color: var(--inn-ink-faint);
    margin: 0 0 16px;
}

.inn-sf-visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   4. Toasts
   -------------------------------------------------------------------------- */

.inn-sf-toasts {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
    z-index: 100000;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
    pointer-events: none;
    padding-inline: 16px;
    width: min(100%, 440px);
}

.inn-sf-toast {
    background: var(--inn-ink);
    color: #fff;
    padding: 12px 20px;
    border-radius: var(--inn-radius-pill);
    box-shadow: var(--inn-shadow-lg);
    font-size: .92rem;
    font-weight: 500;
    text-align: center;
    animation: inn-sf-toast-in .26s cubic-bezier(.2, .8, .3, 1) both;
}

.inn-sf-toast.is-error    { background: var(--inn-negative); }
.inn-sf-toast.is-success  { background: var(--inn-positive); }
.inn-sf-toast.is-leaving  { animation: inn-sf-toast-out .3s ease forwards; }

@keyframes inn-sf-toast-in  { from { opacity: 0; transform: translateY(12px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes inn-sf-toast-out { to   { opacity: 0; transform: translateY(8px) scale(.98); } }

/* --------------------------------------------------------------------------
   5. Filter bar
   -------------------------------------------------------------------------- */

.inn-filters {
    display: grid;
    /* Dates, then the three controls beside them, then the reset. THE COUNT IS
       PART OF THE MARKUP: a filter added or removed without this number moving
       leaves a column standing empty or two controls sharing one. The rendered
       bar and this value are compared in tests/test-filter-bar.php. */
    grid-template-columns: minmax(272px, 1.5fr) repeat(3, minmax(164px, 1fr)) auto;
    gap: 16px;
    align-items: end;
    padding: 20px;
    margin-bottom: 28px;
    background: var(--inn-canvas);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    box-shadow: var(--inn-shadow-sm);
}

@media (max-width: 1080px) {
    .inn-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .inn-filter--dates { grid-column: 1 / -1; }
    .inn-filter--reset { grid-column: 1 / -1; justify-self: start; }
}
@media (max-width: 560px) {
    .inn-filters { grid-template-columns: 1fr; padding: 16px; }
}

.inn-filter { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

/* The reset control has no label above it, so it aligns to the control row
   rather than the label row, and must never wrap onto two lines. */
.inn-filter--reset { justify-content: flex-end; }
.inn-filter--reset .inn-sf-btn { white-space: nowrap; }

.inn-filter-dates { display: flex; align-items: center; gap: 8px; }
.inn-date { flex: 1; min-width: 0; }
.inn-date input { width: 100%; }
.inn-date-sep { color: var(--inn-ink-faint); font-size: 1rem; flex: none; }

/* Popover controls (guests / price / amenities) ------------------------- */

.inn-pop { position: relative; }

.inn-pop-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    min-height: 46px;
    padding: 10px 14px;
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius-sm);
    background: var(--inn-surface);
    color: var(--inn-ink);
    font-family: var(--inn-font-body);
    font-size: .95rem;
    text-align: left;
    cursor: pointer;
    transition: border-color .18s ease, box-shadow .18s ease;
}
/* THESE ARE SELECTS DRAWN AS BUTTONS, AND ONLY THE BUTTONS WERE BEING PAINTED.
   Guests and Price are <button>s; Type beside them is a real <select> and the
   dates are <input>s, which no `button:hover` rule can reach. So the row
   diverged under the cursor: the two pseudo-selects filled with the theme's
   accent while their neighbours sat still, and the only rule here said
   border-color — nothing claimed the fill or the ink, so the kit had both.
   Stating the resting fill is what holds them level. --inn-surface and
   --inn-canvas are both #FFFFFF, so "the control does not fill" and "the bar
   shows through" are the same pixel; the surface token is named because what
   is being held still is the control's own background, not the bar's. */
.inn-pop-toggle.inn-pop-toggle:hover:not([disabled]) { border-color: var(--inn-line-strong); background: var(--inn-surface); color: var(--inn-ink); }
.inn-pop-toggle.inn-pop-toggle:active:not([disabled]) { border-color: var(--inn-brand); background: var(--inn-surface); color: var(--inn-ink); }
/* Focus gets the real <select>'s own treatment — brand edge and ring, as on
   .inn-sf-select:focus — so the row still matches when a keyboard is driving
   it. It is written as :focus rather than :focus-visible because the kit lists
   `button:focus` beside `button:hover`: a toggle left focused after its panel
   closed would otherwise sit on the page painted the theme's accent, with
   nothing here saying anything about it. */
.inn-pop-toggle.inn-pop-toggle:focus,
.inn-pop-toggle.inn-pop-toggle[aria-expanded="true"] { border-color: var(--inn-brand); background: var(--inn-surface); color: var(--inn-ink); box-shadow: 0 0 0 3px var(--inn-brand-soft); }
.inn-pop-toggle.inn-pop-toggle[disabled] { opacity: .55; cursor: not-allowed; }

.inn-pop-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inn-pop-toggle.has-value .inn-pop-value { font-weight: 600; color: var(--inn-brand); }

.inn-pop-caret {
    flex: none;
    width: 8px; height: 8px;
    border-right: 1.5px solid var(--inn-ink-faint);
    border-bottom: 1.5px solid var(--inn-ink-faint);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform .2s ease;
}
.inn-pop-toggle[aria-expanded="true"] .inn-pop-caret { transform: rotate(-135deg) translate(-2px, -2px); }

.inn-pop-panel {
    position: absolute;
    z-index: 40;
    top: calc(100% + 8px);
    left: 0;
    width: max(100%, 300px);
    max-height: min(420px, 60vh);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 18px;
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    box-shadow: var(--inn-shadow-lg);
    animation: inn-sf-pop .16s ease both;
}
.inn-pop-panel[hidden] { display: none; }

/* Keep the panel on screen when its control sits at the right edge. */
.inn-filter--price .inn-pop-panel { left: auto; right: 0; }

@media (max-width: 560px) {
    .inn-pop-panel { left: 0; right: 0; width: auto; }
}

@keyframes inn-sf-pop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

.inn-pop-note {
    margin: 14px 0 0;
    font-size: .8rem;
    color: var(--inn-ink-faint);
    line-height: 1.45;
}
.inn-pop-actions { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--inn-line); }

/* Steppers --------------------------------------------------------------- */

.inn-stepper {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 0;
}
.inn-stepper + .inn-stepper { border-top: 1px solid var(--inn-line); }
.inn-stepper-text strong { display: block; font-size: .95rem; font-weight: 600; }
.inn-stepper-text small { color: var(--inn-ink-faint); font-size: .8rem; }

.inn-stepper-ctl { display: flex; align-items: center; gap: 4px; flex: none; }

.inn-step {
    width: 34px; height: 34px;
    display: grid; place-items: center;
    border: 1px solid var(--inn-line-strong, #C7D2E2);
    border-radius: 50%;
    /* Fallbacks for the same reason as the dialog panel: these controls render
       inside it, and a − with no colour is a button that looks empty. */
    background: var(--inn-surface, #FFFFFF);
    color: var(--inn-brand, #1B2F55);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease;
}
.inn-step.inn-step:hover:not([disabled]),
.inn-step.inn-step:focus-visible {
    /* `color` is restated for the reason given on the dialog's close button: a
       theme rule on `button:hover` beats the base rule here, and turned the −
       and + white against the pale hover fill. The doubled class is the general
       form of that fix — see THE STATE SPECIFICITY RULE in section 1. */
    border-color: var(--inn-brand);
    background: var(--inn-brand-soft);
    color: var(--inn-brand);
}
.inn-step.inn-step:active:not([disabled]) {
    border-color: var(--inn-brand-dark);
    background: var(--inn-sky);
    color: var(--inn-brand-dark);
}
.inn-step.inn-step:focus-visible {
    outline: 2px solid var(--inn-brand);
    outline-offset: 2px;
}
.inn-step.inn-step[disabled] { opacity: .35; cursor: not-allowed; }

/* THE − AND + SIT IN THE MIDDLE OF THE CIRCLE.
   ---------------------------------------------------------------------------
   These are the guest steppers: the accommodation grid's "Add guests" panel
   and the same control on the unit page. The products quantity pill uses
   `.inn-step` too and is deliberately not matched here — `.inn-qty .inn-step`
   already forces its own box, and that one was reported as fine.

   What was wrong is the same shape as the product dialog's close button, which
   this file already hardens, and which these two never got. A `button` carries
   the user agent's 6px of inline padding, and a theme's `button` rule (the kit
   is (0,1,1), a widget container can be stronger) adds its own padding, a pink
   fill and a min-height. The 34px circle is border-box on this site, so that
   padding is eaten out of the circle and the glyph — a single character, lined
   up on the text baseline — ends up high and to one side of it.

   The box is forced. The fill is not: it is named at (0,3,1), which clears a
   kit `button` rule, and the states below are named one class higher so a
   hover still changes the circle. `font-size: 0` hides the character itself
   and the mark is drawn, because a "+" and a "−" are painted on the math axis
   of whatever face the theme loaded, which is not the middle of the em box and
   so not the middle of the circle. The character stays in the markup for the
   case where this sheet does not arrive; the accessible name is the
   aria-label. */
.inn-stepper button.inn-step.inn-step {
    box-sizing: border-box !important;
    display: grid !important;
    place-items: center !important;
    width: 34px !important;
    height: 34px !important;
    min-width: 0 !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    border-style: solid !important;
    border-width: 1px !important;
    border-color: var(--inn-line-strong, #C7D2E2);
    border-radius: 50% !important;
    line-height: 0 !important;
    font-size: 0 !important;
    appearance: none;
    background: var(--inn-surface, #FFFFFF);
    color: var(--inn-brand, #1B2F55);
    text-indent: 0;
    /* Both marks are taken out of flow. The button still contains the
       character, and a grid item with a sibling — even one at font-size: 0 —
       is laid out in half the circle. The bars are absolute, at 50% and pulled
       back by half their own size, so they do not share the box with anything. */
    position: relative;
}
.inn-stepper button.inn-step.inn-step::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    display: block;
    background: currentColor;
    border-radius: 1px;
    transform: translate(-50%, -50%);
}
/* One bar. 12px in a 34px circle is the same proportion as the old 1.1rem glyph. */
.inn-stepper button.inn-step.inn-step[data-dir="-1"]::before {
    width: 12px;
    height: 2px;
}
/* ::after exists only on the plus — a second bar on the minus would be a
   second mark. */
.inn-stepper button.inn-step.inn-step[data-dir="1"]::before,
.inn-stepper button.inn-step.inn-step[data-dir="1"]::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    display: block;
    background: currentColor;
    border-radius: 1px;
    transform: translate(-50%, -50%);
}
.inn-stepper button.inn-step.inn-step[data-dir="1"]::before {
    width: 12px;
    height: 2px;
}
.inn-stepper button.inn-step.inn-step[data-dir="1"]::after {
    width: 2px;
    height: 12px;
}
.inn-stepper button.inn-step.inn-step:hover:not([disabled]),
.inn-stepper button.inn-step.inn-step:focus-visible {
    border-color: var(--inn-brand, #1B2F55);
    background: var(--inn-brand-soft, #E8EFF7);
    color: var(--inn-brand, #1B2F55);
}
.inn-stepper button.inn-step.inn-step:active:not([disabled]) {
    border-color: var(--inn-brand-dark, #122140);
    background: var(--inn-sky, #D6EAF6);
    color: var(--inn-brand-dark, #122140);
}
.inn-stepper button.inn-step.inn-step:focus-visible {
    outline: 2px solid var(--inn-brand, #1B2F55);
    outline-offset: 2px;
}
.inn-stepper button.inn-step.inn-step[disabled] {
    opacity: .35;
    cursor: not-allowed;
}

.inn-step-input {
    /* Sized in ch so the box follows the digits rather than a guessed pixel
       width, and box-sized with its own padding and height because themes put
       generous padding and a min-height on every `input` — which cropped a
       two-digit quantity to something like "5" with the rest cut off. */
    box-sizing: border-box;
    width: 4ch;
    min-width: 0;
    height: 34px;
    padding: 0 2px;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    line-height: 1;
    background: transparent;
    color: var(--inn-ink);
    font-family: var(--inn-font-body);
    font-size: 1rem;
    font-weight: 600;
    text-align: center;
    -moz-appearance: textfield;
}
.inn-step-input::-webkit-outer-spin-button,
.inn-step-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.inn-step-input.inn-step-input:focus { outline: none; }
.inn-step-input.inn-step-input:focus-visible { outline: 2px solid var(--inn-brand); outline-offset: 1px; border-radius: 4px; }

/* Dual range slider ------------------------------------------------------ */

.inn-range { position: relative; height: 34px; margin: 6px 4px 0; }

.inn-range-track {
    position: absolute;
    inset-inline: 0;
    top: 15px;
    height: 4px;
    background: var(--inn-line);
    border-radius: 2px;
}
.inn-range-fill {
    position: absolute;
    top: 0; bottom: 0;
    background: var(--inn-brand);
    border-radius: 2px;
}

.inn-range-input {
    position: absolute;
    inset-inline: 0;
    top: 0;
    width: 100%;
    height: 34px;
    margin: 0;
    background: none;
    appearance: none;
    pointer-events: none; /* Only the thumbs are grabbable. */
}
.inn-range-input.inn-range-input:focus-visible { outline: none; }

.inn-range-input::-webkit-slider-thumb {
    appearance: none;
    pointer-events: auto;
    width: 20px; height: 20px;
    border-radius: 50%;
    border: 2px solid var(--inn-brand);
    background: var(--inn-surface);
    box-shadow: var(--inn-shadow-sm);
    cursor: grab;
}
.inn-range-input::-moz-range-thumb {
    pointer-events: auto;
    width: 16px; height: 16px;
    border-radius: 50%;
    border: 2px solid var(--inn-brand);
    background: var(--inn-surface);
    cursor: grab;
}
.inn-range-input.inn-range-input:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--inn-brand-soft); }
.inn-range-input.inn-range-input:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px var(--inn-brand-soft); }

/* The thumb is the one control here that is dragged rather than clicked, so
   the pressed state is the cursor rather than a colour. */
.inn-range-input.inn-range-input:active::-webkit-slider-thumb { cursor: grabbing; border-color: var(--inn-brand-dark); }
.inn-range-input.inn-range-input:active::-moz-range-thumb { cursor: grabbing; border-color: var(--inn-brand-dark); }

.inn-range-readout {
    display: flex;
    justify-content: space-between;
    margin-top: 10px;
    font-size: .9rem;
    font-weight: 600;
    color: var(--inn-ink);
}

/* Checkbox rows ---------------------------------------------------------- */

/* TWO COLUMNS SINCE THE AMENITIES FILTER WENT. There were four — box, icon,
   label, count — and the amenity rows in the filter popover were the only
   markup that ever filled them. Every remaining checkbox in the plugin is a box
   and a sentence: the voucher's "email this to them", the registration form's
   indemnity and consent. The `.inn-checks` fieldset, `.inn-check-icon` and
   `.inn-check-count` went with the filter for the same reason. */
.inn-check {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 10px;
    padding: 8px 6px;
    border-radius: var(--inn-radius-sm);
    cursor: pointer;
    transition: background .14s ease;
}
.inn-check.inn-check:hover { background: var(--inn-brand-soft); color: var(--inn-ink); }
.inn-check.inn-check:active { background: var(--inn-sky); color: var(--inn-ink); }

/* Visually hidden but still focusable and hit-testable — a zero-size input is
   skipped by some assistive tech and by automated clicks. */
.inn-check input {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.inn-check-box {
    width: 18px; height: 18px;
    border: 1.5px solid var(--inn-line-strong);
    border-radius: 3px;
    background: var(--inn-surface);
    display: grid;
    place-items: center;
    transition: background .14s ease, border-color .14s ease;
}
.inn-check-box::after {
    content: "";
    width: 10px; height: 6px;
    border-left: 2px solid #fff;
    border-bottom: 2px solid #fff;
    transform: rotate(-45deg) scale(0);
    transition: transform .14s ease;
    margin-top: -2px;
}
.inn-check input:checked + .inn-check-box { background: var(--inn-brand); border-color: var(--inn-brand); }
.inn-check input:checked + .inn-check-box::after { transform: rotate(-45deg) scale(1); }
.inn-check input:focus-visible + .inn-check-box { box-shadow: 0 0 0 3px var(--inn-brand-soft); border-color: var(--inn-brand); }

.inn-check-label { font-size: .92rem; }

/* --------------------------------------------------------------------------
   6. Accommodation cards
   -------------------------------------------------------------------------- */

.inn-card {
    display: flex;
    flex-direction: column;
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    overflow: hidden;
    transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.inn-card.inn-card:hover,
.inn-card.inn-card:focus-within { border-color: var(--inn-line-strong); box-shadow: var(--inn-shadow); transform: translateY(-2px); }
.inn-card[hidden] { display: none; }

.inn-card-media {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    background: var(--inn-brand-soft);
    overflow: hidden;
}
.inn-card-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s cubic-bezier(.2,.8,.3,1); }
.inn-card:hover .inn-card-media img { transform: scale(1.04); }

.inn-card-monogram {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-family: var(--inn-font-display);
    font-size: 3rem;
    font-weight: 600;
    letter-spacing: .06em;
    color: #fff;
    background: linear-gradient(140deg,
        hsl(var(--inn-hue, 214) 34% 38%),
        hsl(var(--inn-hue, 214) 42% 20%));
}

.inn-card-chip {
    position: absolute;
    left: 12px; bottom: 12px;
    padding: 5px 12px;
    background: rgba(255, 255, 255, .94);
    color: var(--inn-brand);
    font-family: var(--inn-font-display);
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    border-radius: var(--inn-radius-sm);
}

.inn-card-body {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1;
    padding: 18px 20px 20px;
}

.inn-card-title { font-size: 1.3rem; margin: 0; }
.inn-card-title.inn-card-title a { color: inherit; text-decoration: none; }
.inn-card-title.inn-card-title a:hover,
.inn-card-title.inn-card-title a:focus-visible { color: var(--inn-brand); text-decoration: underline; text-underline-offset: 3px; }
.inn-card-title.inn-card-title a:active { color: var(--inn-brand-dark); }

.inn-card-blurb {
    margin: 0;
    font-size: .92rem;
    line-height: 1.55;
    color: var(--inn-ink-soft);
}

.inn-card-specs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 0;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: .82rem;
    color: var(--inn-ink-faint);
}
.inn-card-specs li { display: flex; align-items: center; }
.inn-card-specs li + li::before {
    content: "";
    flex: none;
    width: 3px; height: 3px;
    border-radius: 50%;
    background: currentColor;
    margin: 0 10px;
}

.inn-card-amenities {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    list-style: none;
    margin: 0;
    padding: 0;
}
.inn-card-amenities li {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 10px 4px 7px;
    background: var(--inn-brand-soft);
    color: var(--inn-brand);
    border-radius: var(--inn-radius-pill);
    font-size: .74rem;
    white-space: nowrap;
}
.inn-card-amenities .inn-amenity-icon { width: 14px; height: 14px; }
.inn-card-amenities-more { background: transparent !important; color: var(--inn-ink-faint) !important; padding-left: 4px !important; }

/* Availability slot, filled in once dates are chosen --------------------- */

.inn-card-availability {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-radius: var(--inn-radius-sm);
    font-size: .85rem;
    line-height: 1.4;
}
.inn-card-availability[hidden] { display: none; }
.inn-card-availability.is-checking { background: var(--inn-canvas); color: var(--inn-ink-faint); border: 1px solid var(--inn-line); }
.inn-card-availability.is-free     { background: var(--inn-positive-soft); color: var(--inn-positive); }
.inn-card-availability.is-taken    { background: var(--inn-negative-soft); color: var(--inn-negative); }
.inn-card-availability.is-unknown  { background: var(--inn-notice-soft); color: var(--inn-notice); }
.inn-card-availability strong { font-weight: 700; }

.inn-spinner {
    flex: none;
    width: 14px; height: 14px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: inn-spin .7s linear infinite;
    opacity: .7;
}
@keyframes inn-spin { to { transform: rotate(360deg); } }

/* A unit that cannot take the party, or is booked out, stays visible but
   recedes — hiding it entirely makes the grid feel broken. */
.inn-card.is-unavailable { opacity: .62; }
/* One class above the card's own states, so a room that cannot be booked does
   not lift towards the cursor as though it could. */
.inn-card.inn-card.is-unavailable:hover,
.inn-card.inn-card.is-unavailable:focus-within { transform: none; box-shadow: none; }

.inn-card-foot {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid var(--inn-line);
}

.inn-card-price { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.inn-card-price-from { font-size: .72rem; text-transform: uppercase; letter-spacing: .1em; color: var(--inn-ink-faint); }
.inn-card-price-value { font-family: var(--inn-font-display); font-size: 1.35rem; font-weight: 600; color: var(--inn-ink); }
.inn-card-price-value--muted { font-size: .95rem; color: var(--inn-ink-faint); }
.inn-card-price-unit { font-size: .75rem; color: var(--inn-ink-faint); }

.inn-card-cta { flex: none; }

/* --------------------------------------------------------------------------
   7. Section bands (mirrors the site's alternating full-width bands)
   -------------------------------------------------------------------------- */

.inn-sf-band { padding: clamp(28px, 5vw, 56px) 0; }
.inn-sf-band--sky   { background: var(--inn-sky); }
.inn-sf-band--sand  { background: var(--inn-sand); }

/* --------------------------------------------------------------------------
   8. Products — toolbar
   -------------------------------------------------------------------------- */

.inn-shop-toolbar {
    display: grid;
    grid-template-columns: minmax(260px, 2fr) minmax(180px, 1fr) auto;
    gap: 16px;
    align-items: end;
    padding: 20px;
    margin-bottom: 28px;
    background: var(--inn-canvas);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    box-shadow: var(--inn-shadow-sm);
}
@media (max-width: 720px) {
    .inn-shop-toolbar { grid-template-columns: 1fr; padding: 16px; }
}

.inn-search { position: relative; display: flex; align-items: center; }
.inn-search .inn-sf-input { padding-left: 42px; padding-right: 38px; }

.inn-search-icon {
    position: absolute;
    left: 14px;
    color: var(--inn-ink-faint);
    pointer-events: none;
}

.inn-search-clear {
    position: absolute;
    right: 8px;
    /* Same hardening as the dialog close: a theme's padding and line-height on
       `button` turn a 26px circle into an oval and park the × on the baseline.
       The fill is restated one element higher so a kit `button` rule cannot
       paint this the accent pink while the field beside it stays white. */
    box-sizing: border-box !important;
    width: 26px !important;
    height: 26px !important;
    min-width: 0 !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 50% !important;
    line-height: 1 !important;
    display: grid !important;
    place-items: center !important;
    appearance: none;
    background: var(--inn-line, #DFE5EE);
    color: var(--inn-ink-soft, #4A5A78);
    font-size: 1rem;
    cursor: pointer;
}
button.inn-search-clear.inn-search-clear {
    background: var(--inn-line, #DFE5EE);
    color: var(--inn-ink-soft, #4A5A78);
}
.inn-search-clear.inn-search-clear:hover,
.inn-search-clear.inn-search-clear:focus-visible { background: var(--inn-line-strong); color: var(--inn-ink); }
.inn-search-clear.inn-search-clear:active { background: var(--inn-ink-faint); color: #fff; }

.inn-search-hint { margin: 6px 0 0; font-size: .78rem; color: var(--inn-ink-faint); }

/* --------------------------------------------------------------------------
   9. Product cards
   -------------------------------------------------------------------------- */

.inn-prod {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    overflow: hidden;
    transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.inn-prod.inn-prod:hover,
.inn-prod.inn-prod:focus-within { border-color: var(--inn-line-strong); box-shadow: var(--inn-shadow); transform: translateY(-2px); }
.inn-prod[hidden] { display: none; }
.inn-prod.is-in-cart { border-color: var(--inn-brand); }

/* The whole card opens the detail dialog. This button is stretched behind the
   content; the buy controls sit above it, so they keep their own clicks. */
.inn-prod-open {
    position: absolute;
    inset: 0;
    z-index: 1;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}
.inn-prod-open.inn-prod-open:focus-visible {
    outline: 2px solid var(--inn-brand);
    outline-offset: -3px;
}
/* The opener is stretched over the whole card and has no box of its own, so a
   press has nowhere to show except as a tint over what it covers. Without it a
   tap on a phone — where the card cannot lift, because nothing hovers — looked
   like nothing happening while the dialog was fetched. */
.inn-prod-open.inn-prod-open:active { background: rgba(27, 47, 85, .07); color: inherit; }

.inn-prod-media {
    position: relative;
    aspect-ratio: 1 / 1;
    background: var(--inn-sand);
    overflow: hidden;
}
.inn-prod-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s cubic-bezier(.2,.8,.3,1); }
.inn-prod:hover .inn-prod-media img { transform: scale(1.04); }

.inn-prod-noimage {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-family: var(--inn-font-display);
    font-size: 3rem;
    color: var(--inn-accent);
    background: var(--inn-accent-soft);
}

.inn-prod-flag {
    position: absolute;
    top: 12px; left: 12px;
    padding: 4px 10px;
    background: var(--inn-accent);
    color: #fff;
    font-family: var(--inn-font-display);
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    border-radius: var(--inn-radius-sm);
}
.inn-prod-flag--out { background: var(--inn-ink-soft); top: auto; bottom: 12px; }

.inn-prod-body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
    padding: 16px 18px 8px;
}

.inn-prod-cat {
    margin: 0;
    font-family: var(--inn-font-display);
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--inn-accent);
}

.inn-prod-name { margin: 0; font-size: 1.12rem; line-height: 1.25; }

.inn-prod-desc {
    margin: 0;
    font-size: .86rem;
    line-height: 1.5;
    color: var(--inn-ink-soft);
}

.inn-prod-price {
    margin: 6px 0 0;
    font-family: var(--inn-font-display);
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--inn-ink);
}

/* Buy controls sit above the stretched opener. */
.inn-prod-buy {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px 18px 18px;
}

.inn-qty {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    align-self: flex-start;
    padding: 3px;
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius-pill);
    background: var(--inn-surface);
}

/* The three controls are given one height and told not to flex, so the −, the
   figure and the + sit on a single baseline inside the pill. They drifted
   before because each took its height from its own content and from whatever
   the theme puts on a button or an input, which differ. */
.inn-qty .inn-step,
.inn-qty .inn-step-input {
    flex: none;
    height: 30px;
    min-height: 0;
    align-self: center;
}
.inn-qty .inn-step {
    width: 30px;
    padding: 0;
    border: 0;
    font-size: 1.05rem;
}
.inn-qty .inn-step:hover:not([disabled]),
.inn-qty .inn-step:focus-visible {
    background: var(--inn-brand-soft);
    color: var(--inn-brand);
}
.inn-qty .inn-step-input { width: 3.5ch; font-size: .95rem; }

/* WHY THESE ARE !important, WHEN ALMOST NOTHING ELSE HERE IS.
   ---------------------------------------------------------------------------
   These controls are dropped into somebody else's theme, and themes style
   `input` and `button` heavily and at specificities we cannot predict — a rule
   like `.elementor-widget-container input[type="number"]` is 0-3-1 and beats
   anything reasonable we can write without an ancestor to hang off. The dialog
   is also moved to <body> to escape a themed containing block, so scoping under
   .inn-sf is not available either: it would fix the card and break the dialog.

   The list is deliberately short. Only the box-model properties that decide
   whether the control is usable at all are forced — a theme's padding cropped
   the figure, a theme's `width: 100%` stretched the box across the pill, a
   theme's min-height pushed the − and + off the line. Colour, font and
   behaviour are all left alone, so a theme can still make these look like its
   own. */
.inn-qty .inn-step,
.inn-qty .inn-step-input {
    box-sizing: border-box !important;
    height: 30px !important;
    min-height: 0 !important;
    line-height: 1 !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    background-image: none !important;
    margin: 0 !important;
    flex: none !important;
}
.inn-qty .inn-step {
    width: 30px !important;
    padding: 0 !important;
    border-radius: 50% !important;
}
.inn-qty .inn-step-input {
    /* Room for two digits in any font: ch follows the digit width, and the em
       floor covers a face where ch measures narrow. */
    width: 4ch !important;
    min-width: 2.6em !important;
    padding: 0 2px !important;
    text-align: center !important;
    text-indent: 0 !important;
    line-height: normal !important;

    /* THREE WAYS A THEME CAN MAKE THE FIGURE VANISH, and all three are common.
       text-indent pushes it out of the box. -webkit-text-fill-color overrides
       `color` outright in WebKit and Blink, and themes set it for autofill
       styling. opacity dims it to nothing. None of them is exotic, and each on
       its own leaves an empty box with a working − and +.

       The literal fallback in var() is deliberate too: these controls also
       render inside the dialog, which is moved to <body> and so sits outside
       whatever element declares the tokens. A var() that cannot resolve makes
       the whole declaration invalid, and the figure would inherit the page's
       colour — white, on a white panel. */
    color: var(--inn-ink, #16243F) !important;
    -webkit-text-fill-color: currentColor !important;
    opacity: 1 !important;
}

.inn-prod-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.inn-prod-actions .inn-sf-btn { width: 100%; padding-inline: 8px; }

.inn-prod-incart {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin: 0;
    padding: 8px 8px 8px 12px;
    background: var(--inn-brand-soft);
    border-radius: var(--inn-radius-sm);
    color: var(--inn-brand);
    font-size: .8rem;
    line-height: 1.35;
}
.inn-prod-incart[hidden] { display: none; }

.inn-incart-remove {
    /* Forced for the same reason as the quantity stepper: a theme's padding and
       min-height on `button` inflate a 22x22 box into an oval, and its own
       line-height pushes the glyph off centre — which is what turns a round
       close button into a lopsided lozenge. The box is stated outright so the
       circle stays a circle, and the glyph is centred by the grid rather than by
       whatever line-height happens to be inherited. */
    flex: none !important;
    box-sizing: border-box !important;
    width: 22px !important;
    height: 22px !important;
    min-width: 0 !important;
    min-height: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    border: 0 !important;
    border-radius: 50% !important;
    line-height: 1 !important;
    display: grid !important;
    place-items: center !important;
    background: transparent;
    color: var(--inn-brand, #1B2F55);
    font-size: 1.05rem;
    cursor: pointer;
    transition: background .15s ease;
}
/* Restated above the kit's resting `button` rule, which is (0,1,1) and was
   painting this mark's circle the accent. The hover further down is (0,3,0). */
button.inn-incart-remove.inn-incart-remove {
    background: transparent;
    color: var(--inn-brand, #1B2F55);
}
.inn-incart-remove.inn-incart-remove:focus-visible {
    outline: 2px solid var(--inn-brand, #1B2F55);
    outline-offset: 2px;
}
/* The colour is restated for the reason given on the voucher chips: the fill is
   a 14% navy wash, and a theme's `button:hover { color }` turned the glyph
   white on it — a remove button that vanishes under the cursor that reached
   for it. */
.inn-incart-remove.inn-incart-remove:hover { background: rgba(27, 47, 85, .14); color: var(--inn-brand, #1B2F55); }
.inn-incart-remove.inn-incart-remove:active { background: rgba(27, 47, 85, .24); color: var(--inn-brand, #1B2F55); }

/* The standalone [inn_voucher] page --------------------------------------- */

.inn-voucher-page { padding-block: clamp(16px, 3vw, 32px); }

.inn-voucher-pagehead {
    max-width: 46rem;
    margin: 0 auto clamp(20px, 3vw, 36px);
    text-align: center;
}
.inn-voucher-pagetitle {
    font-family: var(--inn-font-display, Georgia, serif);
    font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.4rem);
    margin: 0 0 .3em;
}
.inn-voucher-pageintro {
    margin: 0;
    color: var(--inn-ink-soft, #46556F);
    font-size: 1.02rem;
    line-height: 1.6;
}

/* The gift voucher's card ------------------------------------------------- */

/* Its "image" is the artwork itself, which is 1.62:1 against a card media box
   that is square — so it is centred in the box with room around it rather than
   cropped, and the sand ground reads as a mount. */
.inn-prod-media--voucher {
    display: grid;
    place-items: center;
    padding: 14px;
    background: var(--inn-accent-soft);
}
.inn-prod-media--voucher .inn-voucher {
    width: 100%;
    box-shadow: var(--inn-shadow);
    transition: transform .5s cubic-bezier(.2,.8,.3,1);
}
.inn-prod--voucher:hover .inn-prod-media--voucher .inn-voucher { transform: scale(1.03); }

/* The designer is borrowed by the dialog, whose content area is two columns.
   It brings its own two-column layout, so it takes the full width and its own
   padding rather than being squeezed into one of them. */
.inn-dlg-content > .inn-voucher-layout {
    grid-column: 1 / -1;
    padding: clamp(20px, 3vw, 32px);
}

/* --------------------------------------------------------------------------
   10. Detail dialog
   -------------------------------------------------------------------------- */

.inn-dlg {
    position: fixed;
    inset: 0;
    z-index: 99990;
    display: grid;
    place-items: center;
    padding: clamp(12px, 4vw, 40px);
}
/* `hidden` beats this display:grid — see the one normalising rule in section 1. */

.inn-dlg-scrim {
    position: absolute;
    inset: 0;
    background: rgba(22, 36, 63, .55);
    backdrop-filter: blur(2px);
    animation: inn-sf-fade .2s ease both;
}

.inn-dlg-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(100%, 900px);
    /* 100% of the padded viewport box, not a fixed 820px. The old cap made a
       tall product scroll on a tall screen with empty space above and below it,
       because the panel stopped growing long before the screen ran out. Now the
       panel grows to fit its content and stops at the edge of the gutter, so
       inn-dlg-content's overflow-y: auto only produces a scrollbar when the
       content genuinely will not fit on the screen. */
    max-height: 100%;
    /* Literal fallbacks on the three properties that decide whether this is
       visible at all. The dialog is moved to <body> to escape a themed
       containing block, which also moves it outside whatever element declares
       the tokens — and an unresolved var() with no fallback invalidates the
       whole declaration, so the panel loses its background and becomes a pane
       of text floating on the page. The tokens are on :root now, which is the
       real fix; this is what keeps the component honest if that ever changes. */
    background: var(--inn-surface, #FFFFFF);
    border-radius: var(--inn-radius-lg, 18px);
    box-shadow: var(--inn-shadow-lg, 0 24px 60px rgba(16, 29, 56, .28));
    overflow: hidden;
    animation: inn-dlg-in .24s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes inn-dlg-in { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }

.inn-dlg-x {
    position: absolute;
    top: 12px; right: 12px;
    z-index: 3;
    /* Same hardening as the small × above — this one is 38px and just as
       vulnerable to a theme's button padding. */
    box-sizing: border-box !important;
    width: 38px !important;
    height: 38px !important;
    min-width: 0 !important;
    min-height: 0 !important;
    padding: 0 !important;
    line-height: 1 !important;
    border-radius: 50% !important;
    display: grid !important;
    place-items: center !important;
    border: 0;
    background: rgba(255,255,255,.92);
    color: var(--inn-ink, #16243F);
    font-size: 1.4rem;
    cursor: pointer;
    box-shadow: var(--inn-shadow-sm);
}
/* The box above is forced; the fill was not, and a single class loses to a
   kit `button` rule, which is how the exit dialog's close button arrived pink.
   Named again here so this circle keeps the white it was given. The hover
   below is (0,3,0) and still outranks this (0,2,1). */
button.inn-dlg-x.inn-dlg-x {
    background: rgba(255,255,255,.92);
    color: var(--inn-ink, #16243F);
}
/* Both the colour and the background, every time. The rule used to set only
   the background, so `color` came from the base rule at one class of
   specificity — which a theme's `button:hover { color: #fff }` outranks. The
   result was a white × on a white circle: the close button disappeared under
   the cursor. Naming the colour here settles it, and a focus ring replaces the
   theme's default outline, which sat awkwardly around the circle. */
.inn-dlg-x.inn-dlg-x:hover,
.inn-dlg-x.inn-dlg-x:focus-visible {
    background: #fff;
    color: var(--inn-brand, #1B2F55);
}
.inn-dlg-x.inn-dlg-x:active {
    background: var(--inn-brand-soft, #E8EFF7);
    color: var(--inn-brand-dark, #122140);
}
.inn-dlg-x.inn-dlg-x:focus-visible {
    outline: 2px solid var(--inn-brand);
    outline-offset: 2px;
}

.inn-dlg-content {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0;
    overflow-y: auto;
    flex: 1;
    /* Without this a flex child's automatic minimum size is its content, so the
       panel would grow past its max-height instead of letting this scroll —
       which is the whole reason the scrollbar has to exist at all. */
    min-height: 0;
}
@media (max-width: 720px) {
    .inn-dlg-content { grid-template-columns: 1fr; }
}

.inn-dlg-media { background: var(--inn-sand); padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.inn-dlg-hero { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--inn-radius-sm); }

.inn-dlg-noimage {
    display: grid;
    place-items: center;
    aspect-ratio: 1 / 1;
    font-family: var(--inn-font-display);
    font-size: 4rem;
    color: var(--inn-accent);
}

.inn-dlg-thumbs { display: flex; gap: 8px; flex-wrap: wrap; }
.inn-dlg-thumb {
    width: 56px; height: 56px;
    padding: 0;
    border: 2px solid transparent;
    border-radius: var(--inn-radius-sm);
    background: none;
    overflow: hidden;
    cursor: pointer;
}
.inn-dlg-thumb img { width: 100%; height: 100%; object-fit: cover; }
/* These had no states at all: four photographs of a product, and no way to tell
   from the pointer that any of them was a control. */
.inn-dlg-thumb.inn-dlg-thumb:hover { border-color: var(--inn-line-strong); }
.inn-dlg-thumb.inn-dlg-thumb:active { border-color: var(--inn-brand-dark); }
.inn-dlg-thumb.inn-dlg-thumb:focus-visible { outline: 2px solid var(--inn-brand); outline-offset: 2px; }
.inn-dlg-thumb.inn-dlg-thumb.is-active { border-color: var(--inn-brand); }

.inn-dlg-info { padding: clamp(20px, 3vw, 32px); }
.inn-dlg-title { font-size: clamp(1.5rem, 1.3rem + .8vw, 2rem); margin-bottom: .2em; }
.inn-dlg-price { font-family: var(--inn-font-display); font-size: 1.5rem; font-weight: 600; margin: 0 0 4px; }
.inn-dlg-sku { margin: 0 0 16px; font-size: .78rem; color: var(--inn-ink-faint); letter-spacing: .04em; }
.inn-dlg-desc { color: var(--inn-ink-soft); font-size: .95rem; line-height: 1.65; }
.inn-dlg-desc :where(p, ul, ol) { margin: 0 0 1em; }
.inn-dlg-desc :where(ul, ol) { padding-left: 1.2em; }
.inn-dlg-linkout { grid-column: 1 / -1; padding: 0 clamp(20px, 3vw, 32px) 24px; }

.inn-dlg-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    padding: 16px clamp(20px, 3vw, 32px);
    border-top: 1px solid var(--inn-line);
    background: var(--inn-canvas);
}
.inn-dlg-foot[hidden] { display: none; }
.inn-dlg-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   11. Accommodation view page
   -------------------------------------------------------------------------- */

.inn-unit-banner {
    position: relative;
    display: flex;
    align-items: flex-end;
    min-height: clamp(280px, 42vw, 460px);
    margin-bottom: clamp(24px, 4vw, 44px);
    padding: clamp(20px, 4vw, 40px);
    border-radius: var(--inn-radius-lg);
    overflow: hidden;
    background-color: var(--inn-brand-dark);
    background-image: var(--inn-banner);
    background-size: cover;
    background-position: center;
    color: #fff;
}

/* Scrim: the title has to stay legible over whatever photograph is set. */
.inn-unit-banner::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top,
        rgba(18, 33, 64, .88) 0%,
        rgba(18, 33, 64, .55) 42%,
        rgba(18, 33, 64, .12) 100%);
}
.inn-unit-banner.is-plain::after {
    background: linear-gradient(140deg, rgba(27,47,85,.9), rgba(18,33,64,.98));
}

.inn-unit-banner-inner { position: relative; z-index: 1; width: 100%; }

.inn-unit-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 20px;
    color: rgba(255,255,255,.85);
    font-size: .84rem;
    text-decoration: none;
    transition: color .16s ease;
}
.inn-unit-back.inn-unit-back:hover,
.inn-unit-back.inn-unit-back:focus-visible { color: #fff; text-decoration: underline; }
.inn-unit-back.inn-unit-back:active { color: var(--inn-accent); }

.inn-unit-eyebrow {
    margin: 0 0 6px;
    font-family: var(--inn-font-display);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: var(--inn-eyebrow-space);
    text-transform: uppercase;
    color: var(--inn-accent);
}

.inn-unit-banner .inn-unit-title {
    margin: 0 0 14px;
    color: #fff;
    font-size: clamp(2rem, 1.4rem + 3vw, 3.4rem);
    line-height: 1.05;
    text-transform: uppercase;
    letter-spacing: .01em;
}

.inn-unit-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 0;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: .9rem;
    color: rgba(255,255,255,.92);
}
.inn-unit-facts li { display: flex; align-items: center; }
.inn-unit-facts li + li::before {
    content: "";
    flex: none;
    width: 3px; height: 3px;
    border-radius: 50%;
    background: var(--inn-accent);
    margin: 0 14px;
}

.inn-unit-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(300px, 1fr);
    gap: clamp(24px, 4vw, 48px);
    align-items: start;
    padding-bottom: clamp(32px, 6vw, 64px);
}
@media (max-width: 900px) {
    .inn-unit-layout { grid-template-columns: 1fr; }
}

/* Gallery ---------------------------------------------------------------- */

.inn-gallery { margin-bottom: clamp(24px, 4vw, 40px); }

.inn-gallery-hero { margin: 0; }
.inn-gallery-hero img {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    border-radius: var(--inn-radius);
    background: var(--inn-brand-soft);
}

.inn-gallery-strip {
    display: flex;
    gap: 10px;
    margin-top: 10px;
    overflow-x: auto;
    padding-bottom: 4px;
    scrollbar-width: thin;
}

.inn-gallery-thumb {
    flex: none;
    width: 92px;
    aspect-ratio: 3 / 2;
    padding: 0;
    border: 2px solid transparent;
    border-radius: var(--inn-radius-sm);
    background: var(--inn-brand-soft);
    overflow: hidden;
    cursor: pointer;
    opacity: .72;
    transition: opacity .16s ease, border-color .16s ease;
}
.inn-gallery-thumb img { width: 100%; height: 100%; object-fit: cover; }
.inn-gallery-thumb.inn-gallery-thumb:hover,
.inn-gallery-thumb.inn-gallery-thumb:focus-visible { opacity: 1; border-color: var(--inn-line-strong); }
.inn-gallery-thumb.inn-gallery-thumb:active { opacity: 1; border-color: var(--inn-brand-dark); }
.inn-gallery-thumb.inn-gallery-thumb.is-active { opacity: 1; border-color: var(--inn-brand); }

/* Body sections ---------------------------------------------------------- */

.inn-unit-section { margin-bottom: clamp(24px, 4vw, 40px); }
.inn-unit-section h2 {
    font-size: clamp(1.3rem, 1.15rem + .6vw, 1.7rem);
    margin-bottom: .6em;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.inn-unit-prose { color: var(--inn-ink-soft); font-size: 1rem; line-height: 1.7; }
.inn-unit-prose p { margin: 0 0 1em; }

.inn-unit-amenities {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 12px 20px;
    list-style: none;
    margin: 0;
    padding: 0;
}
.inn-unit-amenities li {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: .94rem;
    color: var(--inn-ink);
}
.inn-unit-amenities .inn-amenity-icon { color: var(--inn-brand); flex: none; }

.inn-unit-notes {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 8px;
    color: var(--inn-ink-soft);
    font-size: .94rem;
}
.inn-unit-notes li { padding-left: 20px; position: relative; }
.inn-unit-notes li::before {
    content: "";
    position: absolute;
    left: 2px; top: .62em;
    width: 5px; height: 5px;
    border-radius: 50%;
    background: var(--inn-accent);
}

/* Booking panel ---------------------------------------------------------- */

.inn-unit-aside { position: sticky; top: 24px; }
@media (max-width: 900px) { .inn-unit-aside { position: static; } }

.inn-book {
    padding: clamp(18px, 2.5vw, 26px);
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    box-shadow: var(--inn-shadow);
}

.inn-book-price { margin: 0 0 18px; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.inn-book-price-value { font-family: var(--inn-font-display); font-size: 1.9rem; font-weight: 600; }
.inn-book-price-unit { font-size: .82rem; color: var(--inn-ink-faint); }

.inn-book-dates { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 6px; }

/* THE − AND + FOLLOW THE LABEL; THEY DO NOT CHASE THE PANEL EDGE. .inn-stepper
   is space-between, so the cluster travels with whatever width it is given —
   and this panel is given a lot: about 330px in the sticky aside, and the whole
   column once the layout stacks under 900px. The controls ended up against the
   panel's inner edge, a hundred pixels from the word they belong to, which
   reads as two unrelated things on one line.
   264px is not a guess: it is the measure the same stepper has inside the
   filter popover (a 300px panel with 18px of padding), which is the one place
   this control was designed at. Capping the block rather than the rows keeps
   the rule between Adults and Children, and the "sleeps N" line under them, to
   the same measure. Below 264px nothing changes at all. */
.inn-book-guests { margin-bottom: 18px; max-width: 264px; }

.inn-book-cap { margin: 4px 0 0; font-size: .78rem; color: var(--inn-ink-faint); }
.inn-book-cap.is-max { color: var(--inn-notice); }

.inn-book-result { margin-top: 16px; padding: 14px 16px; border-radius: var(--inn-radius-sm); font-size: .9rem; }
.inn-book-result p { margin: 0 0 8px; }
.inn-book-result p:last-child { margin-bottom: 0; }
.inn-book-result.is-checking { background: var(--inn-canvas); border: 1px solid var(--inn-line); color: var(--inn-ink-soft); }
.inn-book-result.is-free     { background: var(--inn-positive-soft); color: var(--inn-positive); }
.inn-book-result.is-taken    { background: var(--inn-negative-soft); color: var(--inn-negative); }
.inn-book-result.is-warn     { background: var(--inn-notice-soft);   color: var(--inn-notice); }

.inn-book-yes { font-family: var(--inn-font-display); font-size: 1.15rem; text-transform: uppercase; letter-spacing: .06em; }

.inn-book-sum { margin: 12px 0 16px; display: grid; gap: 6px; color: var(--inn-ink); }
.inn-book-sum > div { display: flex; justify-content: space-between; gap: 16px; }
.inn-book-sum dt { color: var(--inn-ink-soft); font-size: .85rem; margin: 0; }
.inn-book-sum dd { margin: 0; font-weight: 600; text-align: right; font-size: .9rem; }
.inn-book-sum-total { border-top: 1px solid rgba(31,79,58,.2); padding-top: 8px; margin-top: 2px; }
.inn-book-sum-total dd { font-family: var(--inn-font-display); font-size: 1.15rem; }

.inn-book-fine { margin-top: 10px !important; font-size: .78rem; opacity: .8; text-align: center; }

/* Calendar --------------------------------------------------------------- */

.inn-cal {
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--inn-line);
}

.inn-cal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }

.inn-cal-nav {
    /* The ‹ and › are the same kind of circle as the guest stepper. Without
       the forced box, a theme's button padding parks them off centre and the
       kit's resting fill turns the circle pink — on the booking panel, directly
       under the stepper this was reported against. */
    box-sizing: border-box !important;
    width: 32px !important;
    height: 32px !important;
    min-width: 0 !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    border-radius: 50% !important;
    line-height: 1 !important;
    display: grid !important;
    place-items: center !important;
    border: 1px solid var(--inn-line, #DFE5EE);
    background: var(--inn-surface, #FFFFFF);
    color: var(--inn-brand, #1B2F55);
    font-size: 1.1rem;
    cursor: pointer;
    appearance: none;
}
button.inn-cal-nav.inn-cal-nav {
    background: var(--inn-surface, #FFFFFF);
    color: var(--inn-brand, #1B2F55);
    border: 1px solid var(--inn-line, #DFE5EE);
}
.inn-cal-nav.inn-cal-nav:hover,
.inn-cal-nav.inn-cal-nav:focus-visible { background: var(--inn-brand-soft); border-color: var(--inn-brand); color: var(--inn-brand); }
.inn-cal-nav.inn-cal-nav:active { background: var(--inn-brand); border-color: var(--inn-brand); color: #fff; }

.inn-cal-title {
    margin: 0;
    font-family: var(--inn-font-display);
    font-size: .95rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.inn-cal-months { display: grid; grid-template-columns: 1fr; gap: 20px; }
@media (min-width: 720px) and (max-width: 900px) { .inn-cal-months { grid-template-columns: 1fr 1fr; } }

.inn-cal-month-name {
    margin: 0 0 8px;
    font-size: .82rem;
    font-weight: 600;
    color: var(--inn-ink-soft);
    text-align: center;
}

.inn-cal-dow, .inn-cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}
.inn-cal-dow span {
    text-align: center;
    font-size: .68rem;
    font-weight: 700;
    color: var(--inn-ink-faint);
    padding-bottom: 4px;
}

.inn-cal-day {
    aspect-ratio: 1;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: var(--inn-radius-sm);
    background: var(--inn-brand-soft);
    color: var(--inn-brand);
    font-family: var(--inn-font-body);
    font-size: .82rem;
    cursor: pointer;
    transition: background .12s ease, color .12s ease;
}
.inn-cal-day.is-blank { background: none; cursor: default; }
.inn-cal-day.inn-cal-day:hover:not([disabled]):not(.is-blank),
.inn-cal-day.inn-cal-day:focus-visible:not([disabled]):not(.is-blank) { background: var(--inn-brand); color: #fff; }
.inn-cal-day.inn-cal-day:active:not([disabled]):not(.is-blank) { background: var(--inn-brand-dark); color: #fff; }

.inn-cal-day.is-past,
.inn-cal-day.is-taken {
    background: transparent;
    color: var(--inn-ink-faint);
    cursor: not-allowed;
}
/* Booked nights get a strike so "unavailable" survives a greyscale print or
   a colour-blind reader, not just a lighter grey. */
.inn-cal-day.is-taken { text-decoration: line-through; opacity: .65; }

.inn-cal-day.is-between { background: var(--inn-brand-soft); color: var(--inn-brand-dark); border-radius: 0; }
.inn-cal-day.is-start,
.inn-cal-day.is-end { background: var(--inn-brand); color: #fff; font-weight: 700; }
.inn-cal-day.is-start { border-radius: var(--inn-radius-sm) 0 0 var(--inn-radius-sm); }
.inn-cal-day.is-end   { border-radius: 0 var(--inn-radius-sm) var(--inn-radius-sm) 0; }

.inn-cal-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    margin-top: 14px;
    font-size: .74rem;
    color: var(--inn-ink-faint);
}
.inn-cal-legend span { display: inline-flex; align-items: center; gap: 6px; }
.inn-cal-key { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.inn-cal-key--free  { background: var(--inn-brand-soft); }
.inn-cal-key--taken { background: transparent; border: 1px solid var(--inn-line-strong); }
.inn-cal-key--sel   { background: var(--inn-brand); }

.inn-cal-hint { margin: 10px 0 0; font-size: .8rem; color: var(--inn-ink-soft); }
.inn-cal-loading, .inn-cal-error { margin: 0; font-size: .85rem; color: var(--inn-ink-soft); display: flex; align-items: center; gap: 8px; }

/* --------------------------------------------------------------------------
   12. Extras step
   -------------------------------------------------------------------------- */

.inn-extras { padding-block: clamp(20px, 4vw, 40px) clamp(32px, 6vw, 64px); }

.inn-steps {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 4px;
    list-style: none;
    margin: 0 0 clamp(20px, 3vw, 32px);
    padding: 0;
    counter-reset: inn-step;
    font-size: .78rem;
}
.inn-steps li {
    display: flex;
    align-items: center;
    gap: 8px;
    counter-increment: inn-step;
    color: var(--inn-ink-faint);
}
.inn-steps li::before {
    content: counter(inn-step);
    display: grid;
    place-items: center;
    width: 22px; height: 22px;
    border-radius: 50%;
    border: 1px solid currentColor;
    font-size: .7rem;
    font-weight: 700;
}
.inn-steps li + li::after { content: none; }
.inn-steps li:not(:last-child) { padding-right: 18px; position: relative; }
.inn-steps li:not(:last-child)::after {
    content: "";
    position: absolute;
    right: 6px;
    width: 8px; height: 1px;
    background: var(--inn-line-strong);
}
.inn-steps li.is-done { color: var(--inn-brand); }
.inn-steps li.is-done::before { content: "✓"; background: var(--inn-brand); border-color: var(--inn-brand); color: #fff; }
.inn-steps li.is-current { color: var(--inn-ink); font-weight: 600; }
.inn-steps li.is-current::before { border-color: var(--inn-accent); color: var(--inn-accent); }

/* Confirmed-stay bar --------------------------------------------------- */

.inn-held {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: clamp(18px, 3vw, 28px);
    margin-bottom: clamp(28px, 5vw, 48px);
    background: var(--inn-brand-soft);
    border-radius: var(--inn-radius);
    border-left: 3px solid var(--inn-accent);
}

.inn-held-title { margin: 0 0 8px; font-size: clamp(1.4rem, 1.2rem + .8vw, 2rem); text-transform: uppercase; }

.inn-held-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 0;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: .9rem;
    color: var(--inn-ink-soft);
}
.inn-held-facts li { display: flex; align-items: center; }
.inn-held-facts li + li::before {
    content: "";
    flex: none;
    width: 3px; height: 3px;
    border-radius: 50%;
    background: var(--inn-accent);
    margin: 0 12px;
}

.inn-held-total { margin: 0; text-align: right; }
.inn-held-total-label { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .1em; color: var(--inn-ink-faint); }
.inn-held-total-value { font-family: var(--inn-font-display); font-size: 1.9rem; font-weight: 600; color: var(--inn-brand); }

/* Offer sections --------------------------------------------------------- */

/* Two buttons, each opening the offer under it. They start closed so the
   step is a choice. Both may be open at once: a voucher and a product are
   not alternatives. The chevron is drawn, not typed, so it does not join the
   button's accessible name — aria-expanded already says whether it is open. */
.inn-addons { display: grid; gap: 12px; }

.inn-addon-toggle.inn-addon-toggle {
    justify-content: space-between;
    text-align: left;
}
.inn-addon-toggle.inn-addon-toggle::after {
    content: "";
    flex: none;
    width: 8px;
    height: 8px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    margin-top: -4px;
}
.inn-addon-toggle.inn-addon-toggle[aria-expanded="true"] {
    border-color: var(--inn-brand);
}
.inn-addon-toggle.inn-addon-toggle[aria-expanded="true"]::after {
    transform: rotate(225deg);
    margin-top: 2px;
}

.inn-addon-panel { padding-top: clamp(16px, 3vw, 28px); }
.inn-addon-panel .inn-offer { margin-bottom: 0; }

.inn-offer { margin-bottom: clamp(28px, 5vw, 48px); }

.inn-offer-head { text-align: center; margin-bottom: clamp(20px, 3vw, 32px); }

.inn-offer-title {
    margin: 0 0 .35em;
    font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.4rem);
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: .02em;
}

.inn-offer-sub { margin: 0; color: var(--inn-ink-soft); font-size: 1rem; }
.inn-offer-empty { text-align: center; color: var(--inn-ink-faint); }

.inn-offer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
    gap: 16px;
}

.inn-mini {
    display: flex;
    flex-direction: column;
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    overflow: hidden;
    transition: border-color .2s ease, box-shadow .2s ease;
}
.inn-mini.inn-mini:hover,
.inn-mini.inn-mini:focus-within { border-color: var(--inn-line-strong); box-shadow: var(--inn-shadow-sm); }
.inn-mini.is-in-cart { border-color: var(--inn-brand); }

.inn-mini-media { aspect-ratio: 1; background: var(--inn-sand); position: relative; }
.inn-mini-media img { width: 100%; height: 100%; object-fit: cover; }
.inn-mini-noimage {
    position: absolute; inset: 0;
    display: grid; place-items: center;
    font-family: var(--inn-font-display);
    font-size: 2rem;
    color: var(--inn-accent);
}

.inn-mini-body { display: flex; flex-direction: column; gap: 6px; flex: 1; padding: 12px 14px 14px; }
.inn-mini-name { margin: 0; font-size: .98rem; line-height: 1.25; }
.inn-mini-desc { margin: 0; font-size: .8rem; color: var(--inn-ink-soft); line-height: 1.45; }
.inn-mini-price { margin: 2px 0 8px; font-family: var(--inn-font-display); font-size: 1.05rem; font-weight: 600; }
.inn-mini-buy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    margin-top: auto;
}
.inn-mini-buy .inn-sf-btn { align-self: stretch; }
.inn-mini-buy .inn-prod-incart { align-self: stretch; }

/* --------------------------------------------------------------------------
   13. Voucher
   -------------------------------------------------------------------------- */

.inn-voucher-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(300px, .9fr);
    gap: clamp(24px, 4vw, 44px);
    align-items: start;
}
@media (max-width: 860px) {
    .inn-voucher-layout { grid-template-columns: 1fr; }
}

.inn-voucher-preview { position: sticky; top: 24px; }
@media (max-width: 860px) { .inn-voucher-preview { position: static; } }

/* The artwork itself ----------------------------------------------------- */

.inn-voucher {
    position: relative;
    aspect-ratio: 1.62 / 1;
    padding: 10px;
    border-radius: var(--inn-radius);
    background:
        radial-gradient(120% 90% at 20% 0%, #24406F 0%, rgba(36,64,111,0) 60%),
        linear-gradient(150deg, #1B2F55 0%, #101D38 100%);
    box-shadow: var(--inn-shadow-lg);
    color: #fff;
    overflow: hidden;
}

.inn-voucher-frame {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(4px, 1vw, 10px);
    height: 100%;
    padding: clamp(14px, 3vw, 26px);
    border: 1px solid rgba(184, 148, 90, .55);
    border-radius: 2px;
    text-align: center;
}

.inn-voucher-motif {
    position: absolute;
    left: 0; right: 0; bottom: -14%;
    width: 100%;
    height: auto;
    color: var(--inn-accent);
    /* Faint enough to read as watermark rather than compete with the code
       and terms that sit over it. */
    opacity: .14;
    z-index: 0;
}

.inn-voucher-head { margin-bottom: auto; }
.inn-voucher-brand {
    margin: 0;
    font-family: var(--inn-font-display);
    font-size: clamp(1rem, .8rem + 1vw, 1.5rem);
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--inn-accent);
}
.inn-voucher-place {
    margin: 2px 0 0;
    font-size: clamp(.56rem, .5rem + .3vw, .7rem);
    letter-spacing: .34em;
    text-transform: uppercase;
    color: rgba(255,255,255,.66);
}

.inn-voucher-kind {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    font-family: var(--inn-font-display);
    font-size: clamp(.62rem, .55rem + .3vw, .78rem);
    letter-spacing: .3em;
    text-transform: uppercase;
    color: rgba(255,255,255,.8);
}
.inn-voucher-rule { width: clamp(18px, 4vw, 34px); height: 1px; background: rgba(184,148,90,.7); }

.inn-voucher-amount {
    margin: 0;
    min-height: 1.1em;
    font-family: var(--inn-font-display);
    font-size: clamp(2rem, 1.2rem + 4.4vw, 3.6rem);
    font-weight: 600;
    line-height: 1;
    letter-spacing: .01em;
    color: #fff;
    transition: opacity .15s ease;
}
/* Before an amount is chosen the card shows a ruled blank, like a real one. */
.inn-voucher-amount.is-blank::after {
    content: "";
    display: block;
    width: clamp(120px, 34%, 220px);
    height: 1px;
    margin: .55em auto 0;
    background: rgba(255,255,255,.35);
}

.inn-voucher-to { display: flex; align-items: baseline; gap: 8px; font-size: clamp(.62rem, .55rem + .3vw, .78rem); }
.inn-voucher-label { letter-spacing: .2em; text-transform: uppercase; color: rgba(255,255,255,.55); }
.inn-voucher-name { color: #fff; border-bottom: 1px solid rgba(255,255,255,.25); min-width: 90px; }

.inn-voucher-message {
    margin: 0;
    max-width: 84%;
    font-size: clamp(.62rem, .55rem + .3vw, .8rem);
    font-style: italic;
    color: rgba(255,255,255,.78);
    line-height: 1.4;
}

.inn-voucher-foot {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 3px;
    width: 100%;
}
.inn-voucher-code {
    font-family: var(--inn-font-display);
    font-size: clamp(.66rem, .58rem + .3vw, .84rem);
    letter-spacing: .22em;
    color: var(--inn-accent);
}
.inn-voucher-code.is-masked { opacity: .6; }
.inn-voucher-terms {
    font-size: clamp(.5rem, .45rem + .25vw, .62rem);
    letter-spacing: .1em;
    text-transform: uppercase;
    color: rgba(255,255,255,.45);
}

/* Voucher form ----------------------------------------------------------- */

.inn-voucher-form { display: grid; gap: 16px; }

.inn-vf-presets { border: 0; margin: 0; padding: 0; display: grid; gap: 10px; }
.inn-vf-chips { display: flex; flex-wrap: wrap; gap: 8px; }

.inn-vf-chip {
    padding: 9px 16px;
    border: 1px solid var(--inn-line-strong);
    border-radius: var(--inn-radius-pill);
    background: var(--inn-surface);
    color: var(--inn-ink);
    font-family: var(--inn-font-body);
    font-size: .88rem;
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease, color .16s ease;
}
/* A STATE THAT PAINTS A FILL HAS TO SAY WHAT THE TEXT DOES. The doubled class
   wins the cream fill back from the kit — and then the kit's own
   `button:hover { color }` took the letters, because nothing here had claimed
   them, and R 500 went white on cream. Half a state is worse than none: the
   resting chip was legible and the one under the cursor was not.
   Third time for this exact shape; the dialog's close button and the quantity
   stepper each carry an older, local copy of this note. */
.inn-vf-chip.inn-vf-chip:hover,
.inn-vf-chip.inn-vf-chip:focus-visible { border-color: var(--inn-accent); background: var(--inn-accent-soft); color: var(--inn-ink); }
.inn-vf-chip.inn-vf-chip:active { border-color: var(--inn-accent-dark); background: var(--inn-accent-soft); color: var(--inn-ink); }
/* Last word, as on the tab bar: the chosen amount stays the chosen amount while
   the cursor is on it. These are radio buttons in disguise. */
.inn-vf-chip.inn-vf-chip.is-active,
.inn-vf-chip.inn-vf-chip.is-active:hover,
.inn-vf-chip.inn-vf-chip.is-active:focus-visible { background: var(--inn-brand); border-color: var(--inn-brand); color: #fff; }
.inn-vf-chip.inn-vf-chip.is-active:active { background: var(--inn-brand-dark); border-color: var(--inn-brand-dark); color: #fff; }

.inn-vf-amount { position: relative; display: block; }
.inn-vf-amount .inn-sf-input { padding-left: 34px; font-size: 1.1rem; font-weight: 600; }
.inn-vf-amount .inn-sf-input::placeholder { font-weight: 400; opacity: .7; }
.inn-vf-currency {
    position: absolute;
    left: 14px; top: 50%;
    transform: translateY(-50%);
    color: var(--inn-ink-faint);
    font-size: 1rem;
    pointer-events: none;
}

.inn-vf-hint { margin: 0; font-size: .78rem; color: var(--inn-ink-faint); }
.inn-vf-optional { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--inn-ink-faint); }
.inn-vf-message { min-height: 62px; resize: vertical; line-height: 1.5; }

.inn-vf-check { grid-template-columns: auto 1fr; padding-inline: 0; }
.inn-vf-email { display: grid; gap: 8px; padding: 14px; background: var(--inn-canvas); border-radius: var(--inn-radius-sm); }

.inn-vf-error {
    margin: 0;
    padding: 10px 14px;
    background: var(--inn-negative-soft);
    color: var(--inn-negative);
    border-radius: var(--inn-radius-sm);
    font-size: .85rem;
}

.inn-vf-added {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 0;
    padding: 10px 10px 10px 14px;
    background: var(--inn-positive-soft);
    color: var(--inn-positive);
    border-radius: var(--inn-radius-sm);
    font-size: .88rem;
}
.inn-vf-added .inn-incart-remove { color: var(--inn-positive); }
.inn-vf-added .inn-incart-remove.inn-incart-remove:hover { background: rgba(31,107,78,.14); color: var(--inn-positive); }
.inn-vf-added .inn-incart-remove.inn-incart-remove:active { background: rgba(31,107,78,.24); color: var(--inn-positive); }

/* Footer ----------------------------------------------------------------- */

.inn-extras-foot {
    max-width: 460px;
    margin: clamp(28px, 5vw, 48px) auto 0;
    text-align: center;
}
.inn-extras-note { margin: 0 0 12px; font-size: .82rem; color: var(--inn-ink-faint); }

/* --------------------------------------------------------------------------
   14. Voucher denominations
   -------------------------------------------------------------------------- */

/* The amount is no longer typed. A voucher is real CiMSO stock and Issue
   Voucher carries no amount, so the only values that can be sold are the ones
   staff already created — the chips are the whole control, and one of them is
   always chosen. */

.inn-vf-chip {
    /* The chip carries a tick beside its amount when it is chosen, so it lays
       its own children out. The transition list repeats the three the chip
       already had because box-shadow joins them for the selected ring. */
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    transition: border-color .16s ease, background .16s ease, color .16s ease, box-shadow .16s ease;
}

/* Selection cannot rest on the accent alone: these are radio buttons in
   disguise, and somebody who cannot separate navy from white still has to see
   which amount they are buying. So the chosen chip gains a tick, heavier
   letterforms and a ring drawn inside its own border — three signals that all
   survive greyscale and a re-skin. */
.inn-vf-chip.is-active {
    font-weight: 700;
    box-shadow: inset 0 0 0 2px var(--inn-surface), 0 0 0 1px var(--inn-brand);
}

/* The tick is drawn, not typed. Generated text is folded into a control's
   accessible name in most engines, so a "✓" here would have the chip announce
   its own tick on top of the aria-checked the script already sets. A shape
   says it to the eye and nothing at all to a screen reader. */
.inn-vf-chip.is-active::before {
    content: "";
    flex: none;
    align-self: center;
    width: 9px; height: 5px;
    margin-top: -2px;
    border-left: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(-45deg);
}

/* The small print under the add button — that vouchers are not refundable, and
   what happens next. It belongs before the click, not on the thank-you page. */
.inn-vf-note {
    margin: 0;
    font-size: .78rem;
    line-height: 1.5;
    color: var(--inn-ink-faint);
    text-align: center;
}

@media (prefers-reduced-motion: reduce) {
    .inn-vf-chip { transition: none; }
}

/* --------------------------------------------------------------------------
   15. Guest registration
   -------------------------------------------------------------------------- */

/* This is the one screen on the storefront that is pure paperwork, and it is
   reached after the money has already moved. Nothing here is a gate: every
   affordance should read as "when you have a moment", never as "before you may
   arrive".

   Two views share these rules. .inn-reg--hub is what the person who paid sees:
   a card for each guest on the booking. .inn-reg--guest is the page somebody
   reaches from their own link, which is nothing but the form. */

.inn-reg {
    /* Narrower than the rest of the storefront. Filling in an address and a
       next of kin is reading and typing, not browsing — at the full 1240px
       measure a two-column field grid sprawls and the eye loses the label it
       was working down. */
    max-width: 920px;
    padding-block: clamp(20px, 4vw, 40px) clamp(32px, 6vw, 64px);
}

/* The stay itself, restated and read-only. It is here to reassure — "yes, this
   is the booking you paid for" — so it is a band rather than a card, and
   nothing in it can be edited. */
.inn-reg-stay {
    padding: clamp(14px, 2.4vw, 20px) clamp(16px, 3vw, 24px);
    margin: 0 0 clamp(20px, 4vw, 32px);
    background: var(--inn-brand-soft);
    border-left: 3px solid var(--inn-accent);
    border-radius: 0 var(--inn-radius-sm) var(--inn-radius-sm) 0;
    color: var(--inn-ink-soft);
    font-size: .92rem;
    line-height: 1.5;
}
.inn-reg-stay p { margin: 0; }
.inn-reg-stay p + p { margin-top: .4em; }

/* A booking can hold more than one unit, and two stays run together into
   nonsense without a rule between them. */
.inn-reg-stay-item + .inn-reg-stay-item {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--inn-line-strong);
}

.inn-reg-stay-title {
    margin: 0 0 4px;
    font-size: 1.05rem;
    color: var(--inn-ink);
}

/* The band itself stays a block. Only the list of facts inside it lays out in a
   row — a flex container drops the whitespace between its children, which
   would turn a summary written as a sentence into one long word. */
.inn-reg-stay-facts,
.inn-reg-stay dl {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 28px;
    list-style: none;
    margin: 0;
    padding: 0;
}
.inn-reg-stay strong { color: var(--inn-ink); }

/* Guest cards ------------------------------------------------------------ */

/* One card per guest, stacked. A card is a heading row, then whichever of the
   panels below it apply — the invitation, the copied link, the form itself —
   so it is a stack and not a row, and every panel appears and disappears under
   the name it belongs to. */
.inn-reg-list{
    display: grid;
    gap: 12px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.inn-reg-card {
    display: grid;
    gap: 14px;
    padding: clamp(14px, 2.2vw, 20px) clamp(16px, 2.6vw, 22px);
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.inn-reg-card.inn-reg-card:hover,
.inn-reg-card.inn-reg-card:focus-within { border-color: var(--inn-line-strong); }

/* The open card is the one being worked on, and on a booking of four it needs
   to be findable after a scroll. Deliberately nothing for .is-done: a completed
   form can still be reviewed and changed, so receding it would suggest a door
   that has closed. */
.inn-reg-card.is-open { border-color: var(--inn-line-strong); box-shadow: var(--inn-shadow-sm); }

.inn-reg-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 20px;
}

.inn-reg-card-who{ flex: 1 1 240px; min-width: 0; }

.inn-reg-card-name {
    margin: 0;
    font-size: 1.12rem;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

/* A guest whose name we never captured still gets a card, so this line —
   "Adult — you", "Child" — is often the only thing identifying the slot. */
.inn-reg-card-kind{
    margin: 4px 0 0;
    padding: 0;
    font-size: .84rem;
    line-height: 1.5;
    color: var(--inn-ink-soft);
}

.inn-reg-card-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

@media (max-width: 520px) {
    .inn-reg-card-actions .inn-sf-btn { flex: 1 1 100%; }
}

/* Status ----------------------------------------------------------------- */

/* Each state carries its own marker as well as its own colour — a hollow ring
   for nothing yet, a filled dot for sent, a tick for done — so the three are
   still three when the page is printed in black and white. */
.inn-reg-chip{
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 0;
    padding: 5px 12px 5px 10px;
    border: 1px solid transparent;
    border-radius: var(--inn-radius-pill);
    font-family: var(--inn-font-display);
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    white-space: nowrap;
}
.inn-reg-chip::before{
    content: "";
    flex: none;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: currentColor;
}

.inn-reg-chip--todo{
    background: var(--inn-canvas);
    border-color: var(--inn-line-strong);
    color: var(--inn-ink-soft);
}
.inn-reg-chip--todo::before{ background: none; box-shadow: inset 0 0 0 2px currentColor; }

.inn-reg-chip--sent{ background: var(--inn-notice-soft); color: var(--inn-notice); }

.inn-reg-chip--done{ background: var(--inn-positive-soft); color: var(--inn-positive); }
/* Drawn rather than typed, for the same reason the voucher chip's tick is:
   generated text joins the accessible name, and the word beside it already
   says "Completed". */
.inn-reg-chip--done::before{
    width: 9px; height: 5px;
    margin-top: -3px;
    border-radius: 0;
    background: none;
    border-left: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(-45deg);
}

/* POPIA, in one sentence. A guest who opened their own link and typed their
   own ID number did not hand it to whoever paid for the room, so the booker
   gets the fact and never the answers — this line has to explain that without
   sounding like a refusal, which is why it is a quiet aside and not a notice. */
.inn-reg-private {
    margin: 0;
    padding: 10px 14px;
    background: var(--inn-canvas);
    border-left: 2px solid var(--inn-line-strong);
    border-radius: 0 var(--inn-radius-sm) var(--inn-radius-sm) 0;
    color: var(--inn-ink-soft);
    font-size: .82rem;
    line-height: 1.5;
}

/* Inviting a guest to fill in their own ------------------------------------ */

/* Both panels open under the buttons that ask for them, so they read as part of
   the card rather than as a dialogue that has taken it over. */
.inn-reg-invite,
.inn-reg-copy {
    display: grid;
    gap: 10px;
    padding: 14px 16px;
    background: var(--inn-canvas);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius-sm);
}

/* Name and address side by side once there is room for both, stacked on a
   phone. Two fields where there was one is otherwise a taller panel for the
   same job, and this panel opens inside a card that is already dense. The
   error paragraph and the footer keep the full width, so a failure is never
   squeezed into half a column. */
@media (min-width: 560px) {
    .inn-reg-invite {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: 14px;
    }
    .inn-reg-invite > .inn-vf-error,
    .inn-reg-invite > .inn-reg-invite-foot {
        grid-column: 1 / -1;
    }
}

.inn-reg-invite-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
/* The note is the reassurance and the button is the commitment, so the note
   takes the room and the button never shrinks to fit beside it. */
.inn-reg-invite-foot .inn-reg-hint { flex: 1 1 260px; }
.inn-reg-invite-foot .inn-sf-btn { flex: 0 0 auto; }

@media (max-width: 520px) {
    .inn-reg-invite-foot .inn-sf-btn { flex: 1 1 100%; }
}

/* A URL is not prose. Smaller and tabular so the whole of it is on screen to be
   selected, which is the only thing this field is for. */
.inn-reg-copylink {
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
}

.inn-reg-hint {
    margin: 0;
    font-size: .8rem;
    line-height: 1.5;
    color: var(--inn-ink-faint);
}

/* The form opens inside the card, so it needs a line above it — without one the
   first fieldset reads as another panel of the card rather than as the thing
   the button just opened. */
.inn-reg-formwrap {
    margin-top: 2px;
    padding-top: 16px;
    border-top: 1px solid var(--inn-line);
}

/* The guest's own page is nothing but the form. The card chrome around it would
   be a box drawn around a page, with the fieldsets boxed again inside it. */
.inn-reg--guest .inn-reg-card {
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}
.inn-reg--guest .inn-reg-formwrap {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

/* The form --------------------------------------------------------------- */

.inn-reg-form { display: grid; gap: clamp(18px, 3vw, 28px); }

.inn-reg-group {
    /* A fieldset defaults to min-width: min-content, which stops the field grid
       inside it from ever shrinking and pushes the whole page sideways on a
       phone. This one line is the entire fix. */
    min-inline-size: 0;
    margin: 0;
    padding: clamp(18px, 2.6vw, 26px);
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
}

.inn-reg-group-title {
    /* This is a <legend>: the UA's own inline padding would otherwise indent it
       out of line with the fields below. */
    padding-inline: 0;
    margin: 0 0 6px;
    font-family: var(--inn-font-display);
    font-weight: var(--inn-display-weight);
    font-size: clamp(1.05rem, 1rem + .35vw, 1.3rem);
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--inn-ink);
}

.inn-reg-group-note {
    margin: 0 0 18px;
    max-width: 62ch;
    font-size: .86rem;
    line-height: 1.55;
    color: var(--inn-ink-soft);
}

/* A group with no explanatory note still needs air under its title. */
.inn-reg-group-title + .inn-reg-fields{ margin-top: 18px; }

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

/* Two columns of labelled inputs stop being readable long before the viewport
   does — a street address next to a postal code is a thumb-typing trap. */
@media (max-width: 640px) {
    .inn-reg-fields { grid-template-columns: 1fr; }
}

/* Anything with room to write in takes the full measure; a two-column box is
   too short to see what you have already typed. */
.inn-reg-field--textarea { grid-column: 1 / -1; }

.inn-reg-textarea {
    min-height: 92px;
    resize: vertical;
    line-height: 1.5;
}

/* Help text under a field: the schema attaches it to the fields that need
   reassuring, such as why we want an ID number at all. */
.inn-reg-help {
    margin: 0;
    font-size: .78rem;
    line-height: 1.45;
    color: var(--inn-ink-faint);
}

/* The checkbox primitive is built for the four-column filter rows. Here there
   is only a box and a sentence, and the sentence runs to two or three lines, so
   the box sits with its first line rather than floating in the middle. */
.inn-reg-check {
    grid-template-columns: auto 1fr;
    align-items: start;
    padding-inline: 0;
}
.inn-reg-check .inn-check-box { margin-top: 2px; }
.inn-reg-check .inn-check-label { font-size: .88rem; line-height: 1.5; }

.inn-reg-group--consent .inn-check + .inn-check { margin-top: 2px; }

/* Waiver ----------------------------------------------------------------- */

/* Every child of the indemnity fieldset is a step in one sequence — read this,
   accept it, sign it — so they are spaced by the same rhythm rather than each
   carrying its own margin. */
.inn-reg-group--waiver > * + * { margin-top: 12px; }

/* The Hydro supply the wording, and it can be long. Left to run it would push
   the accept box and the save button clean off the screen, so it scrolls in
   place — the reader can still get to the end, and the shape of the form does
   not change when the wording does. Printing undoes this; see the print rules. */
.inn-reg-waiver {
    max-height: 220px;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 16px 18px;
    background: var(--inn-canvas);
    border: 1px solid var(--inn-line-strong);
    border-radius: var(--inn-radius-sm);
    color: var(--inn-ink-soft);
    font-size: .86rem;
    line-height: 1.65;
}
.inn-reg-waiver :where(p, li) { margin: 0 0 .85em; }
.inn-reg-waiver :where(ul, ol) { margin: 0 0 .85em; padding-left: 1.3em; }
.inn-reg-waiver :where(h2, h3, h4) {
    margin: 1.3em 0 .5em;
    font-size: .9rem;
    letter-spacing: .06em;
    text-transform: uppercase;
}
.inn-reg-waiver > :first-child { margin-top: 0; }
.inn-reg-waiver > :last-child { margin-bottom: 0; }
/* The box carries a tabindex so it can be scrolled from the keyboard, which
   makes it focusable without being a control — the one place on this page the
   global focus ring has to be asked for by name. */
.inn-reg-waiver.inn-reg-waiver:focus-visible { outline: 2px solid var(--inn-brand); outline-offset: 3px; }

/* Signature -------------------------------------------------------------- */

.inn-reg-sign { display: grid; gap: 10px; }

/* Clear sits under its own pad and hard against the right, where it is out of
   the way of a hand drawing but unmistakably about this box. Overlaying it on
   the pad would put a button inside the drawing surface. */
.inn-reg-pad {
    display: grid;
    justify-items: end;
    gap: 8px;
}

.inn-reg-canvas {
    display: block;
    width: 100%;
    height: 180px;
    /* The script reads this to ink the stroke, so the signature is drawn in the
       same colour as everything else on the page and follows a re-skin. */
    color: var(--inn-ink);
    background-color: var(--inn-surface);
    /* The line to sign on is a background, not pixels in the canvas: clearing
       the signature is then one clearRect and the rule is still there. */
    background-image: linear-gradient(var(--inn-line-strong), var(--inn-line-strong));
    background-repeat: no-repeat;
    background-size: calc(100% - 48px) 1px;
    background-position: 24px calc(100% - 44px);
    border: 1px dashed var(--inn-line-strong);
    border-radius: var(--inn-radius-sm);
    cursor: crosshair;
    /* Without this a finger drag is claimed by the page as a scroll and the
       stroke never reaches the canvas — the pad is unusable on a phone, which
       is where most of these forms get filled in. */
    touch-action: none;
}
.inn-reg-canvas.inn-reg-canvas:focus-visible { outline: 2px solid var(--inn-brand); outline-offset: 3px; }

/* Actions and feedback --------------------------------------------------- */

/* A stack, not a row: the save button is full width, and the sentence above it
   is the last thing we want read before it is pressed. */
.inn-reg-actions {
    display: grid;
    gap: 12px;
}

@media (max-width: 520px) {
}

/* The live region wrapper. It has no box of its own — what goes into it is an
   error or a confirmation, both of which already carry one — and while both of
   those are hidden it must take up no room, or the form ends on a coloured
   band that says nothing. */
.inn-reg-alerts { display: grid; gap: 10px; }

/* The last word before the button, and the whole point of this screen: none of
   this is compulsory and the booking does not depend on it. */
.inn-reg-note {
    margin: 0;
    font-size: .8rem;
    line-height: 1.5;
    color: var(--inn-ink-faint);
}

/* Field-level error state ------------------------------------------------ */

/* The ring is the point. Only the title is compulsory, so an error here is
   rare and specific, and it must be findable by somebody scrolling a long form
   who cannot see that the border went red. */
/* (0,3,0), so this beats the resting control at (0,2,0) whatever order the
   two rules end up in. The old .inn-sf-input.is-error was (0,2,0) and only
   won because it came later. */
.inn-sf-input.inn-sf-input.is-error,
.inn-sf-select.inn-sf-select.is-error {
    border-color: var(--inn-negative);
    box-shadow: 0 0 0 3px var(--inn-negative-soft);
}

/* Focused and in error at once. If the error ring simply stayed, focus would
   become invisible on exactly the field the script has just jumped to — so the
   negative edge holds the error and the brand halo outside it holds the focus,
   and the two are legible together. */
.inn-sf-input.inn-sf-input.is-error:focus,
.inn-sf-select.inn-sf-select.is-error:focus {
    border-color: var(--inn-negative);
    background-color: var(--inn-surface);
    color: var(--inn-ink);
    box-shadow: 0 0 0 1px var(--inn-negative), 0 0 0 4px var(--inn-brand-soft);
}

/* The accept box is a real checkbox, visually hidden behind the drawn one, so
   an error mark on it lands somewhere nobody can see. The drawn box has to wear
   it instead — otherwise the one compulsory tick on the indemnity fails
   silently. */
.inn-check input.is-error + .inn-check-box {
    border-color: var(--inn-negative);
    box-shadow: 0 0 0 3px var(--inn-negative-soft);
}
.inn-check input.is-error:focus-visible + .inn-check-box {
    border-color: var(--inn-negative);
    box-shadow: 0 0 0 1px var(--inn-negative), 0 0 0 4px var(--inn-brand-soft);
}

@media (prefers-reduced-motion: reduce) {
    .inn-reg-card { transition: none; }
}

/* Printing --------------------------------------------------------------- */

/* Reception print these, and so do guests who would rather bring a signed page
   than trust a phone. What has to survive is the answers and the signature;
   everything that only exists to be clicked can go. */
@media print {
    .inn-sf .inn-reg { max-width: none; padding-block: 0; }

    .inn-sf .inn-reg-actions,
    .inn-sf .inn-reg-card-actions,
    .inn-sf .inn-reg-invite,
    .inn-sf .inn-reg-copy,
    .inn-sf .inn-reg-note,
    .inn-sf .inn-reg-hint { display: none; }

    /* Clear is the only control inside the signature pad, and a printed page
       has nothing to clear. */
    .inn-sf .inn-reg-pad .inn-sf-btn { display: none; }

    .inn-sf .inn-reg-form { gap: 14px; }

    /* Backgrounds and borders mostly do not print, and a group that breaks
       across a page loses its title with them. */
    .inn-sf .inn-reg-group {
        break-inside: avoid;
        padding: 0 0 10px;
        background: none;
        border: 0;
        border-bottom: 1px solid var(--inn-line-strong);
        border-radius: 0;
    }
    .inn-sf .inn-reg-card {
        break-inside: avoid;
        padding: 0;
        background: none;
        border: 0;
        box-shadow: none;
    }
    .inn-sf .inn-reg-formwrap { border-top: 0; padding-top: 0; }

    /* The whole waiver must be on the page — a scroll box prints as its first
       220px and the rest of what somebody agreed to simply vanishes. */
    .inn-sf .inn-reg-waiver {
        max-height: none;
        overflow: visible;
        padding-inline: 0;
        background: none;
        border: 0;
    }

    /* The dashed frame is screen furniture. A single ruled line under the
       signature is what a signed page actually looks like, and a border prints
       where a background image does not. */
    .inn-sf .inn-reg-canvas {
        height: 120px;
        background-image: none;
        border: 0;
        border-bottom: 1px solid var(--inn-ink);
        border-radius: 0;
    }

    .inn-sf .inn-reg-stay {
        background: none;
        border-left: 0;
        padding-inline: 0;
    }

    /* Tinted pills go white on paper, so the state has to be spelt out by its
       outline and its marker instead. */
    .inn-sf .inn-reg-chip{
        background: none;
        border-color: var(--inn-ink-faint);
        color: var(--inn-ink);
    }

    .inn-sf .inn-reg .inn-sf-input.inn-sf-input,
    .inn-sf .inn-reg .inn-sf-select.inn-sf-select {
        background: none;
        background-image: none;
        color: var(--inn-ink);
        border-color: var(--inn-line-strong);
    }
}

/* ---- 17. The arrival-details panel on the WooCommerce order pages ---- */

/* This one block lands inside WooCommerce's own templates rather than on a
   storefront page, so it carries .inn-sf itself to pick up the tokens and then
   deliberately drops the page-level width and rhythm — it is a note inside
   somebody else's layout, not a page of ours. */
.inn-sf.inn-reg--panel {
    max-width: none;
    margin: 24px 0;
    padding: 0;
}

.inn-sf.inn-reg--panel .inn-sf-notice p { margin: 0 0 10px; }
.inn-sf.inn-reg--panel .inn-sf-notice p:last-child { margin-bottom: 0; }

/* ---- 18. Treatment packages ---- */

/* The page is two steps that swap places rather than two pages, so the room
   step inherits the page's own width and rhythm. */
.inn-sf.inn-pkg {
    max-width: var(--inn-maxw);
    margin-inline: auto;
}

.inn-pkg-step + .inn-pkg-step { margin-top: 0; }

.inn-pkg-step-title {
    margin: 0 0 6px;
    font-family: var(--inn-font-display);
    font-weight: var(--inn-display-weight);
    font-size: clamp(1.3rem, 3vw, 1.75rem);
    color: var(--inn-ink);
    letter-spacing: var(--inn-display-space);
}

/* The heading is focused when a package is chosen, so it needs a focus ring
   even though it is not a control — otherwise the move between steps is
   invisible to anybody navigating by keyboard. */
.inn-pkg-step-title.inn-pkg-step-title:focus-visible {
    outline: 2px solid var(--inn-brand);
    outline-offset: 4px;
}

.inn-pkg-invite {
    margin: 0 0 20px;
}

.inn-pkg-invite.inn-pkg-invite a {
    color: var(--inn-brand);
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: color .16s ease;
}
.inn-pkg-invite.inn-pkg-invite a:hover,
.inn-pkg-invite.inn-pkg-invite a:focus-visible { color: var(--inn-brand-dark); }
.inn-pkg-invite.inn-pkg-invite a:active { color: var(--inn-accent-dark); }

/* -- the package cards -- */

.inn-pkg-grid {
    display: grid;
    gap: 20px;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    margin-top: 20px;
}

/* A card is a whole proposition — nights, treatments and a price — so it is
   read top to bottom and its button sits on the floor of the card however
   uneven the treatment lists are. */
.inn-pkg-card {
    display: flex;
    flex-direction: column;
    padding: 22px 22px 18px;
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    box-shadow: var(--inn-shadow-sm);
}

.inn-pkg-card-head { margin-bottom: 10px; }

.inn-pkg-card-name {
    margin: 0;
    font-family: var(--inn-font-display);
    font-weight: var(--inn-display-weight);
    font-size: 1.15rem;
    line-height: 1.25;
    color: var(--inn-ink);
}

.inn-pkg-card-nights {
    margin: 4px 0 0;
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--inn-accent-dark);
}

.inn-pkg-card-blurb {
    margin: 0 0 14px;
    font-size: .94rem;
    line-height: 1.55;
    color: var(--inn-ink-soft);
}

.inn-pkg-card-treatments {
    margin: 0 0 10px;
    padding: 0;
    list-style: none;
    font-size: .9rem;
    line-height: 1.5;
    color: var(--inn-ink);
}

.inn-pkg-card-treatments li {
    position: relative;
    padding-left: 16px;
}

.inn-pkg-card-treatments li::before {
    content: "";
    position: absolute;
    left: 0;
    top: .62em;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--inn-accent);
}

/* The one thing a treatment list must not imply is a booked time. It is said
   here, on the room step, in the basket and in the confirmation — four places,
   because being wrong about it costs a guest their afternoon. */
.inn-pkg-card-note {
    margin: 0 0 16px;
    font-size: .8rem;
    line-height: 1.45;
    color: var(--inn-ink-faint);
}

.inn-pkg-card-foot {
    margin-top: auto;
    padding-top: 14px;
    border-top: 1px solid var(--inn-line);
}

.inn-pkg-card-price {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px;
    margin: 0 0 12px;
}

.inn-pkg-card-from,
.inn-pkg-card-per {
    font-size: .76rem;
    color: var(--inn-ink-faint);
}

.inn-pkg-card-amount {
    font-family: var(--inn-font-display);
    font-size: 1.35rem;
    font-weight: var(--inn-display-weight);
    color: var(--inn-ink);
}

/* -- the room step -- */

.inn-pkg-back { margin-bottom: 14px; }

.inn-pkg-chosen {
    margin: 14px 0 22px;
    padding: 18px 20px;
    background: var(--inn-sand);
    border-radius: var(--inn-radius);
}

.inn-pkg-chosen-nights {
    margin: 0 0 8px;
    font-size: .9rem;
    font-weight: 600;
    color: var(--inn-ink);
}

.inn-pkg-chosen-treatments {
    margin: 0 0 14px;
    padding-left: 18px;
    font-size: .92rem;
    line-height: 1.55;
    color: var(--inn-ink-soft);
}

.inn-pkg-fields {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    align-items: end;
    margin-bottom: 10px;
}

/* Not an input: the departure day is a consequence of the package's length,
   so it is shown rather than asked for. It still sits on the field baseline so
   the row does not look broken. */
.inn-pkg-leaving-value {
    margin: 0;
    min-height: 46px;
    display: flex;
    align-items: center;
    font-size: .95rem;
    font-weight: 600;
    color: var(--inn-ink);
}

.inn-pkg-hint {
    margin: 0 0 16px;
    font-size: .82rem;
    line-height: 1.5;
    color: var(--inn-ink-faint);
}

.inn-pkg-rooms { margin-top: 26px; }

.inn-pkg-rooms-head {
    margin: 0 0 14px;
    font-size: .92rem;
    color: var(--inn-ink-soft);
}

.inn-pkg-rooms-grid {
    display: grid;
    gap: 18px;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

.inn-pkg-room {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--inn-surface);
    border: 1px solid var(--inn-line);
    border-radius: var(--inn-radius);
    box-shadow: var(--inn-shadow-sm);
}

.inn-pkg-room-image {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 2;
    max-width: 100%;
    object-fit: cover;
}

.inn-pkg-room-body {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 16px 18px 18px;
}

.inn-pkg-room-tier {
    margin: 0;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--inn-accent-dark);
}

.inn-pkg-room-name {
    margin: 0;
    font-family: var(--inn-font-display);
    font-size: 1.02rem;
    font-weight: var(--inn-display-weight);
    line-height: 1.3;
    color: var(--inn-ink);
}

.inn-pkg-room-price {
    margin: 6px 0 0;
    font-family: var(--inn-font-display);
    font-size: 1.2rem;
    font-weight: var(--inn-display-weight);
    color: var(--inn-ink);
}

.inn-pkg-room-per {
    margin: 0 0 10px;
    font-size: .78rem;
    color: var(--inn-ink-faint);
}

.inn-pkg-room-body .inn-sf-btn { margin-top: auto; }

@media (max-width: 640px) {
    .inn-pkg-fields { grid-template-columns: 1fr; }
    .inn-pkg-leaving-value { min-height: 0; }
}

/* A package is the sort of thing somebody prints to show somebody else, so
   the treatment list and the price survive and the controls go. */
@media print {
    .inn-sf .inn-pkg-back,
    .inn-sf .inn-pkg-card-foot .inn-sf-btn,
    .inn-sf .inn-pkg-form .inn-sf-btn,
    .inn-sf .inn-pkg-room-body .inn-sf-btn { display: none; }

    .inn-sf .inn-pkg-card,
    .inn-sf .inn-pkg-room {
        box-shadow: none;
        break-inside: avoid;
    }

    .inn-sf .inn-pkg-grid { grid-template-columns: repeat(2, 1fr); }
}
