/* ==========================================================================
   Kani Kawa — v2 booking flow
   The journey guests knew on inline.app (party size, date, then every branch
   with its open sessions), rebuilt in its own navy skin.
   Scoped to .v2-* so nothing here can reach the v1 booking form.
   ========================================================================== */

/* Availability colours. Red is this brand's accent and is used for what the
   guest has CHOSEN and for what they CANNOT have; green means the session is
   open. The site's palette has no green, so it is defined here — a functional
   colour, not a decorative one. */
:root {
    /* Soft terracotta: the one attention colour, legible on both brands' dark grounds. */
    --v2-alert: #e08a6a;
    /* Deep enough that the white time on it clears WCAG AA (4.6:1) — a brighter
       green looked better on a monitor and was 3.3:1, i.e. hard to read on a
       phone outdoors, which is where most of these bookings are made. */
    --v2-open:      #12873d;
    --v2-open-deep: #0f7a38;
    --v2-shut:      #e30613;
}

.v2-page { padding: 28px 0 80px; }
.v2-wrap { width: min(1120px, 92vw); margin: 0 auto; }

/* ---- brand header ---- */
.v2-banner {
    width: 100%;
    aspect-ratio: 1920 / 768;   /* the artwork's real shape; 1200/400 cropped it */
    background-size: cover;
    background-position: center;
    border-radius: 8px;
    overflow: hidden;
}
.v2-brand { padding: 22px 0 18px; border-bottom: 1px solid var(--sy-line); }
.v2-brand__row { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px; flex-wrap: wrap; }
.v2-brand__name { font-size: clamp(1.7rem, 4vw, 2.5rem); font-weight: 700; margin: 0; letter-spacing: 0.01em; }
.v2-brand__tag { margin: 6px 0 0; color: var(--sy-muted); font-size: 0.95rem; }
.v2-brand__back { color: var(--sy-muted); font-size: 0.88rem; display: inline-flex; align-items: center; gap: 7px; }
.v2-brand__back:hover { color: var(--sy-ink); }

/* ---- step 1: pickers ---- */
.v2-step-title { font-size: 1.32rem; font-weight: 700; margin: 30px 0 18px; }
.v2-pickers { display: grid; grid-template-columns: 1fr 1fr; gap: 20px 26px; align-items: end; }
.v2-picker-group { min-width: 0; }
.v2-picker-label { display: block; font-size: 0.95rem; font-weight: 600; margin-bottom: 9px; }
.v2-picker-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

.v2-field {
    position: relative;
    display: block;
    width: 100%;
}
.v2-field select,
.v2-field .v2-fakefield {
    width: 100%;
    appearance: none;
    -webkit-appearance: none;
    background: var(--sy-washi);
    border: 1px solid var(--sy-line);
    border-radius: 6px;
    color: var(--sy-ink);
    font-family: var(--sy-sans);
    font-size: 0.95rem;
    padding: 12px 40px 12px 14px;
    line-height: 1.4;
    cursor: pointer;
    text-align: left;
    transition: border-color 0.18s var(--sy-trans);
}
.v2-field select:focus,
.v2-field .v2-fakefield:focus-visible { outline: none; border-color: var(--sy-gold); }
.v2-field select:hover,
.v2-field .v2-fakefield:hover { border-color: rgba(255,255,255,0.3); }
.v2-field::after {
    content: "";
    position: absolute;
    right: 16px;
    top: 50%;
    width: 8px;
    height: 8px;
    margin-top: -6px;
    border-right: 2px solid var(--sy-muted);
    border-bottom: 2px solid var(--sy-muted);
    transform: rotate(45deg);
    pointer-events: none;
}
.v2-field.is-open::after { margin-top: -2px; transform: rotate(225deg); }
.v2-hint { color: var(--sy-muted); font-size: 0.85rem; margin: 14px 0 0; }

/* The standing "call us for a bigger party" line under the pickers. Deliberately
   quieter than the out-of-range prompt -- this is advice a guest may not need, that
   one is a guest who is stuck -- but the number itself is a link worth seeing. */
.v2-overflow-hint { margin: 14px 0 0; font-size: 0.88rem; line-height: 1.5; color: var(--sy-muted); }
.v2-overflow-hint a {
    color: var(--sy-gold);
    text-decoration: none;
    border-bottom: 1px solid rgba(216, 176, 102, 0.45);
    white-space: nowrap;
}
.v2-overflow-hint a:hover { color: var(--sy-gold-light); }

