@import url("/brand/lockup.css?v=ebf97389720c");
/*
 * CitiHome Platform Design System
 * Shared by the mother site, booking, guest, business, offers and operations.
 * Existing product-specific layouts remain intact; these tokens and primitives
 * make their brand, interaction, focus, surfaces and live status consistent.
 */
:root {
  color-scheme: light;
  --cp-navy-950: #071b25;
  --cp-navy-900: #0d2733;
  --cp-navy-800: #153946;
  --cp-copper-600: #b85f3d;
  --cp-copper-500: #d07850;
  --cp-copper-300: #efb399;
  --cp-sage-600: #527b70;
  --cp-sage-100: #e7f0ec;
  --cp-sand-50: #fbfaf7;
  --cp-sand-100: #f5f1e9;
  --cp-sand-200: #ece5d9;
  --cp-ink: #14252d;
  --cp-muted: #68777d;
  /* The shared accent every cross-page component draws with. It was never defined, so
     notification-runtime.js (and anything else reading it) always fell back to its own
     hardcoded #dc8055 — an orange chosen against a dark panel, which measures 2.9:1 on a
     white one. A component cannot pick a readable accent for a surface it does not know
     about; the theme has to name it. Bronze here for light, the warmer orange for dark. */
  --cp-accent: #b45309;
  --cp-line: color-mix(in srgb, var(--cp-navy-900) 13%, transparent);
  --cp-surface: rgba(255, 255, 255, .92);
  --cp-surface-solid: #fff;
  --cp-shadow-sm: 0 8px 25px rgba(7, 27, 37, .07);
  --cp-shadow-lg: 0 28px 80px rgba(7, 27, 37, .16);
  --cp-radius-sm: 12px;
  --cp-radius-md: 18px;
  --cp-radius-lg: 28px;
  --cp-ease: cubic-bezier(.2, .8, .2, 1);
  --cp-font-sans: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --cp-font-display: "Chakra Petch", Inter, ui-sans-serif, sans-serif;

  /* Bridge older page tokens into one brand palette. */
  --navy: var(--cp-navy-900);
  --navy2: var(--cp-navy-950);
  --navy-2: var(--cp-navy-950);
  --ink: var(--cp-ink);
  --dark: var(--cp-navy-950);
  --paper: var(--cp-sand-50);
  --muted: var(--cp-muted);
  --line: var(--cp-line);
  --copper: var(--cp-copper-500);
  --orange: var(--cp-copper-500);
  --green: var(--cp-sage-600);
  --white: #fff;
  --soft: var(--cp-sand-100);
  --sky: #e9f4fa;
  --mint: #dce9df;
  --cream: var(--cp-sand-100);
  --sand: var(--cp-sand-200);
  --blue: #176aa2;
  --gold: #c9a24b;

  /* Semantic status inks: readable in light here, overridden for dark below.
     These replace the raw Tailwind 300/400 tints that were unreadable on white. */
  /* 2026-08-05 — Item A2. These land on their own 14%-tint chips, not on the page,
     and measured 3.83–4.08:1 there. Deepened against the tint. */
  --cp-success-ink: #116634;
  --cp-warn-ink: #8a5406;
  /* Long-form alias for the warning ink. Some call sites reach for the full
     word; both names must resolve to the same amber or the two spellings
     drift into two colours. var() resolves at the element, so the dark
     override of --cp-warn-ink below flows through this alias untouched. */
  --cp-warning-ink: var(--cp-warn-ink);
  --cp-danger-ink: #b91c1c;
  --cp-info-ink: #1d4ed8;
  --cp-accent-ink: #6d28d9;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --cp-ink: #eef4f4;
  --cp-muted: #9fb0b5;
  --cp-accent: #dc8055;
  --cp-line: rgba(230, 238, 239, .13);
  --cp-surface: rgba(13, 32, 42, .9);
  --cp-surface-solid: #102b37;
  --cp-sand-50: #081d27;
  --cp-sand-100: #0d2631;
  --cp-sand-200: #143540;
  --cp-shadow-sm: 0 8px 28px rgba(0, 0, 0, .24);
  --cp-shadow-lg: 0 32px 90px rgba(0, 0, 0, .4);
  --white: #102b37;
  --soft: #143540;
  --sky: #0f2e3c;
  --mint: #12313a;
  --cream: #0d2631;
  --sand: #143540;
  --blue: #7db8dc;
  --gold: #c9a24b;
  --cp-success-ink: #86efac;
  --cp-warn-ink: #fcd34d;
  --cp-danger-ink: #fca5a5;
  --cp-info-ink: #93c5fd;
  --cp-accent-ink: #c4b5fd;
}

html {
  background: var(--cp-sand-50);
  accent-color: var(--cp-copper-500);
  scrollbar-color: var(--cp-copper-500) transparent;
}

