/* Shared Konnect Services interaction/accessibility layer. Brand colors remain module-owned. */
:root{--v-space-1:4px;--v-space-2:8px;--v-space-3:12px;--v-space-4:16px;--v-space-5:24px;--v-control-h:44px;--v-radius:9px}
html{scroll-padding-top:80px}
body{overflow-wrap:anywhere}
body.valoria-guest-page{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}
body.valoria-guest-page>main,body.valoria-guest-page>.g-shell{flex:1 0 auto}
body.valoria-guest-page>.g-shell{min-height:100vh;min-height:100dvh;display:flex;flex-direction:column}
body.valoria-guest-page>.g-shell>main{flex:1 0 auto}
.valoria-guest-footer{position:static!important;inset:auto!important;margin-top:auto;display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap}
.valoria-guest-footer a{color:inherit}
.skip-link{position:fixed;z-index:10000;inset-block-start:8px;inset-inline-start:8px;transform:translateY(-160%);background:var(--navy,#22375C);color:#fff!important;padding:10px 14px;border-radius:8px;text-decoration:none}
.skip-link:focus{transform:translateY(0)}
main:focus{outline:none}
/* Canonical Guest header — assets/valoria-guest-shell.php's valoria_guest_header_html() is the only place that emits this markup; every Guest module (Concierge, Spa, Restaurants, Tickets) loads this stylesheet after its own, so these rules win the cascade and the header can never visually diverge by module. Module content BELOW the header keeps its own module-specific styling. */
.g-top{background:var(--navy,#22375C);color:#fff}
.g-top .row{padding:0 22px;height:64px;display:flex;align-items:center;gap:16px}
/* Root cause of the guest header visibly breaking into "VALORI/A",
   "HOM/E", "SERVICE/S" etc under a narrow/zoomed viewport (Owner QA
   pass, Item 14): body{overflow-wrap:anywhere} above applies globally,
   and none of these header text elements opted back out of it with
   white-space:nowrap -- so the instant a flex child (brand or a nav
   link) is squeezed below its own content's natural width, the browser
   is free to break the word anywhere, including mid-letter, rather than
   simply overflowing/scrolling. flex-shrink:0 on .brand additionally
   guarantees the wordmark itself is never the thing that gives up space
   first; .g-nav already becomes a horizontally-scrollable rail at
   narrow widths (below), which only actually works once its own labels
   refuse to wrap in the first place. */
.g-top .brand{display:inline-flex;align-items:center;gap:11px;flex-shrink:0}
.g-top .brand img{width:32px;height:28px;flex-shrink:0}
.g-top .brand b{font:700 16px Outfit,sans-serif;letter-spacing:4px;color:#fff;white-space:nowrap}
.g-top .brand small{display:block;font:700 8px Outfit,sans-serif;letter-spacing:2.5px;color:#F2BD89;margin-top:1px;white-space:nowrap}
.g-top .sp{margin-inline-start:auto}
.g-top .g-nav{display:flex;align-items:center;gap:22px}
.g-top .g-nav a{color:#AEB6CD;font:600 11px 'Outfit',sans-serif;letter-spacing:1.6px;text-transform:uppercase;white-space:nowrap;flex-shrink:0}
.g-top .g-nav a:hover,.g-top .g-nav a.on{color:#fff}
.g-top .g-nav a.signin{color:#F2BD89}
.g-top .whoami{display:inline-flex;align-items:center;gap:9px;color:#AEB6CD;font:600 11px 'Outfit',sans-serif;letter-spacing:.4px;white-space:nowrap}
.g-top .whoami{min-width:0;max-width:100%}
/* the signed-in label: one line with an ellipsis on a wide header (the full name is in its tooltip), wrapped on a narrow one -- a long guest name never pushes the page sideways */
.g-top .whoami .who{min-width:0;max-width:30ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.g-top .whoami .dot{width:7px;height:7px;border-radius:50%;background:#F2BE89;flex:none;box-shadow:0 0 0 3px rgba(242,190,137,.2)}
.g-top .whoami a{color:#F2BD89;text-transform:uppercase;letter-spacing:1.4px;font-size:10px;margin-inline-start:4px}
.g-top .whoami a.who{color:inherit;text-transform:none;letter-spacing:.4px;font-size:inherit;margin:0;text-decoration:none;font-weight:inherit}
.g-top .whoami a.who:hover{text-decoration:underline}
.g-top .whoami a.who:focus-visible{outline:2px solid #F2BD89;outline-offset:2px;border-radius:3px}
.g-top .langsw{position:relative;display:inline-block}
.g-top .langsw>summary{list-style:none;cursor:pointer;color:#AEB6CD;font:600 12px 'Outfit',sans-serif;letter-spacing:.5px;display:inline-flex;align-items:center;gap:8px;white-space:nowrap;flex-shrink:0;padding:6px 8px;border-radius:8px}
.g-top .langsw>summary::-webkit-details-marker{display:none}
.g-top .langsw>summary:hover,.g-top .langsw>summary:focus-visible{color:#fff;background:rgba(255,255,255,.08)}
.g-top .langsw-label{text-transform:none;letter-spacing:normal}
.g-top .langmenu{position:absolute;inset-block-start:calc(100% + 8px);inset-inline-end:0;z-index:80;min-width:190px;background:#fff;border:1px solid var(--line,#E3E7ED);border-radius:12px;box-shadow:0 12px 30px rgba(34,55,92,.16);padding:8px;display:flex;flex-direction:column;gap:2px}
.g-top .langmenu a{color:var(--ink,#1B2942);font:500 14px 'Inter',sans-serif;padding:10px 12px;border-radius:8px;display:flex;align-items:center;gap:11px;letter-spacing:normal;text-transform:none;min-height:44px}
.g-top .langmenu a:hover,.g-top .langmenu a:focus-visible{background:var(--teal-soft,rgba(242,187,130,.10));color:var(--teal-d,#B8732E)}
.g-top .langmenu a.on{color:var(--teal-d,#B8732E);font-weight:600;background:var(--teal-soft,rgba(242,187,130,.06))}
.flag-icon{width:22px;height:15px;border-radius:2px;object-fit:cover;flex-shrink:0;box-shadow:0 0 0 1px rgba(0,0,0,.08)}
.flag-icon-emoji{font-size:16px;line-height:1;display:inline-block;width:22px;text-align:center}
.langmenu-names{display:flex;flex-direction:column;line-height:1.25}
.langmenu-native{font-weight:600}
.langmenu-english{font-size:11px;color:var(--ink-muted,#66788C)}
@media(max-width:1099px){
  .g-top .langmenu{inset-inline-end:auto;inset-inline-start:0}
  .g-top .row{height:auto;flex-wrap:wrap;padding:12px 18px;gap:8px 12px}
  .g-top .sp{display:none}
  .g-top .g-nav{flex:1 1 100%;justify-content:flex-start;gap:10px 16px;flex-wrap:wrap;padding-top:4px;border-top:1px solid rgba(255,255,255,.08)}
  .g-top .g-nav a{font-size:10.5px;letter-spacing:1.2px}
  .g-top .whoami{width:100%;justify-content:flex-start;order:5}
  .g-top .whoami .who{max-width:100%;overflow:visible;text-overflow:clip;white-space:normal;overflow-wrap:anywhere}
}
button,input,select,textarea{font:inherit}
.btn,.input,button,select,input:not([type=hidden]),textarea{min-height:var(--v-control-h)}
.btn{line-height:1.2}
.btn-sm{min-height:36px}
button:disabled,.btn[aria-disabled=true],input:disabled,select:disabled,textarea:disabled{cursor:not-allowed;opacity:.58}
:where(a,button,input,select,textarea,summary):focus-visible{outline:3px solid var(--teal-d,#B8732E);outline-offset:3px}
:where(input,select,textarea).input:focus-visible{outline:none;border-color:var(--teal-d,#B8732E);box-shadow:0 0 0 3px var(--teal-soft,rgba(242,187,130,.10))}
.actions{display:flex;align-items:center;gap:var(--v-space-2);flex-wrap:wrap}
.filter-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));align-items:end;gap:var(--v-space-3)}
.filter-grid label{min-width:0}.responsive-table{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
/* Operational tables (Tickets/Restaurants admin queues, etc.) must never
   compress into unreadable, one-character-per-line headers when their
   container is narrower than the table's natural content width — they
   should gain a horizontal scrollbar instead. min-width:max-content keeps
   every table at its intrinsic content width regardless of how narrow a
   parent grid/flex track shrinks it to; nowrap headers/cells are what let
   that intrinsic width be measured sanely instead of wrapping mid-word. */
.responsive-table table,.card:has(>table)>table{min-width:max-content}
.responsive-table th,.responsive-table td,.card:has(>table)>table th,.card:has(>table)>table td{white-space:nowrap}
.responsive-table td.wrap,.card:has(>table)>table td.wrap{white-space:normal}
/* page_top()'s shared .two ratio (1fr / 1.6fr) is tuned for a detail page's
   narrow content column plus wide conversation/history column. An
   operational queue + a short activity sidebar needs the opposite shape —
   this modifier gives the primary (first) column the larger share. */
.two.queue-layout{grid-template-columns:minmax(0,1.6fr) minmax(0,1fr)}
@media(max-width:900px){.two.queue-layout{grid-template-columns:minmax(0,1fr)}}
.error,.err,[role=alert]{scroll-margin-top:var(--v-space-5)}
.star-rating{border:0;padding:0;margin:10px 0;display:flex;gap:4px}.star-rating legend{font-weight:700;margin-bottom:5px}.star-rating input{position:absolute;opacity:0;pointer-events:none}.star-rating label{min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--line,#DCE1E7);border-radius:9px;font-size:25px;color:#9aa7aa;cursor:pointer;background:#fff}.star-rating input:checked+label{color:#d69421;background:#fff7e8;border-color:#d69421}.star-rating input:focus-visible+label{outline:3px solid var(--teal-d,#B8732E);outline-offset:2px}.star-rating label:hover{color:#d69421}
.visually-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}
.rm{min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center}
[id^=order-],[id^=request-],[id^=appointment-]{scroll-margin-top:90px}
.card:has(>table){overflow-x:auto;-webkit-overflow-scrolling:touch}
@media(max-width:720px){
  .wrap{padding-inline:16px}
  .actions{align-items:stretch}
  .actions>.btn{flex:1 1 160px}
  .filter-grid{grid-template-columns:1fr}
  table{font-size:13px}
  th,td{padding-inline:9px}
  .topbar nav,.g-nav,.a-top nav{max-width:100%;overflow-x:auto;scrollbar-width:thin}
  .guest-inhouse-table thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .guest-inhouse-table,.guest-inhouse-table tbody,.guest-inhouse-table tr,.guest-inhouse-table td{display:block;width:100%}
  .guest-inhouse-table tr{padding:10px 0;border-bottom:2px solid var(--line,#e8e8e8)}
  .guest-inhouse-table td{display:grid;grid-template-columns:minmax(105px,38%) minmax(0,1fr);gap:10px;border:0;padding:6px 4px}
  .guest-inhouse-table td::before{content:attr(data-label);font-weight:700;color:var(--muted,#68717f)}
}
@media(max-width:520px){.two,.grid{grid-template-columns:1fr!important}.card{padding:16px}.h1,h1{font-size:clamp(1.45rem,8vw,2rem)}.topbar{height:auto;min-height:62px;flex-wrap:wrap;padding-block:10px}.who{margin-inline-start:0!important;width:100%}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}
.nav-locked{display:inline-flex;align-items:center;flex-wrap:wrap;gap:6px;max-width:100%;color:var(--muted,#68717f);cursor:not-allowed;opacity:.75}
.nav-locked:focus-visible{outline:2px solid var(--teal-d,#B8732E);outline-offset:2px}
.nav-locked .lock-badge{font-size:11px;letter-spacing:.02em;border:1px solid var(--line,#e8e8e8);border-radius:999px;padding:1px 8px;white-space:normal;overflow-wrap:break-word;line-height:1.5;max-width:100%}

/* Shared admin shell additions (launch-hardening unification pass) — used by
   any module rendered through the shared Console page_top()/page_bottom(). */
.alert{border-radius:9px;padding:11px 14px;margin-bottom:16px;font-weight:500}
.alert.bad{background:rgba(210,91,78,.08);color:#B34437;border:1px solid rgba(210,91,78,.3)}
.lang-tabs{display:flex;gap:4px;margin-bottom:18px;border-bottom:1px solid var(--line,#E3E7ED);flex-wrap:wrap}
.lang-tab{padding:9px 14px;font:600 12px Outfit,Inter,sans-serif;color:var(--muted,#66788C);border-bottom:2px solid transparent}
.lang-tab.active{color:var(--teal-d,#B8732E);border-bottom-color:var(--teal-d,#B8732E)}
.lang-tab:hover{color:var(--teal-dd,#8F5521)}
.pill.warn{background:rgba(192,138,45,.12);color:#9C6A1F}
.pill.soon{background:#EDF0F4;color:#5e6d80;font-weight:700;letter-spacing:.02em}
.soon-card{opacity:.62;cursor:not-allowed}.soon-card a,.soon-card .btn{pointer-events:none}

/* Experience Studio: guest-side building blocks (custom fields, notices, service cards, compact menu). */
.xp-sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.xp-req{color:#C0503F;font-weight:700}
.xp-help{display:block;margin-top:4px;font-size:12px}
.field label.xp-choice,label.xp-choice{display:flex;gap:10px;align-items:center;min-height:44px;margin:0;text-transform:none;letter-spacing:0;font:400 14px Inter,system-ui,sans-serif;color:var(--ink)}
.xp-choice input{width:20px;height:20px;flex-shrink:0}
.xp-fieldset{border:0;padding:0;margin:0}
.xp-fieldset legend{font:600 10px Outfit,Inter,sans-serif;letter-spacing:1.2px;text-transform:uppercase;color:var(--muted);margin-bottom:6px;padding:0}
.xp-notice{margin:14px 0}
.items.xp-list{grid-template-columns:1fr}
.xp-list .item{flex-direction:row}
.xp-list .item .ph{width:120px;height:auto;min-height:90px;flex-shrink:0}
.xp-services .item{transition:box-shadow .15s ease,transform .15s ease}
.xp-services .item:hover,.xp-services .item:focus-visible{box-shadow:0 14px 34px rgba(34,55,92,.14);transform:translateY(-2px)}
.xp-services .item:focus-visible{outline:3px solid var(--teal-line)}
.xp-services .item .btn{margin-top:auto;align-self:flex-start}
.xp-hero{padding:8px 0}
.xp-contact,.xp-intro{margin:18px 0}
@media(prefers-reduced-motion:reduce){.xp-services .item{transition:none}.xp-services .item:hover{transform:none}}
/* Guest portal: unread badge on Notifications and the urgent-alert banner (assets/valoria-guest-shell.php). Both render nothing when there is nothing unread. */
.g-badge{display:inline-block;min-width:18px;padding:0 6px;margin-inline-start:6px;border-radius:999px;background:#b3261e;color:#fff;font:700 11px/18px Inter,system-ui,sans-serif;text-align:center;letter-spacing:0;text-transform:none;vertical-align:middle}
.g-alert{background:#fff3e0;border-block:1px solid #e0b36a;color:#4a2b00}
.g-alert .row{display:flex;flex-wrap:wrap;gap:6px 14px;align-items:center;max-width:1180px;margin:0 auto;padding:10px 24px}
.g-alert b{font:700 13px/1.4 Outfit,Inter,sans-serif}
.g-alert span{flex:1 1 220px;min-width:0;overflow-wrap:anywhere}
.g-alert a{color:#4a2b00;font-weight:700;text-decoration:underline;text-underline-offset:3px;min-height:24px;display:inline-block}
.g-alert a:focus-visible{outline:3px solid #4a2b00;outline-offset:2px;border-radius:3px}