/* ---- step 1: the date calendar panel ---- */
.v2-cal {
    margin-top: 18px;
    border: 1px solid var(--sy-line);
    border-radius: 8px;
    background: var(--sy-washi);
    padding: 20px 22px 24px;
}
.v2-cal[hidden] { display: none !important; }
.v2-cal__months { display: grid; grid-template-columns: 1fr 1fr; gap: 34px; }
.v2-cal__month { min-width: 0; }
.v2-cal__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
.v2-cal__title { font-size: 1.05rem; font-weight: 700; text-align: center; flex: 1; }
.v2-cal__nav {
    background: transparent;
    border: 0;
    color: var(--sy-ink);
    font-size: 1.05rem;
    line-height: 1;
    padding: 6px 8px;
    cursor: pointer;
    border-radius: 4px;
}
.v2-cal__nav:disabled { opacity: 0.25; cursor: default; }
.v2-cal__nav:not(:disabled):hover { background: rgba(255,255,255,0.07); }
.v2-cal__nav--ghost { visibility: hidden; }
.v2-cal__dow, .v2-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.v2-cal__dow span { text-align: center; font-size: 0.74rem; color: var(--sy-muted); padding-bottom: 8px; }
.v2-day {
    position: relative;
    aspect-ratio: 1 / 1;
    min-height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--sy-line);
    border-radius: 5px;
    background: transparent;
    color: var(--sy-ink);
    font-family: var(--sy-sans);
    font-size: 0.92rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.16s var(--sy-trans);
}
.v2-day:hover:not(:disabled):not(.is-selected) { border-color: var(--sy-ink); }
.v2-day.is-selected { background: var(--v2-open); border-color: var(--v2-open); color: #fff; }
.v2-day:disabled { border-color: transparent; color: var(--sy-muted); opacity: 0.45; cursor: default; }
.v2-day--blank { border: 0; cursor: default; }
.v2-day__mark {
    position: absolute;
    top: 4px;
    font-size: 0.56rem;
    letter-spacing: 0.06em;
    color: var(--sy-gold);
    font-weight: 700;
}
.v2-day.is-selected .v2-day__mark { color: #fff; }

/* ---- step 1: the outlet list ---- */
.v2-tabs { display: flex; gap: 26px; border-bottom: 1px solid var(--sy-line); margin: 28px 0 0; }
.v2-tab {
    padding: 12px 2px 11px;
    font-size: 0.92rem;
    color: var(--sy-gold);
    border-bottom: 2px solid var(--sy-gold);
    font-weight: 600;
}

.v2-outlets { margin: 0; }
/* The card's bottom rule separates one branch from the NEXT one, so the last card
   must not draw it: the following section (Menu, or Restaurant information when a
   brand has no menu images) opens with its own top rule, and the two were landing
   34px apart as a pair of parallel lines with a gap between them. */
.v2-outlet:last-child { border-bottom: none; }
.v2-outlet {
    display: grid;
    /* The picture spans all three rows of the right-hand column: the words, the
       message, and the seatings. Unchanged to look at -- the seatings simply are
       not nested inside the words any more, which is what lets a phone give them
       the full width. */
    grid-template-columns: 284px 1fr;
    grid-template-rows: auto auto auto;
    column-gap: 22px;
    padding: 26px 14px;
    margin: 0 -14px;
    border-bottom: 1px solid var(--sy-line);
    border-radius: 8px;
    transition: background 0.18s var(--sy-trans);
}
.v2-outlet > .v2-outlet__img { grid-column: 1; grid-row: 1 / span 3; align-self: start; }
.v2-outlet > .v2-outlet__body,
.v2-outlet > .v2-outlet__msg,
.v2-outlet > .v2-slots { grid-column: 2; }
.v2-outlet:hover { background: rgba(255,255,255,0.03); }
.v2-outlet__img {
    aspect-ratio: 16 / 10;
    /* The whole picture, never a crop. `cover` filled the box by cutting the
       banner's sides off, which on artwork that carries the brand's own wordmark
       and branch list meant the part worth showing was the part discarded. It is
       contained instead, on black, so every card shows the same complete image and
       the letterbox reads as a frame rather than a mistake. */
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    background-color: #000;
    border-radius: 6px;
}
.v2-outlet__body { min-width: 0; }
.v2-outlet__name { font-size: 1.35rem; font-weight: 700; margin: 0 0 8px; }
.v2-outlet__addr { color: var(--sy-muted); font-size: 0.92rem; margin: 0 0 6px; }
/* An out-of-range party is the one thing standing between a guest and a booking, and
   as plain body text it read as a caption -- same size, same colour, same weight as
   everything around it -- so nobody noticed it. It is a prompt now. */
.v2-outlet__msg {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 0 0 14px;
    padding: 11px 13px;
    font-size: 0.93rem;
    line-height: 1.45;
    color: var(--sy-ink);
    background: rgba(224, 138, 106, 0.13);
    border: 1px solid rgba(224, 138, 106, 0.42);
    border-left: 3px solid var(--v2-alert);
    border-radius: 6px;
}
/* The explicit display above would otherwise defeat the hidden attribute. */
.v2-outlet__msg[hidden] { display: none !important; }
.v2-outlet__msg::before {
    content: "!";
    flex: 0 0 auto;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background: var(--v2-alert);
    color: #231a16;
    font-weight: 700;
    font-size: 0.8rem;
    line-height: 19px;
    text-align: center;
}
/* A branch that simply is not open that day is information, not an obstacle. Same shape
   so the card does not jump between the two, but quiet. */
.v2-outlet__msg--off {
    color: var(--sy-ink-soft);
    background: rgba(255, 255, 255, 0.04);
    border-color: var(--sy-line);
    border-left-color: var(--sy-muted);
}
.v2-outlet__msg--off::before {
    content: "i";
    background: var(--sy-muted);
    color: var(--sy-washi);
}
/* One row of seatings that slides sideways, at EVERY width. Eleven of them
   wrapped into four rows on a phone and two or three on a desktop, which on a
   list of branches meant the times took more of the page than the branches did.
   The chip cut off at the right edge is the affordance: it reads as a strip. */
.v2-slots {
    display: flex;
    flex-wrap: nowrap;
    gap: 10px;
    align-items: stretch;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: 2px;
}
.v2-slots::-webkit-scrollbar { display: none; }
/* The loading / fully-booked line shares this box and must still wrap rather
   than run off the side of a nowrap row. */
.v2-slots .v2-skeleton { flex: 1 1 100%; white-space: normal; }
.v2-slots[hidden] { display: none !important; }

.v2-chip {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    flex: 0 0 auto;
    min-width: 72px;
    padding: 7px 12px;
    scroll-snap-align: start;
    border: 1px solid var(--v2-open);
    border-radius: 5px;
    background: var(--v2-open);
    color: #fff;
    font-family: var(--sy-sans);
    cursor: pointer;
    line-height: 1.25;
    transition: all 0.18s var(--sy-trans);
}
.v2-chip[hidden] { display: none !important; }
.v2-chip:hover { background: var(--v2-open-deep); border-color: var(--v2-open-deep); transform: translateY(-1px); }
.v2-chip__time { font-size: 0.92rem; font-weight: 700; letter-spacing: 0.02em; }
.v2-chip__note { font-size: 0.62rem; opacity: 0.92; letter-spacing: 0.04em; text-transform: uppercase; }
.v2-chip--off {
    background: var(--v2-shut);
    border-color: var(--v2-shut);
    color: #fff;
    cursor: not-allowed;
    opacity: 0.85;
}
.v2-chip--off:hover { background: var(--v2-shut); border-color: var(--v2-shut); transform: none; }
.v2-skeleton { color: var(--sy-muted); font-size: 0.9rem; padding: 26px 0; }
.v2-note { text-align: center; color: var(--sy-ink-soft); font-size: 0.95rem; padding: 34px 0 0; line-height: 2; }

/* ---- house rules dialog ---- */
.v2-modal {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.72);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4vh 16px;
    /* Above the sticky site header (z-index 100) — otherwise the nav bar sits
       on top of the dimmed backdrop. */
    z-index: 200;
}
.v2-modal[hidden] { display: none !important; }
.v2-modal__panel {
    background: var(--sy-washi);
    border: 1px solid var(--sy-line);
    border-radius: 10px;
    width: min(680px, 100%);
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.v2-modal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 18px 22px;
    border-bottom: 1px solid var(--sy-line);
}
.v2-modal__title { font-size: 1.12rem; font-weight: 700; margin: 0; }
.v2-modal__close { background: transparent; border: 0; color: var(--sy-muted); font-size: 1.15rem; cursor: pointer; padding: 4px 6px; }
.v2-modal__close:hover { color: var(--sy-ink); }
.v2-modal__body { padding: 20px 22px; overflow-y: auto; font-size: 0.92rem; line-height: 1.75; color: var(--sy-ink-soft); }
.v2-modal__foot { padding: 16px 22px 20px; border-top: 1px solid var(--sy-line); }
.v2-modal__note { text-align: center; color: var(--sy-gold); font-size: 0.84rem; margin: 0 0 12px; }

/* ---- step 2: contact form ---- */
.v2-form-title { text-align: center; font-size: clamp(1.25rem, 3vw, 1.85rem); font-weight: 700; margin: 6px 0 30px; }
.v2-form-grid { display: grid; grid-template-columns: 330px 1fr; gap: 34px; align-items: start; }
.v2-summary { border: 1px solid var(--sy-line); border-radius: 8px; overflow: hidden; background: var(--sy-washi); position: sticky; top: 96px; }  /* clears the sticky site header */
/* Matches the banner file (1920x768). The old 16/10 forced a 2.5:1 image into a
   1.6:1 box, so `cover` ate both sides and the brand mark inside it read as a
   square crop. With the true ratio nothing is cropped and the height simply
   follows the width at every screen size. */
.v2-summary__img { aspect-ratio: 1920 / 768; background-size: cover; background-position: center; }
.v2-summary__name { font-size: 1.16rem; font-weight: 700; margin: 0; padding: 18px 20px 4px; }
/* The brand's second line, same lockup as the site header, so the summary confirms
   WHICH restaurant as well as which branch. */
.v2-summary__tagline { margin: 0; padding: 0 20px 16px; font-size: 0.82rem; letter-spacing: 0.04em;
                       text-transform: uppercase; color: var(--sy-muted); }
/* An address wraps, so it must not be forced onto the one line the other facts use. */
.v2-summary__row--addr { align-items: flex-start; line-height: 1.45; }
.v2-summary__row--addr i { margin-top: 2px; }
.v2-summary__facts { border-top: 1px solid var(--sy-line); padding: 16px 20px 18px; display: grid; gap: 11px; }
.v2-summary__row { display: flex; align-items: center; gap: 12px; font-size: 0.95rem; }
.v2-summary__row i { color: var(--sy-gold); width: 18px; text-align: center; }
.v2-summary__modify { margin-left: auto; font-size: 0.85rem; color: var(--sy-muted); }
.v2-summary__modify:hover { color: var(--sy-ink); }

.v2-panel { border: 1px solid var(--sy-line); border-radius: 8px; background: var(--sy-washi); padding: 26px 28px 30px; }
.v2-panel__title { font-size: 1.16rem; font-weight: 700; margin: 0 0 22px; }
.v2-panel__sep { border: 0; border-top: 1px solid var(--sy-line); margin: 24px 0; }
.v2-group { margin-bottom: 20px; }
.v2-group__label { display: block; font-size: 0.92rem; font-weight: 600; margin-bottom: 9px; }
.v2-group__label .req { color: var(--sy-sakura); }
.v2-input {
    width: 100%;
    background: var(--sy-paper);
    border: 1px solid var(--sy-line);
    border-radius: 6px;
    color: var(--sy-ink);
    font-family: var(--sy-sans);
    font-size: 0.95rem;
    padding: 12px 14px;
}
.v2-input:focus { outline: none; border-color: var(--sy-gold); }
.v2-input::placeholder { color: var(--sy-muted); }
textarea.v2-input { resize: vertical; min-height: 104px; line-height: 1.6; }
.v2-two { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.v2-count { text-align: right; color: var(--sy-muted); font-size: 0.78rem; margin: 6px 0 0; }

.v2-tags { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.v2-tag {
    display: flex;
    align-items: center;
    gap: 9px;
    border: 1px solid var(--sy-line);
    border-radius: 6px;
    background: var(--sy-paper);
    color: var(--sy-ink-soft);
    font-family: var(--sy-sans);
    font-size: 0.9rem;
    text-align: left;
    padding: 12px 14px;
    cursor: pointer;
    transition: all 0.16s var(--sy-trans);
}
.v2-tag:hover { border-color: rgba(255,255,255,0.32); color: var(--sy-ink); }
/* Chosen = the brand red, at the same weight as the selected calendar day. The
   old 12%-tint border was easy to miss on a phone in daylight. */
.v2-tag.is-on {
    border-color: var(--v2-open);
    background: var(--v2-open);
    color: #fff;
    font-weight: 600;
}
.v2-tag.is-on .v2-tag__sub { color: rgba(255,255,255,0.82); }
.v2-tag input { display: none; }
.v2-tag__sub { display: block; font-size: 0.78rem; color: var(--sy-muted); margin-top: 2px; }

.v2-agree { font-size: 0.88rem; color: var(--sy-ink-soft); margin: 22px 0 14px; text-align: center; }
.v2-agree a { color: var(--sy-gold); text-decoration: underline; }
.v2-actions { display: grid; gap: 12px; margin-top: 4px; }
/* The shared .sy-btn is this brand's red. Inside the v2 flow the primary button
   is always "yes, go ahead" — accept the rules, book the table — so it takes the
   go colour here. Scoped to v2: v1's Confirm Reservation button is untouched. */
.v2-page .sy-btn:not(.sy-btn--ghost):not(.sy-btn--light),
.v2-modal .sy-btn:not(.sy-btn--ghost):not(.sy-btn--light) {
    background: var(--v2-open);
    border-color: var(--v2-open);
    color: #fff;
}
.v2-page .sy-btn:not(.sy-btn--ghost):not(.sy-btn--light):hover,
.v2-modal .sy-btn:not(.sy-btn--ghost):not(.sy-btn--light):hover {
    background: var(--v2-open-deep);
    border-color: var(--v2-open-deep);
}
.v2-page .sy-btn:disabled,
.v2-modal .sy-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

.v2-alert {
    border: 1px solid var(--sy-sakura);
    border-left-width: 3px;
    border-radius: 6px;
    background: rgba(227,6,19,0.1);
    padding: 13px 16px;
    font-size: 0.9rem;
    margin-bottom: 20px;
}
.v2-alert[hidden] { display: none !important; }
.v2-alert ul { margin: 8px 0 0; padding-left: 20px; }
.v2-alert--warn { border-color: var(--sy-gold); background: rgba(216,176,102,0.1); }

.v2-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.78);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 210;
    text-align: center;
    color: var(--sy-ink);
}
.v2-overlay[hidden] { display: none !important; }

/* ---- responsive ---- */
@media (max-width: 900px) {
    .v2-pickers { grid-template-columns: 1fr; }
    .v2-cal__months { grid-template-columns: 1fr; gap: 26px; }
    .v2-form-grid { grid-template-columns: 1fr; }
    .v2-summary { position: static; }
}
@media (max-width: 640px) {
    .v2-wrap { width: min(1120px, 94vw); }
    /* Inline bleeds the banner to both edges on a phone; ours sat inside the
       wrap with 3vw of gutter each side. The wrap is 94vw here, so each gutter
       is exactly 3vw and the same vw basis makes the pull line up precisely.
       `width: auto` is load-bearing: with the inherited `width: 100%` these
       negative margins would widen the box past the viewport and scroll the
       page sideways, which is the bug already fixed once below. */
    .v2-banner { width: auto; margin-left: -3vw; margin-right: -3vw; border-radius: 0; }
    /* The desktop row bleeds 14px into the gutter for its hover surface; at
       phone width that bleed is wider than the gutter itself and the page
       scrolls sideways by 2px. */
    /* Option A: an 84px thumbnail with the branch beside it, and the seatings
       across the full width underneath -- instead of a 160px band of the same
       brand picture pushing every branch a screen apart. */
    .v2-outlet {
        grid-template-columns: 84px 1fr;
        column-gap: 12px;
        padding: 16px 0;
        margin: 0;
    }
    .v2-outlet > .v2-outlet__img {
        grid-column: 1;
        grid-row: 1;
        width: 84px;
        aspect-ratio: 1;
    }
    .v2-outlet > .v2-outlet__body { grid-column: 2; grid-row: 1; }
    .v2-outlet > .v2-outlet__msg,
    .v2-outlet > .v2-slots { grid-column: 1 / -1; }
    /* Zero, so ONE rule owns the space above the chips -- the meta row's own 6px.
       With 11px here as well the gap was 17px and neither number explained it. */
    .v2-outlet > .v2-slots { margin-top: 0; }
    .v2-outlet__name { font-size: 1.05rem; margin-bottom: 4px; }
    .v2-outlet__addr { font-size: 0.8rem; margin-bottom: 6px; }
    /* 6px: the same step the address leaves above this row, so on a phone the three
       lines of a branch sit on one rhythm instead of the seatings floating away.
       Three classes on purpose (0,3,0) -- the base gap is set with two, so a rule
       written with two would merely tie and be settled by source order, which
       differs between these seven sites; that is how the old `margin-bottom: 0`
       ended up live on two brands and dead on five. */
    .v2-outlet .v2-outlet__body .v2-outlet__meta { margin-bottom: 6px; font-size: 0.8rem; gap: 6px 14px; }
    .v2-picker-row { grid-template-columns: 1fr 1fr; }
    .v2-tags { grid-template-columns: 1fr; }
    .v2-two { grid-template-columns: 1fr; }
    .v2-cal { padding: 16px 14px 20px; }
}

/* ---- menu (the posters, behind a branch picker, at the foot of the page) ---- */
.v2-menu { padding-top: 34px; border-top: 1px solid var(--sy-line); margin-top: 34px; }
.v2-menu .v2-step-title { margin-top: 0; }
.v2-field--menu { max-width: 580px; }
/* Shown in place of the branch select when there is only one branch. */
.v2-menu__outlet { margin: 0; font-size: 1rem; font-weight: 600; color: var(--sy-muted); }

/* The party-cap notice. NOT informational: the party is no longer trimmed to fit,
   so this says why the booking cannot go ahead as asked. */
.v2-partynote {
    display: block;
    margin: 16px 0 0;
    padding: 12px 14px;
    border-left: 3px solid var(--sy-gold);
    background: rgba(255, 255, 255, 0.04);
    border-radius: 4px;
    font-size: 0.93rem;
    line-height: 1.5;
}
/* the explicit display above would otherwise defeat the hidden attribute */
.v2-partynote[hidden] { display: none !important; }
/* A party that cannot be booked online is a stop, not a tip. Same prompt treatment as
   the per-branch message above, so both ways of being out of range look alike. */
.v2-partynote.is-blocking {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    color: var(--sy-ink);
    background: rgba(224, 138, 106, 0.13);
    border: 1px solid rgba(224, 138, 106, 0.42);
    border-left: 3px solid var(--v2-alert);
}
.v2-partynote.is-blocking::before {
    content: "!";
    flex: 0 0 auto;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background: var(--v2-alert);
    color: #231a16;
    font-weight: 700;
    font-size: 0.8rem;
    line-height: 19px;
    text-align: center;
}
/* One shelf of posters, scrolled sideways, exactly how inline presents the same
   menus: every thumbnail shares a HEIGHT and takes whatever width its own ratio
   gives it. Height is the common baseline rather than width, which is what lets a
   1:3 menu page and a near-square a-la-carte sheet sit together without either
   being cropped or letterboxed. */
.v2-menu__pages {
    display: flex;
    flex-wrap: nowrap;
    gap: 14px;
    margin-top: 20px;
    align-items: flex-start;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 8px;
    scrollbar-width: thin;
}
/* the explicit display above would otherwise defeat the hidden attribute */
.v2-menu__pages[hidden] { display: none !important; }
.v2-menu__page {
    flex: 0 0 auto;
    width: auto;
    scroll-snap-align: start;
    padding: 0;
    border: 1px solid var(--sy-line);
    border-radius: 4px;
    background: var(--sy-washi);
    cursor: zoom-in;
    overflow: hidden;
    line-height: 0;
    transition: border-color 0.18s var(--sy-trans), transform 0.18s var(--sy-trans);
}
.v2-menu__page:hover { border-color: var(--sy-gold); transform: translateY(-2px); }
/* the bars contain leaves are the card itself, so keep them quiet */
/* Fixed height, natural width: nothing is cropped and nothing is letterboxed,
   because the box IS the image's own shape. No object-fit and no aspect-ratio
   on purpose -- both would reintroduce a box the image has to be squeezed into. */
.v2-menu__page img {
    height: 400px;
    width: auto;
    display: block;
}

.v2-viewer {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.92);
    z-index: 220;
    overflow: hidden;
}
.v2-viewer[hidden] { display: none !important; }
/* Opens FITTED: the whole poster on screen at once. It used to open at full width
   with height:auto, so a 1600x4825 menu came out ~1177px tall on a phone and the
   guest only ever saw its top -- which reads as being zoomed in on a corner. */