body {
  font-family: var(--cp-font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body::selection,
::selection {
  color: #fff;
  background: var(--cp-copper-600);
}

/* Focus, press and the control transition are all defined once, in the
   INTERACTION SYSTEM block at the foot of this file. These rules only name
   which properties move; the duration, the curve, the ring and the press
   depth all come from tokens. */
:where(button, a, input, select, textarea) {
  transition:
    color var(--cp-dur) var(--cp-ease),
    background-color var(--cp-dur) var(--cp-ease),
    border-color var(--cp-dur) var(--cp-ease),
    box-shadow var(--cp-dur) var(--cp-ease),
    transform var(--cp-dur) var(--cp-ease);
}

:where(input, select, textarea) {
  border-color: var(--cp-line);
}

:where(.card, .panel, .dashboard-panel, .metric-card, .job-card, .service, .offer-card, .stay-card, .request-card) {
  border-color: var(--cp-line);
}

:where(.card, .panel, .dashboard-panel, .metric-card, .job-card, .service, .offer-card):hover {
  box-shadow: var(--cp-hover-shadow);
}

:where(.primary, .primary-button, .solid-button, .btn-gold, .search-button) {
  background: linear-gradient(135deg, var(--cp-copper-500), var(--cp-copper-600)) !important;
  border-color: transparent !important;
  color: #fff !important;
  box-shadow: 0 10px 24px rgba(184, 95, 61, .2);
}

/* The primary button hovers with the same 1px lift as every other raised
   surface. It used to lift 1px here, 2px in citihome.css and 4px on three
   panels — three different buttons wearing the same label. */
:where(.primary, .primary-button, .solid-button, .btn-gold, .search-button):hover {
  filter: brightness(1.08);
  box-shadow: var(--cp-hover-shadow);
  transform: translateY(var(--cp-hover-lift));
}

/*
 * Universal CitiHome signature.
 * The runtime turns every page-level brand in headers, sidebars and footers
 * into this single lockup: Concept Plus mark + CitiHome + affiliate line.
 * The wordmark is a mask so it remains crisp and readable in either theme.
 */

/* The lockup lives in /brand/lockup.css, @imported at the top of this file, so
   the dozen tool pages that do not load this design system can still carry the
   correct brand. One definition, one ratio, one place to change it. */

.cp-brand-masthead {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  min-height: 82px;
  padding: 14px clamp(18px, 5vw, 72px);
  color: #f1f4f7;
  background: #0d1319;
  border-bottom: 1px solid rgba(255, 255, 255, .09);
}

.cp-footer-brand {
  display: flex !important;
  width: max-content !important;
  margin: 0 0 14px !important;
}

:where(footer) > .cp-footer-brand:last-child {
  margin-bottom: 0 !important;
}

/*
 * Selective motion language.
 * Strong motion is reserved for welcome/authentication moments; public
 * mastheads receive a slower ambient treatment. Operational workspaces and
 * footers intentionally stay still so the interface remains calm.
 */
.cp-brand-dynamic,
.cp-brand-ambient {
  isolation: isolate;
  perspective: 560px;
}

.cp-brand-dynamic .cp-brand-symbol,
.cp-brand-ambient .cp-brand-symbol {
  position: relative;
  transform-style: preserve-3d;
}

.cp-brand-dynamic .cp-brand-symbol::before,
.cp-brand-ambient .cp-brand-symbol::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -38%;
  border-radius: 50%;
  opacity: 0;
  background: radial-gradient(
    circle,
    rgba(208, 120, 80, .38) 0,
    rgba(184, 95, 61, .16) 38%,
    transparent 72%
  );
  filter: blur(3px);
  pointer-events: none;
}

.cp-brand-dynamic.cp-brand-visible .cp-brand-symbol::before {
  animation: cpBrandAura 4.8s var(--cp-ease) infinite;
}

.cp-brand-dynamic.cp-brand-visible .cp-brand-symbol img {
  animation: cpBrandSculpt 6.4s var(--cp-ease) infinite;
  filter:
    drop-shadow(0 8px 20px rgba(184, 95, 61, .34))
    drop-shadow(0 0 15px rgba(208, 120, 80, .16)) !important;
}

.cp-brand-dynamic.cp-brand-visible .cp-brand-wordmark {
  background:
    linear-gradient(
      105deg,
      var(--cp-brand-color) 0%,
      var(--cp-brand-color) 38%,
      color-mix(in srgb, var(--cp-brand-color) 58%, white) 49%,
      var(--cp-brand-color) 60%,
      var(--cp-brand-color) 100%
    ) !important;
  background-size: 240% 100% !important;
  animation: cpBrandSheen 6.8s ease-in-out infinite;
}

.cp-brand-dynamic.cp-brand-visible .cp-brand-affiliate {
  animation: cpBrandCaption 4.8s ease-in-out infinite;
}

.cp-brand-ambient.cp-brand-visible .cp-brand-symbol::before {
  animation: cpBrandAura 9s var(--cp-ease) infinite;
}

.cp-brand-ambient.cp-brand-visible .cp-brand-symbol img {
  animation: cpBrandBreathe 10s var(--cp-ease) infinite;
}

.cp-brand-ambient.cp-brand-visible .cp-brand-wordmark {
  background:
    linear-gradient(
      105deg,
      var(--cp-brand-color) 0%,
      var(--cp-brand-color) 44%,
      color-mix(in srgb, var(--cp-brand-color) 72%, white) 50%,
      var(--cp-brand-color) 56%,
      var(--cp-brand-color) 100%
    ) !important;
  background-size: 280% 100% !important;
  animation: cpBrandSheen 14s ease-in-out infinite;
}

.cp-brand-stage-dynamic {
  isolation: isolate;
}

.cp-brand-stage-dynamic::before,
.cp-brand-stage-dynamic::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -14px;
  border: 1px solid rgba(208, 120, 80, .17);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}

.cp-brand-stage-dynamic::after {
  inset: -28px;
  border-color: rgba(208, 120, 80, .09);
}

.cp-brand-stage-dynamic.cp-brand-visible::before {
  animation: cpBrandRing 4.6s ease-out infinite;
}

.cp-brand-stage-dynamic.cp-brand-visible::after {
  animation: cpBrandRing 4.6s 2.3s ease-out infinite;
}

@keyframes cpBrandAura {
  0%, 100% { opacity: .28; transform: scale(.78); }
  50% { opacity: .88; transform: scale(1.18); }
}

@keyframes cpBrandSculpt {
  0%, 100% { transform: translateY(0) rotateX(0) rotateY(-4deg); }
  30% { transform: translateY(-4px) rotateX(2deg) rotateY(8deg); }
  65% { transform: translateY(1px) rotateX(-2deg) rotateY(-8deg); }
}

@keyframes cpBrandBreathe {
  0%, 100% { transform: translateY(0) scale(1); }
  50% { transform: translateY(-1.5px) scale(1.025); }
}

@keyframes cpBrandSheen {
  0%, 30% { background-position: 115% 50%; }
  62%, 100% { background-position: -105% 50%; }
}

@keyframes cpBrandCaption {
  0%, 100% { opacity: .62; letter-spacing: .18em; }
  50% { opacity: .92; letter-spacing: .205em; }
}

@keyframes cpBrandRing {
  0% { opacity: 0; transform: scale(.7) rotate(0); }
  24% { opacity: .55; }
  100% { opacity: 0; transform: scale(1.45) rotate(16deg); }
}

:where(.eyebrow, [class*="kicker"], [class*="overline"]) {
  font-family: var(--cp-font-display);
  letter-spacing: .14em;
}

/* Fixed, quiet platform dock for standalone satellite URLs. Embedded views use
   the parent shell and intentionally hide this dock. */