.v2-viewer__scroll {
    position: absolute;
    inset: 0;
    padding: 24px 16px 40px;
    -webkit-overflow-scrolling: touch;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.v2-viewer__scroll img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    border-radius: 4px;
    cursor: zoom-in;
}
/* Tap to read. This toggle is not a nicety: the site sets user-scalable=no, so
   pinch-zoom cannot rescue a fitted poster and these menus are dense. The width
   floor is what makes the text legible on a phone; the view then scrolls both ways. */
.v2-viewer.is-zoom .v2-viewer__scroll {
    display: block;
    overflow: auto;
    text-align: center;
}
.v2-viewer.is-zoom .v2-viewer__scroll img {
    width: clamp(820px, 100%, 1000px);
    max-width: none;
    max-height: none;
    height: auto;
    cursor: zoom-out;
}
.v2-viewer__hint {
    position: absolute;
    left: 0; right: 0;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    margin: 0;
    text-align: center;
    font-size: 0.85rem;
    color: rgba(255,255,255,0.72);
    pointer-events: none;
}
.v2-viewer.is-zoom .v2-viewer__hint { display: none; }
.v2-viewer__close {
    position: absolute;
    top: calc(12px + env(safe-area-inset-top, 0px));
    right: 14px;
    z-index: 2;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid var(--sy-line);
    background: rgba(20,20,20,0.9);
    color: var(--sy-ink);
    font-size: 0.95rem;
    cursor: pointer;
}
.v2-viewer__close:hover { border-color: var(--sy-ink); }