.cp-platform-dock {
  position: fixed;
  z-index: 10050;
  left: 50%;
  bottom: max(14px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 54px;
  max-width: calc(100vw - 24px);
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 999px;
  color: #eef4f4;
  background: rgba(7, 27, 37, .88);
  box-shadow: 0 20px 55px rgba(5, 19, 27, .3);
  backdrop-filter: blur(22px) saturate(1.2);
  -webkit-backdrop-filter: blur(22px) saturate(1.2);
}

.cp-embedded .cp-platform-dock {
  display: none !important;
}

/* The dock is fixed at the bottom with no space reserved for it, so on short
   viewports it floats over whatever content ends the page (the last line of
   copy, a form's bottom field). reserveDockSpace() in unify.js measures the
   dock's real footprint (height + gap to viewport floor + safe-area, never a
   guessed constant) into --cp-dock-h and adds this class to <body> wherever
   the dock mounts and reservation isn't opted out. The 92px fallback covers
   the instant before the first measurement lands. chos.html opts itself out
   (it reserves space per-overlay instead, see cpDockReserve() there) — any
   page can do the same via <html data-cp-dock-reserve="off">. */
body.cp-dock-reserved {
  padding-bottom: calc(var(--cp-dock-h, 92px) + 14px);
}

.cp-platform-home,
.cp-platform-context,
.cp-live-status,
.cp-platform-theme {
  min-height: 40px;
  border: 0;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 0 13px;
  color: inherit;
  background: transparent;
  text-decoration: none;
  white-space: nowrap;
}

.cp-platform-home:hover,
.cp-platform-theme:hover {
  background: rgba(255, 255, 255, .09);
}

.cp-platform-home img {
  width: 27px;
  height: 27px;
  object-fit: contain;
}

.cp-platform-home span {
  display: flex;
  flex-direction: column;
  line-height: 1.05;
}

.cp-platform-home b {
  font-family: var(--cp-font-display);
  font-size: 12px;
  letter-spacing: .02em;
}

.cp-platform-home small,
.cp-platform-context {
  font-size: 8px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #9fb0b5;
}

.cp-platform-context {
  border-left: 1px solid rgba(255, 255, 255, .12);
  border-radius: 0;
}

.cp-live-status {
  font-size: 9px;
  letter-spacing: .08em;
  color: #b7c5c8;
}

/* The dock is centred with translateX(-50%), so a label that grows or shrinks slides
   the entire bar sideways. "Live · now", "Syncing…" and "Offline" are all given the
   same box, so the dock keeps still whatever the connection is doing. */
.cp-live-status > span:last-child {
  display: inline-block;
  min-width: 62px;
}

.cp-live-dot {
  width: 8px;
  height: 8px;
  flex: 0 0 8px;
  border-radius: 50%;
  background: #f0ab55;
  box-shadow: 0 0 0 5px rgba(240, 171, 85, .11);
}

.cp-live-status[data-state="live"] .cp-live-dot {
  background: #57c79b;
  box-shadow: 0 0 0 5px rgba(87, 199, 155, .13);
}

.cp-live-status[data-state="offline"] .cp-live-dot {
  background: #e2675d;
  box-shadow: 0 0 0 5px rgba(226, 103, 93, .13);
}

.cp-platform-theme {
  width: 40px;
  justify-content: center;
  padding: 0;
  cursor: pointer;
  font-size: 16px;
}

/* Founder / team workspace switcher — every department from any surface. */
.cp-platform-switch {
  max-width: 168px;
  height: 34px;
  padding: 0 10px;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 99px;
  background: rgba(255, 255, 255, .07);
  color: #f3efe8;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  appearance: none;
}
.cp-platform-switch:hover { border-color: rgba(255, 255, 255, .3); }
.cp-platform-switch option { color: var(--cp-ink); background: var(--cp-surface-solid); }
@media (max-width: 640px) { .cp-platform-switch { max-width: 120px; font-size: 10px; } }

/* Live freshness line can be placed in any dashboard heading. */
.cp-live-freshness {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--cp-muted);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}

.cp-live-freshness::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #57c79b;
}

/* Native View Transitions keep state changes calm instead of flashing. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: .24s;
  animation-timing-function: var(--cp-ease);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  .cp-brand-dynamic .cp-brand-symbol::before,
  .cp-brand-ambient .cp-brand-symbol::before,
  .cp-brand-stage-dynamic::before,
  .cp-brand-stage-dynamic::after {
    display: none !important;
  }
}

@media (max-width: 680px) {
  .cp-brand-lockup {
    gap: 8px !important;
  }

  .cp-brand-lockup .cp-brand-symbol {
    flex-basis: 36px !important;
    width: 36px !important;
    height: 40px !important;
  }

  .cp-brand-lockup .cp-brand-symbol img {
    width: 33px !important;
    height: 36px !important;
  }

  .cp-brand-lockup .cp-brand-wordmark {
    width: 112px !important;
    height: 28px !important;
  }

  .cp-brand-lockup .cp-brand-affiliate {
    font-size: 6.2px !important;
    letter-spacing: .14em !important;
  }

  .cp-brand-masthead {
    min-height: 70px;
    padding: 11px 16px;
  }

  .cp-platform-dock {
    width: calc(100vw - 18px);
    justify-content: space-between;
    bottom: max(8px, env(safe-area-inset-bottom));
  }

  .cp-platform-context {
    display: none;
  }

  .cp-platform-home span {
    display: none;
  }

  .cp-live-status {
    flex: 1;
    justify-content: center;
  }
}

@media print {
  .cp-platform-dock {
    display: none !important;
  }
}

/*
 * Professional site shell
 * Every public surface receives the same complete navigation, live state,
 * mobile menu, support routes, compliance details and legal footer. Existing
 * page-specific controls are retained as contextual navigation.
 */
.cp-pro-header {
  position: relative;
  z-index: 10020;
  box-sizing: border-box;
  display: flex !important;
  align-items: center !important;
  gap: clamp(14px, 2vw, 28px) !important;
  width: 100%;
  min-height: 78px;
  padding: 12px clamp(18px, 4.2vw, 72px) !important;
  color: #f3f7f7 !important;
  background:
    radial-gradient(circle at 8% 0, rgba(208, 120, 80, .12), transparent 28%),
    color-mix(in srgb, #091923 94%, transparent) !important;
  border: 0 !important;
  border-bottom: 1px solid rgba(255, 255, 255, .1) !important;
  box-shadow: 0 14px 45px rgba(4, 16, 23, .15);
  backdrop-filter: blur(24px) saturate(1.12);
  -webkit-backdrop-filter: blur(24px) saturate(1.12);
}

.cp-site-header {
  position: sticky;
  top: 0;
}

.cp-pro-header > .cp-brand-lockup {
  --cp-brand-color: #f3f7f7;
  --cp-brand-muted: #8e9aa5;
  flex: 0 0 auto;
}

.cp-pro-header .cp-header-primary,
.cp-pro-header .cp-header-local {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 2.1vw, 34px);
  min-width: 0;
  margin: 0 auto;
}

.cp-pro-header .cp-header-local {
  flex: 1 1 auto;
}

.cp-pro-header .cp-header-primary a,
.cp-pro-header .cp-header-local a,
.cp-pro-header .cp-header-local button {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  margin: 0;
  padding: 0;
  border: 0;
  color: #bac6ca !important;
  background: transparent !important;
  box-shadow: none !important;
  font-family: var(--cp-font-sans);
  font-size: 12px;
  font-weight: 650;
  line-height: 1;
  letter-spacing: .015em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.cp-pro-header .cp-header-primary a::after,
.cp-pro-header .cp-header-local a::after {
  content: "";
  position: absolute;
  right: 50%;
  bottom: 2px;
  left: 50%;
  height: 1px;
  background: var(--cp-copper-300);
  transition: right .25s var(--cp-ease), left .25s var(--cp-ease);
}

.cp-pro-header .cp-header-primary a:hover,
.cp-pro-header .cp-header-local a:hover,
.cp-pro-header .cp-header-local button:hover {
  color: #fff !important;
}

.cp-pro-header .cp-header-primary a:hover::after,
.cp-pro-header .cp-header-local a:hover::after {
  right: 0;
  left: 0;
}

.cp-header-utility {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-left: auto;
}

.cp-header-live,
.cp-header-theme,
.cp-header-menu,
.cp-header-book {
  box-sizing: border-box;
  min-height: 42px;
  border: 1px solid rgba(255, 255, 255, .13);
  border-radius: 12px;
  color: #dce5e7;
  background: rgba(255, 255, 255, .045);
}

.cp-header-live {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  font-size: 9px;
  font-weight: 650;
  letter-spacing: .075em;
  text-transform: uppercase;
  white-space: nowrap;
}

.cp-header-live .cp-live-dot {
  width: 7px;
  height: 7px;
  flex-basis: 7px;
}

.cp-header-live[data-state="live"] .cp-live-dot {
  background: #57c79b;
  box-shadow: 0 0 0 5px rgba(87, 199, 155, .12);
}

.cp-header-live[data-state="offline"] .cp-live-dot {
  background: #e2675d;
  box-shadow: 0 0 0 5px rgba(226, 103, 93, .12);
}

.cp-header-theme,
.cp-header-menu {
  display: inline-grid;
  width: 42px;
  place-items: center;
  padding: 0;
  font: inherit;
  cursor: pointer;
}

.cp-header-theme {
  font-size: 16px;
}

.cp-header-theme:hover,
.cp-header-menu:hover {
  border-color: rgba(239, 179, 153, .46);
  background: rgba(208, 120, 80, .12);
}

.cp-header-menu {
  gap: 4px;
  align-content: center;
}

.cp-header-menu span {
  display: block;
  width: 16px;
  height: 1.5px;
  border-radius: 3px;
  background: currentColor;
  transition: transform .2s var(--cp-ease), opacity .2s var(--cp-ease);
}

.cp-menu-open .cp-header-menu span:nth-child(1) {
  transform: translateY(5.5px) rotate(45deg);
}

.cp-menu-open .cp-header-menu span:nth-child(2) {
  opacity: 0;
}

.cp-menu-open .cp-header-menu span:nth-child(3) {
  transform: translateY(-5.5px) rotate(-45deg);
}

.cp-header-book {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-width: 122px;
  justify-content: center;
  padding: 0 17px;
  border-color: transparent;
  color: #fff !important;
  background: linear-gradient(135deg, var(--cp-copper-500), var(--cp-copper-600));
  box-shadow: 0 10px 25px rgba(184, 95, 61, .22);
  font-size: 11px;
  font-weight: 750;
  text-decoration: none;
  white-space: nowrap;
}

.cp-header-book span {
  font-size: 14px;
}

.cp-header-book:hover {
  transform: translateY(-1px);
  box-shadow: 0 13px 30px rgba(184, 95, 61, .32);
}

.cp-mobile-menu {
  position: absolute;
  z-index: 10030;
  top: calc(100% + 1px);
  right: clamp(14px, 4.2vw, 72px);
  width: min(540px, calc(100vw - 28px));
  padding: 24px;
  overflow: hidden;
  color: #eef4f4;
  background:
    radial-gradient(circle at 100% 0, rgba(208, 120, 80, .16), transparent 38%),
    #0b222d;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 0 0 20px 20px;
  box-shadow: 0 30px 80px rgba(3, 15, 21, .38);
}

.cp-mobile-menu[hidden] {
  display: none !important;
}

.cp-mobile-menu-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding-bottom: 17px;
  border-bottom: 1px solid rgba(255, 255, 255, .1);
}

.cp-mobile-menu-head b {
  font-family: var(--cp-font-display);
  font-size: 15px;
  letter-spacing: .02em;
}

.cp-mobile-menu-head span {
  color: #8ea0a6;
  font-size: 9px;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.cp-mobile-primary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 7px;
  padding: 16px 0;
}

.cp-mobile-primary a {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 0 14px;
  color: #d8e2e4 !important;
  background: rgba(255, 255, 255, .045);
  border: 1px solid rgba(255, 255, 255, .07);
  border-radius: 10px;
  font-size: 12px;
  font-weight: 650;
  text-decoration: none;
}

.cp-mobile-primary a:hover {
  color: #fff !important;
  background: rgba(208, 120, 80, .12);
  border-color: rgba(208, 120, 80, .28);
}

.cp-mobile-support {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, .1);
}

.cp-mobile-support a {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: #eef4f4 !important;
  font-size: 11px;
  font-weight: 650;
  text-decoration: none;
}

.cp-mobile-support a span {
  color: var(--cp-copper-300);
  font-size: 9px;
  font-weight: 500;
}

footer.cp-pro-footer {
  position: relative !important;
  z-index: 10;
  display: block !important;
  box-sizing: border-box;
  width: 100% !important;
  height: auto !important;
  min-height: 0 !important;
  margin: 0 !important;
  padding: clamp(48px, 7vw, 96px) clamp(20px, 5vw, 88px) 110px !important;
  overflow: hidden;
  color: #e9eff0 !important;
  background:
    radial-gradient(circle at 8% 12%, rgba(208, 120, 80, .14), transparent 26%),
    radial-gradient(circle at 92% 15%, rgba(82, 123, 112, .12), transparent 24%),
    linear-gradient(145deg, #071923, #0c2732 56%, #081b25) !important;
  border: 0 !important;
  border-top: 1px solid rgba(255, 255, 255, .09) !important;
  text-align: left !important;
}

footer.cp-pro-footer::before {
  content: "";
  position: absolute;
  top: 0;
  right: 5vw;
  left: 5vw;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(208, 120, 80, .65), transparent);
}

.cp-footer-shell {
  display: grid;
  grid-template-columns: minmax(250px, 1.55fr) repeat(3, minmax(125px, .72fr)) minmax(245px, 1.2fr);
  gap: clamp(28px, 4vw, 68px);
  max-width: 1540px;
  margin: 0 auto;
}