@media (max-width: 640px) {
    /* Shorter shelf on a phone so more than one poster is in view at a time. */
    .v2-menu__page img { height: 320px; }
    /* hover lift would stick after a tap and fight the scroll */
    .v2-menu__page:hover { transform: none; }
    .v2-field--menu { max-width: none; }
}

/* ---- a branch that books somewhere else (Johor / Aeon Tebrau, on inline.app) ---- */
/* Same shape as a branch card so it reads as one of the list, with no bottom rule
   because it is always the last row. */
.v2-extoutlet {
    display: grid;
    grid-template-columns: 284px 1fr;
    gap: 22px;
    padding: 26px 14px;
    margin: 0 -14px;
    border-radius: 8px;
}
.v2-extoutlet__cta {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 11px 20px;
    border: 1px solid var(--sy-gold);
    border-radius: 5px;
    color: var(--sy-gold);
    font-size: 0.95rem;
    font-weight: 600;
    transition: all 0.18s var(--sy-trans);
}
.v2-extoutlet__cta:hover { background: var(--sy-gold); color: var(--sy-paper); }
@media (max-width: 640px) {
    .v2-extoutlet { grid-template-columns: 1fr; gap: 14px; padding: 22px 0; margin: 0; }
    .v2-extoutlet .v2-outlet__img { aspect-ratio: 16 / 7; }
}

/* ---- the brand's hours, stated once above the branch list ---- */
/* Sits under the branch list now, so the air belongs above it. */
.v2-hours {
    margin: 22px 0 0;
    font-size: 0.93rem;
    line-height: 1.6;
    color: var(--sy-ink-soft);
}
.v2-hours i { color: var(--sy-gold); margin-right: 6px; }
.v2-hours__note { color: var(--sy-muted); font-size: 0.86rem; }

/* ---- map and phone, on the branch's own card ---- */
/* Finishes the address, with real air before the session chips: under them, a
   thumb aiming for a seating was landing on a phone call instead. */
/* `.v2-outlet` in front on purpose: this row is a <p> and the last child of the
   card body, so site.css's `p:last-child { margin-bottom: 0 }` (0,1,1) outranked a
   bare class (0,1,0) and silently cancelled this gap for as long as it has existed.
   Two classes (0,2,0) beat it. */
.v2-outlet .v2-outlet__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 20px;
    margin: 0 0 26px;
    font-size: 0.9rem;
}
.v2-outlet__link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--sy-gold);
    white-space: nowrap;
}
.v2-outlet__link:hover { text-decoration: underline; }

/* ---- hero carousel ---- */
.v2-hero { position: relative; }
.v2-hero__track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    border-radius: 8px;
}
.v2-hero__track::-webkit-scrollbar { display: none; }
.v2-hero__slide { flex: 0 0 100%; scroll-snap-align: center; }
.v2-hero__slide img {
    width: 100%;
    aspect-ratio: 1920 / 768;   /* the banner artwork's own shape */
    object-fit: cover;
    display: block;
}
.v2-hero__dots {
    position: absolute;
    left: 0; right: 0; bottom: 10px;
    display: flex; justify-content: center; gap: 7px;
    pointer-events: none;
}
.v2-hero__dot {
    pointer-events: auto;
    width: 7px; height: 7px; padding: 0;
    border: 0; border-radius: 50%;
    background: rgba(255,255,255,0.45);
    cursor: pointer;
    transition: background 0.2s var(--sy-trans), width 0.2s var(--sy-trans);
}
.v2-hero__dot.is-on { background: #fff; width: 18px; border-radius: 4px; }
.v2-hero__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 34px; height: 34px;
    display: flex; align-items: center; justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.42);
    color: #fff;
    font-size: 0.95rem;
    cursor: pointer;
    transition: background 0.18s var(--sy-trans), opacity 0.18s var(--sy-trans);
}
.v2-hero__nav:hover { background: rgba(0, 0, 0, 0.62); }
.v2-hero__nav--prev { left: 10px; }
.v2-hero__nav--next { right: 10px; }
/* at an end the arrow stays visible but stops inviting a tap */
.v2-hero__nav:disabled { opacity: 0.3; cursor: default; }
@media (max-width: 640px) {
    /* edge to edge, matching the single banner below */
    .v2-hero { width: auto; margin-left: -3vw; margin-right: -3vw; }
    .v2-hero__track { border-radius: 0; }
    /* kept on phones on purpose: swiping is not discoverable on its own */
    .v2-hero__nav { width: 30px; height: 30px; font-size: 0.85rem; }
    .v2-hero__nav--prev { left: 6px; }
    .v2-hero__nav--next { right: 6px; }
}