.cp-footer-intro {
  max-width: 360px;
}

.cp-footer-intro .cp-brand-lockup {
  --cp-brand-color: #f4f7f8;
  --cp-brand-muted: #89979f;
  margin-bottom: 22px;
}

.cp-footer-intro p {
  max-width: 330px;
  margin: 0 0 24px;
  color: #96a7ac;
  font-size: 12px;
  line-height: 1.8;
}

.cp-footer-trust {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.cp-footer-trust span {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 30px;
  padding: 0 10px;
  color: #b9c6c9;
  background: rgba(255, 255, 255, .045);
  border: 1px solid rgba(255, 255, 255, .075);
  border-radius: 999px;
  font-size: 8px;
  font-weight: 650;
  letter-spacing: .055em;
  text-transform: uppercase;
}

.cp-footer-trust i {
  color: #63c8a3;
  font-style: normal;
}

.cp-footer-column {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 13px;
  padding-top: 7px;
}

.cp-footer-column b,
.cp-footer-label {
  margin-bottom: 8px;
  color: var(--cp-copper-300);
  font-family: var(--cp-font-display);
  font-size: 9px;
  font-weight: 650;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.cp-footer-column a,
.cp-footer-contact > a:not(.cp-footer-whatsapp),
.cp-footer-bottom a {
  color: #a8b7bb !important;
  font-size: 11px;
  line-height: 1.4;
  text-decoration: none;
}

.cp-footer-column a:hover,
.cp-footer-contact > a:hover,
.cp-footer-bottom a:hover {
  color: #fff !important;
}

.cp-footer-contact {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 7px 0 0 clamp(0px, 2vw, 32px);
  border-left: 1px solid rgba(255, 255, 255, .09);
}

.cp-footer-contact h2 {
  margin: 8px 0 20px;
  color: #f2f5f6;
  font-family: var(--cp-font-display);
  font-size: clamp(23px, 2.1vw, 34px);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -.025em;
}

.cp-footer-whatsapp {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  width: 100%;
  min-height: 46px;
  margin-bottom: 16px;
  padding: 0 15px;
  color: #fff !important;
  background: rgba(208, 120, 80, .14);
  border: 1px solid rgba(208, 120, 80, .34);
  border-radius: 10px;
  font-size: 11px;
  font-weight: 700;
  text-decoration: none;
}

.cp-footer-whatsapp:hover {
  background: rgba(208, 120, 80, .23);
  transform: translateY(-1px);
}

.cp-footer-contact address {
  margin-top: 13px;
  color: #788c92;
  font-size: 10px;
  font-style: normal;
  line-height: 1.65;
}

.cp-footer-bottom {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  margin-top: 10px;
  padding-top: 24px;
  color: #6f8389;
  border-top: 1px solid rgba(255, 255, 255, .09);
  font-size: 9px;
  letter-spacing: .025em;
}

.cp-footer-bottom nav {
  display: flex;
  gap: 20px;
}

.cp-footer-live {
  display: inline-flex;
  align-items: center;
  justify-self: end;
  gap: 8px;
  color: #91aaa9;
  font-size: 9px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.cp-footer-live i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #57c79b;
  box-shadow: 0 0 0 5px rgba(87, 199, 155, .11);
}

.cp-footer-legacy {
  max-width: 1540px;
  margin: 18px auto 0;
  color: #71858b;
  font-size: 9px;
}

.cp-footer-legacy summary {
  width: max-content;
  padding: 5px 0;
  color: #7f9399;
  cursor: pointer;
  letter-spacing: .04em;
}

.cp-footer-legacy-body {
  margin-top: 10px;
  padding: 15px;
  background: rgba(255, 255, 255, .025);
  border: 1px solid rgba(255, 255, 255, .06);
  border-radius: 10px;
}

.cp-footer-legacy-body .cp-brand-lockup,
.cp-footer-legacy-body .footer-brand,
.cp-footer-legacy-body > .brand {
  display: none !important;
}

.cp-embedded .cp-pro-header,
.cp-embedded footer.cp-pro-footer {
  display: none !important;
}

@media (max-width: 1280px) {
  .cp-footer-shell {
    grid-template-columns: minmax(250px, 1.5fr) repeat(3, minmax(115px, .7fr));
  }

  .cp-footer-contact {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: 1.25fr 1fr 1fr;
    gap: 18px 28px;
    align-items: end;
    padding: 26px 0 0;
    border-top: 1px solid rgba(255, 255, 255, .09);
    border-left: 0;
  }

  .cp-footer-contact .cp-footer-label,
  .cp-footer-contact h2 {
    grid-column: 1;
  }

  .cp-footer-contact h2 {
    grid-row: 2 / span 3;
    margin: 0;
  }

  .cp-footer-contact .cp-footer-whatsapp {
    grid-column: 2;
    grid-row: 2;
    margin: 0;
  }

  .cp-footer-contact > a:not(.cp-footer-whatsapp),
  .cp-footer-contact address {
    grid-column: 3;
    margin: 0;
  }
}

@media (max-width: 1060px) {
  .cp-pro-header .cp-header-local {
    display: none !important;
  }

  .cp-pro-header.cp-has-local {
    justify-content: flex-start;
  }
}

@media (max-width: 860px) {
  .cp-pro-header {
    min-height: 70px;
    padding: 9px 16px !important;
  }

  .cp-pro-header > .cp-brand-lockup {
    margin-right: auto;
  }

  /* Hide only the INJECTED nav on small screens (the hamburger replaces it).
     A page's OWN header controls — Book, Manage my stay, EN/AR — must stay,
     otherwise citihome.html loses its whole mobile header. */
  .cp-pro-header .cp-header-primary {
    display: none !important;
  }

  .cp-header-live,
  .cp-header-book {
    display: none;
  }

  .cp-header-utility {
    gap: 6px;
    margin-left: 0;
  }

  .cp-mobile-menu {
    right: 10px;
  }

  .cp-footer-shell {
    grid-template-columns: repeat(2, 1fr);
  }

  .cp-footer-intro,
  .cp-footer-contact,
  .cp-footer-bottom {
    grid-column: 1 / -1;
  }

  .cp-footer-intro {
    max-width: none;
  }

  .cp-footer-contact {
    display: flex;
    align-items: flex-start;
  }

  .cp-footer-contact h2 {
    margin: 8px 0 18px;
  }

  .cp-footer-contact .cp-footer-whatsapp {
    width: min(100%, 360px);
    margin-bottom: 14px;
  }

  .cp-footer-bottom {
    grid-template-columns: 1fr;
    justify-items: start;
  }

  .cp-footer-live {
    justify-self: start;
  }
}

@media (max-width: 520px) {
  /* THE CONNECTOR IS NOT WHAT GETS DROPPED.
     This hid "Affiliate by" on the narrowest screens, which left a CitiHome mark
     beside an unexplained Concept Plus mark — two unrelated logos, on the width
     where most guests arrive. The founder's instruction is to stack them instead,
     which the rule at 560px already does; this only has to stop hiding the line
     that carries the whole meaning of the lockup. */
  .cp-pro-header > .cp-brand-lockup .cp-brand-affiliate {
    display: block !important;
  }

  .cp-pro-header > .cp-brand-lockup .cp-brand-wordmark {
    width: 92px !important;
  }

  .cp-pro-header > .cp-brand-lockup .cp-brand-symbol {
    flex-basis: 30px !important;
    width: 30px !important;
  }

  .cp-pro-header > .cp-brand-lockup .cp-brand-symbol img {
    width: 28px !important;
    height: 31px !important;
  }

  .cp-mobile-menu {
    top: 100%;
    right: 8px;
    width: calc(100vw - 16px);
    padding: 18px;
    border-radius: 0 0 16px 16px;
  }

  .cp-mobile-menu-head span {
    display: none;
  }

  .cp-mobile-primary,
  .cp-mobile-support {
    grid-template-columns: 1fr;
  }

  footer.cp-pro-footer {
    padding: 44px 18px 100px !important;
  }

  .cp-footer-shell {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  .cp-footer-intro,
  .cp-footer-column,
  .cp-footer-contact,
  .cp-footer-bottom {
    grid-column: 1;
  }

  .cp-footer-column {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px 18px;
    padding-top: 20px;
    border-top: 1px solid rgba(255, 255, 255, .08);
  }

  .cp-footer-column b {
    grid-column: 1 / -1;
  }
}

@media print {
  .cp-header-utility,
  .cp-mobile-menu,
  footer.cp-pro-footer {
    display: none !important;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
 * 2026-08-05 — THEME-AWARE INKS (Item A)
 *
 * Measured, not assumed. The previous session's probe reported 59 light-mode
 * failures on club.html and blamed "dark tokens leaking into light". Re-measured
 * with a corrected probe — one that parses `color(srgb …)` (Chrome now serves
 * the header background in that form, and the old parser dropped it, so every
 * element in the dark header was scored against the white page behind it) and
 * that treats an opaque linear-gradient as a real surface instead of walking
 * past it to the body — the true count is 26, and --cp-ink resolves correctly
 * in both themes. The real defects are a small set of INKS that were picked
 * against one surface and then used on another. Fixed here at the token level.
 *
 * Every value below was computed against the surface it actually lands on;
 * the ratio is in the comment. Target 4.5:1 (3:1 for large text).
 * ════════════════════════════════════════════════════════════════════════════ */
:root {
  /* #68777d measured 4.45:1 on --cp-sand-50 — under the bar by a hair, and it is
     the body-copy ink on every public page, so it was the single most-repeated
     failure. #606e75 is the same hue, 5.05:1. */
  --cp-muted: #606e75;

  /* Gold and sage were only ever readable as *fills*. Used as text they run
     3.0–4.4:1. These are the ink-grade members of the same families. */
  --cp-gold-ink: #7d611f;   /* 5.59:1 on sand-50 */
  --cp-green-ink: #3f6459;  /* 6.08:1 on a light card */

  /* Ink for text sitting on the copper accent fill. */
  --cp-on-accent: #fff;
}

:root[data-theme="dark"] {
  --cp-gold-ink: #d8b667;   /* 8.07:1 on --cp-sand-100 dark */
  --cp-green-ink: #8fbfae;  /* 8.42:1 on --cp-sand-50 dark */
}

/* The primary button. White on --cp-copper-500 is 3.24:1 — it failed on EVERY
   page in both themes, which is why it kept showing up in every sweep. Neither
   pure white nor navy clears 4.5:1 across the old 500→600 gradient, so the fill
   itself moves one step deeper into the same copper family; white then measures
   5.09:1 at the light end and 6.61:1 at the dark end. Same button, same brand. */
:where(.primary, .primary-button, .solid-button, .btn-gold, .search-button, .button-primary) {
  background: linear-gradient(135deg, #ad5533, #964526) !important;
  color: var(--cp-on-accent) !important;
}

/* The shared footer is dark in both themes by design, so these greys never
   flipped — they were simply too dark for it. */
.cp-footer-contact address { color: #95a9af; }   /* 4.41 → 6.34:1 */
.cp-footer-bottom { color: #8ea3a9; }            /* 3.91 → 5.89:1 */
.cp-footer-legacy { color: #8ea3a9; }            /* 3.77 → 5.52:1 */
.cp-footer-legacy summary { color: #9db1b7; }    /* 3.08 → 6.4:1  */

/* --cp-accent was tuned against --cp-sand-50 (#fbfaf7) and measures 4.46:1 on
   --cp-sand-100 (#f5f1e9), the cream panel the eyebrows actually sit on. One
   step deeper clears both surfaces. */
:root { --cp-accent: #9f4a08; }

/* Item A2, from the chos.html sweep: the footer's own band is lighter than the
   page footer these greys were tuned against, so they came back under the bar
   there — 3.86:1 for the affiliate line and 4.40:1 for the copyright. */
.cp-footer-shell .cp-brand-affiliate { color: #a9b8be !important; }
.cp-footer-shell .cp-footer-bottom,
.cp-footer-shell .cp-footer-bottom span { color: #a9b8be; }

/* Performance/a11y baseline: a visible keyboard position is shared by every
   operational PWA, including controls whose component stylesheet removed the
   browser outline. Keep mouse focus visually quiet via :focus-visible. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--cp-focus-ring) !important;
  outline-offset: var(--cp-focus-ring-offset) !important;
}

/* Dialog content remains reachable on short phones and does not scroll the
   page underneath it. This also protects the last action from bottom-nav
   occlusion. */
:where([role="dialog"], .modal-card, .dialog-card, .sheet-card) {
  max-block-size: min(90dvh, 760px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-padding-block-end: 24px;
}

@media (pointer: coarse), (max-width: 760px) {
  :where(button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"], .modal-close, .drawer-close, .mobile-nav a, .mobile-nav button, .bottom-nav a, .bottom-nav button) {
    min-inline-size: 44px;
    min-block-size: 44px;
  }

  :where(main, .view, .page-content) {
    scroll-padding-block-end: calc(88px + env(safe-area-inset-bottom));
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    scroll-behavior: auto !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
 * THE INTERACTION SYSTEM  —  2026-08-12
 *
 * The complaint was that "the mouse styling is not like the rest of the places
 * and it changes". It was correct, and it was measurable. Sweeping every
 * stylesheet and inline <style> in public/ turned up 275 interaction-state
 * rules carrying 143 distinct hover treatments, 19 distinct focus treatments,
 * 8 distinct disabled treatments, 10 distinct selected treatments, 21 distinct
 * transition durations and 5 distinct easing curves. The same button did not
 * feel like the same button twice. Full ledger in docs/INTERACTION-AUDIT.md.
 *
 * This block is the single definition. Everything below is a token; component
 * styles consume the token rather than inventing a value. Adding a new lift
 * distance or a new focus ring colour is now a change to this block, which is
 * the point — variation has to be argued for in one place instead of drifting
 * in thirty.
 *
 * Rules that are not negotiable and are encoded here rather than remembered:
 *   · no state is signalled by colour alone — disabled also drops its pointer
 *     affordance and its hover response, selected also carries a marker rail
 *     and a weight change;
 *   · the keyboard ring is :focus-visible and is never removed, only replaced;
 *   · prefers-reduced-motion turns the transitions off, not down;
 *   · every token is defined for both themes.
 * ════════════════════════════════════════════════════════════════════════════ */
:root {
  /* Motion. One duration for controls, one for surfaces, one curve.
     Replaces 21 durations spanning .09s–.55s and 5 different curves. */
  --cp-dur: .18s;
  --cp-dur-lg: .26s;
  /* --cp-ease is defined at the top of this file; it stays the one curve. */

  /* Hover. A hover is a 6% ink wash, a firmer edge and, on a card-sized
     surface, a single 1px lift. Not 13 lift distances and 24 shadows. */
  --cp-hover-bg: color-mix(in srgb, var(--cp-ink) 6%, transparent);
  --cp-hover-bg-strong: color-mix(in srgb, var(--cp-ink) 10%, transparent);
  --cp-hover-border: color-mix(in srgb, var(--cp-ink) 26%, transparent);
  --cp-hover-ink: var(--cp-accent);
  --cp-hover-lift: -1px;
  --cp-hover-shadow: var(--cp-shadow-sm);

  /* Focus. One ring, keyboard only, always visible, never merely a colour. */
  /* The old light ring was copper-500 mixed 65% into white — 2.4:1 against the
     white and sand surfaces it is drawn on, i.e. a focus ring you had to look
     for. This is the same copper family two steps deeper, 4.9:1 on white and
     4.5:1 on --cp-sand-100, clearing the 3:1 bar for a non-text indicator with
     room to spare. */
  --cp-focus-ring-color: #a5502f;
  --cp-focus-ring-width: 3px;
  --cp-focus-ring-offset: 3px;
  --cp-focus-ring: var(--cp-focus-ring-width) solid var(--cp-focus-ring-color);
  /* The inner halo a text field wears while it holds the caret. */
  --cp-focus-halo: 0 0 0 4px color-mix(in srgb, var(--cp-copper-500) 16%, transparent);

  /* Press. One depth. Replaces scale(.97)/(.985)/(.99). */
  --cp-press-scale: .985;
  --cp-press-shift: 1px;

  /* Disabled. One opacity for controls, replacing .35/.42/.45/.5/.55/.6/.65/.72.
     A whole card carrying body copy is a second case and gets its own named
     value rather than a one-off: .45 on a control is dim, on a paragraph it is
     unreadable. Two tokens, both named here, is still one system. */
  --cp-disabled-opacity: .45;
  --cp-disabled-opacity-surface: .68;

  /* Selected. Fill plus a 3px marker rail plus a weight step, so the state
     survives a monochrome screen and a colour-blind reader. */
  --cp-selected-bg: color-mix(in srgb, var(--cp-copper-500) 12%, transparent);
  --cp-selected-ink: var(--cp-accent);
  --cp-selected-border: color-mix(in srgb, var(--cp-copper-500) 55%, transparent);
  --cp-selected-marker: var(--cp-copper-600);
  --cp-selected-weight: 650;
}

:root[data-theme="dark"] {
  /* On a dark surface an ink wash is invisible; the wash inverts to light.
     Same perceptual weight, opposite direction. */
  --cp-hover-bg: color-mix(in srgb, #fff 8%, transparent);
  --cp-hover-bg-strong: color-mix(in srgb, #fff 13%, transparent);
  --cp-hover-border: color-mix(in srgb, #fff 30%, transparent);
  --cp-focus-ring-color: #d8b667;
  --cp-focus-halo: 0 0 0 4px color-mix(in srgb, #d8b667 22%, transparent);
  --cp-selected-bg: color-mix(in srgb, var(--cp-copper-500) 22%, transparent);
  --cp-selected-border: color-mix(in srgb, var(--cp-copper-300) 45%, transparent);
  --cp-selected-marker: var(--cp-copper-300);
}

/* ── One curve, one duration ───────────────────────────────────────────────
 * This deliberately overrides only the timing sub-properties, never the
 * property list. A component keeps deciding WHAT animates; the platform
 * decides how fast and along which curve. That is the whole of the founder's
 * "it changes" — the same chip easing differently on two screens.
 * Non-interactive set pieces (hero crossfade, shimmer, marquee) are untouched
 * because they are animations or live outside this selector list. */
a,
button,
[role="button"],
[role="tab"],
[role="option"],
summary,
input,
select,
textarea,
label,
.chip,
.tab,
.pill,
.card,
.panel,
.metric-card,
.job-card,
.offer-card,
.stay-card,
.request-card,
.home-card,
.dashboard-panel {
  transition-duration: var(--cp-dur) !important;
  transition-timing-function: var(--cp-ease) !important;
}

/* Surfaces are large, so they get the slower of the two durations —
   one deliberate exception, named here rather than scattered. */
.card,
.panel,
.metric-card,
.job-card,
.offer-card,
.stay-card,
.request-card,
.home-card,
.dashboard-panel {
  transition-duration: var(--cp-dur-lg) !important;
}

/* ── Hover ─────────────────────────────────────────────────────────────────
 * Baseline only, at :where() specificity, so a component that has a reason to
 * differ still wins. What it guarantees is that anything WITHOUT a hover rule
 * gets the same one as everything else instead of nothing. */
:where(button, [role="button"], .chip, .tab, .pill):not(:disabled):not([aria-disabled="true"]):hover {
  background-color: var(--cp-hover-bg);
  border-color: var(--cp-hover-border);
}

:where(.card, .panel, .dashboard-panel, .metric-card, .job-card, .service, .offer-card, .home-card):hover {
  box-shadow: var(--cp-hover-shadow);
  transform: translateY(var(--cp-hover-lift));
}

/* ── Focus ─────────────────────────────────────────────────────────────────
 * :focus-visible, never :focus, so a mouse click does not paint a ring but a
 * Tab key always does. The !important is load-bearing: platform.css is linked
 * BEFORE the panel stylesheets on chos.html, several of which still carry an
 * `outline:none`, and a keyboard user losing their position is not a style
 * preference. */
:where(a, button, [role="button"], input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--cp-focus-ring) !important;
  outline-offset: var(--cp-focus-ring-offset) !important;
}

:where(input, select, textarea):focus-visible {
  border-color: var(--cp-copper-500) !important;
  box-shadow: var(--cp-focus-halo) !important;
}

/* ── Press ─────────────────────────────────────────────────────────────────
 * One depth for every pressable thing. A disabled control does not depress —
 * pressing something inert must not feel like it worked. */
:where(button, [role="button"], a):not(:disabled):not([aria-disabled="true"]):active {
  transform: translateY(var(--cp-press-shift)) scale(var(--cp-press-scale));
}

/* ── Disabled ──────────────────────────────────────────────────────────────
 * Three signals, never one: dimmed, cursor says no, and every hover/press
 * response is withdrawn so the control does not answer the mouse. The reason
 * text is the fourth signal and belongs to the markup — the contracts UI
 * already renders its greyed actions with a reason and no onclick, and that
 * is the pattern, not the exception. */
:where(button, [role="button"], a, input, select, textarea, .chip, .tab, .pill):disabled,
:where(button, [role="button"], a, input, select, textarea, .chip, .tab, .pill)[aria-disabled="true"],
:where(.is-disabled, .disabled) {
  opacity: var(--cp-disabled-opacity);
  cursor: not-allowed;
}

:where(button, [role="button"], a, .chip, .tab, .pill):disabled:hover,
:where(button, [role="button"], a, .chip, .tab, .pill)[aria-disabled="true"]:hover,
:where(.is-disabled, .disabled):hover {
  background-color: inherit;
  border-color: inherit;
  box-shadow: none;
  transform: none;
  filter: none;
}

/* ── Selected ──────────────────────────────────────────────────────────────
 * Fill, rail and weight together. The rail is what makes the state legible
 * when the fill is the only thing a colour-blind reader cannot resolve. */
:where([aria-selected="true"], [aria-current="true"], [aria-current="page"], .is-selected, .cp-selected) {
  background-color: var(--cp-selected-bg);
  color: var(--cp-selected-ink);
  border-color: var(--cp-selected-border);
  font-weight: var(--cp-selected-weight);
}

/* Vertical lists get an inline-start rail; horizontal segments get an
   underline. Same idea, correct axis. */
:where(li, tr, .row, .list-row, .nav-item)[aria-selected="true"],
:where(li, tr, .row, .list-row, .nav-item)[aria-current="true"],
:where(li, tr, .row, .list-row, .nav-item).is-selected {
  box-shadow: inset 3px 0 0 0 var(--cp-selected-marker);
}

:where([role="tab"], .tab, .segment, .seg-btn)[aria-selected="true"],
:where([role="tab"], .tab, .segment, .seg-btn)[aria-current="true"],
:where([role="tab"], .tab, .segment, .seg-btn).is-selected {
  box-shadow: inset 0 -3px 0 0 var(--cp-selected-marker);
}

/* ── Reduced motion ────────────────────────────────────────────────────────
 * Off, not merely quick. The two blocks above set transition timing with
 * !important, so the opt-out has to answer at the same weight. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: .001ms !important;
    transition-delay: 0ms !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }

  :where(button, [role="button"], a):active,
  :where(.card, .panel, .dashboard-panel, .metric-card, .job-card, .offer-card, .home-card):hover {
    transform: none;
  }
}

/* ── THE CONSOLE HEADER DREW ITS CONTROLS ON TOP OF ITS OWN TITLE ─────────
 * Photographed by the founder on a real iPhone against the live console. On
 * "Owner desk — one owner, every panel" the moon button was painted OVER the
 * wrapped title text, the search box sat inside the title block, and the bell
 * and the avatar hung below the header onto the page content. On "Contract
 * reconciliation — signed terms against what we bill on" the title took five
 * lines and the same controls landed on it. Four screens, one row.
 *
 * THE MECHANISM, not a guess: the console header is `.topbar` — a flex row
 * with NO flex-wrap, holding the title block and `.tb-actions`. `.tb-actions`
 * carries `min-width:0` (added so the row could shrink instead of scrolling
 * the whole page sideways at 900px) and contains `.search-box` at a hard
 * `width:280px`. At 375px the row has ~319px to give. The title block asks for
 * its share, `.tb-actions` is allowed to shrink to nothing — and its children
 * do NOT shrink with it: they overflow their own box, leftwards over the
 * title and downwards past the header's bottom edge onto the content. Every
 * artefact in those photos is that one overflow.
 *
 * THE FIX IS A SECOND LINE, NOT A SMALLER CONTROL. Below the tablet
 * breakpoint the title takes a full row of its own and `.tb-actions` takes the
 * next one, so a long title can wrap as far as it likes without shortening the
 * controls' row by a single pixel — no title length can push a control off
 * screen or onto another. The search box stops declaring a width the viewport
 * cannot honour and takes a line when it needs one. The header stays sticky
 * and stays IN FLOW, so its real height — however many lines the title took —
 * is space the content below already starts after; nothing to measure, unlike
 * the fixed dock above.
 *
 * `:has()` keeps this to the console header. `.topbar` is also the class on
 * the amenities/operations/field topbars, which are a brand + links row and
 * are not broken; `.tb-actions` exists only on the console. */
@media (max-width: 860px) {
  .topbar:has(> .tb-actions) {
    flex-wrap: wrap;
    align-items: flex-start;
    row-gap: 10px;
  }

  .topbar:has(> .tb-actions) > *,
  .topbar > .tb-actions {
    flex: 1 1 100%;
    min-width: 0;
  }

  .topbar > .tb-actions {
    justify-content: flex-start;
    row-gap: 10px;
  }

  /* The 280px that could not fit. Auto width lets it take the row's remainder,
     and a full basis when the buttons beside it leave less than 180px. */
  .topbar > .tb-actions > .search-box {
    flex: 1 1 180px;
    width: auto;
  }

  /* A title is one long unbroken word away from overflowing a 375px column
     (a URL, a unit reference); it must break rather than widen the row. */
  .topbar h2 {
    overflow-wrap: anywhere;
  }
}