/* ---- phone with a country picker ---- */
.v2-phone { position: relative; display: flex; gap: 8px; }
.v2-phone__cc {
    flex: 0 0 auto;
    display: inline-flex; align-items: center; gap: 7px;
    padding: 0 12px;
    border: 1px solid var(--sy-line);
    border-radius: 6px;
    background: var(--sy-washi);
    color: var(--sy-ink);
    font: inherit;
    cursor: pointer;
    white-space: nowrap;
}
.v2-phone__cc:hover { border-color: var(--sy-gold); }
.v2-phone__cc i { font-size: 0.7rem; color: var(--sy-muted); }
.v2-phone__flag { font-size: 1.15rem; line-height: 1; }
.v2-phone__dial { font-variant-numeric: tabular-nums; }
.v2-phone__num { flex: 1 1 auto; min-width: 0; }
.v2-phone__panel {
    position: absolute;
    z-index: 30;
    top: calc(100% + 6px); left: 0;
    width: min(340px, 100%);
    background: var(--sy-washi);
    border: 1px solid var(--sy-line);
    border-radius: 8px;
    box-shadow: 0 10px 28px rgba(0,0,0,0.35);
    padding: 10px;
}
/* the explicit padding above would otherwise defeat the hidden attribute */
.v2-phone__panel[hidden] { display: none !important; }
.v2-phone__search {
    width: 100%;
    padding: 9px 11px;
    border: 1px solid var(--sy-line);
    border-radius: 6px;
    background: transparent;
    color: var(--sy-ink);
    font: inherit;
}
.v2-phone__list {
    list-style: none; margin: 8px 0 0; padding: 0;
    max-height: 260px; overflow-y: auto;
}
.v2-phone__list li {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 8px;
    border-radius: 5px;
    cursor: pointer;
    font-size: 0.93rem;
}
.v2-phone__list li:hover { background: rgba(255,255,255,0.06); }
.v2-phone__list li.is-on { background: rgba(255,255,255,0.09); }
.v2-phone__name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-phone__code { color: var(--sy-muted); font-variant-numeric: tabular-nums; }
.v2-phone__none { margin: 10px 4px 2px; color: var(--sy-muted); font-size: 0.9rem; }
.v2-phone__none[hidden] { display: none !important; }
@media (max-width: 640px) {
    .v2-phone__panel { width: 100%; }
}

/* ---- option B on this brand ----
   Seven and eight branches, every one of them showing the SAME brand picture. It cost
   a row per branch on a phone and a 284px column on a desktop, and in neither place
   did it tell anyone which branch they were reading -- an identical picture cannot.
   The branch keeps the full width at every size. */
.v2-outlet__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.v2-outlet { grid-template-columns: 1fr; }
.v2-outlet > .v2-outlet__img { display: none; }
/* All three, not just the body: the base rule puts every one of them in column 2, and
   a child still asking for column 2 makes the grid grow an implicit second track --
   the picture would be gone and its empty column would not. */
.v2-outlet > .v2-outlet__body,
.v2-outlet > .v2-outlet__msg,
.v2-outlet > .v2-slots { grid-column: 1 / -1; }
/* the Inline branch carries the same picture, and loses it too, so the list reads as one */
.v2-extoutlet { grid-template-columns: 1fr; }
.v2-extoutlet .v2-outlet__img { display: none; }
