/* ux-overrides.css: loaded last in the site.css bundle so these rules win
   the cascade. Post-launch UX-audit fixes: mobile fold, tap targets, and a
   more compact cookie banner. Keep this file human-readable (not minified);
   it is concatenated after styles.css by scripts/build.js. */

/* Mobile header: the social-icon row is duplicated in the footer, so hiding
   it on small screens reclaims the fold for real content. */
@media (max-width: 768px) {
  header .nav-social { display: none; }

  /* Thumb-friendly nav pills (were ~26px tall). */
  header nav ul li a {
    padding: 9px 14px;
    font-size: 14px;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
  }
  header nav > .logo-link { margin-bottom: 4px; }
  .logo-img { height: 34px; }
}

/* ── Compact mobile header + menu sheet ───────────────────────────────────
   js/ui.js (nav module) adds .mnav-header / nav.mnav and a [hidden] row of
   call, search and Menu buttons. Every rule is scoped to those classes, so a
   page without JS keeps the full wrapped link list. Target: one row, under
   72px tall on a 390px phone (it was ~235px of stacked pills). The breakpoint
   matches MQ in js/ui.js. */
.mnav-scrim[hidden],
.mnav-bar[hidden] {
  display: none;
}

@media (max-width: 959px) {
  header.mnav-header {
    min-height: 0;
  }
  header.mnav-header .container,
  header.mnav-header nav.mnav {
    position: static;
  }
  header.mnav-header nav.mnav,
  header.cin-scrolled nav.mnav {
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 0;
  }
  header.mnav-header nav.mnav > .logo-link {
    margin: 0;
    flex: 0 1 auto;
    min-width: 0;
  }
  header.mnav-header nav.mnav .logo-img,
  header.cin-scrolled nav.mnav .logo-img {
    height: 40px;
    width: auto;
  }
  header.mnav-header nav.mnav > .mnav-bar[hidden] {
    display: flex;
  }
  header.mnav-header nav.mnav > .mnav-bar {
    align-items: center;
    gap: 4px;
    margin-left: auto;
    flex: 0 0 auto;
  }
  /* The palette's own header button becomes the row's search icon. */
  header.mnav-header nav.mnav > .sp-navbtn,
  header.mnav-header nav.mnav > .ss-navbtn {
    display: none;
  }
  header.mnav-header nav.mnav > ul {
    display: none;
  }

  header.mnav-header nav.mnav .mnav-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-width: 44px;
    height: 44px;
    padding: 0 10px;
    margin: 0;
    border: 1px solid transparent;
    border-radius: var(--r-sm, 8px);
    background: none;
    color: var(--ink);
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
  }
  header.mnav-header nav.mnav .mnav-btn svg {
    display: block;
    fill: currentColor;
  }
  header.mnav-header nav.mnav .mnav-call {
    color: var(--link);
  }
  header.mnav-header nav.mnav .mnav-toggle {
    border-color: var(--border);
    padding: 0 12px;
  }
  header.mnav-header nav.mnav .mnav-btn:hover {
    background: var(--surface-2);
  }

  /* The sheet: the page's own link list, hung from the bottom edge of the
     sticky header (absolute, not fixed: header.cin-scrolled carries a
     backdrop-filter, which would re-anchor a fixed child to the header). */
  header.mnav-header nav.mnav.mnav-open > ul {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 2;
    margin: 0;
    padding: 4px 16px 20px;
    list-style: none;
    background: var(--surface);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 12px 28px var(--shadow-tint-3);
    max-height: calc(100vh - var(--mnav-top, 60px));
    max-height: calc(100dvh - var(--mnav-top, 60px));
    overflow-y: auto;
    overscroll-behavior: contain;
    opacity: 1;
  }
  header.mnav-header nav.mnav.mnav-open > ul > li > a {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 48px;
    padding: 12px 4px;
    font-size: 17px;
    font-weight: 600;
    color: var(--ink);
    background: none;
    border-radius: 0;
    border-bottom: 1px solid var(--border);
    white-space: normal;
  }
  header.mnav-header nav.mnav.mnav-open > ul > li > a[aria-current='page'] {
    color: var(--link);
    box-shadow: inset 3px 0 0 var(--link);
    padding-left: 12px;
  }
  header.mnav-header nav.mnav.mnav-open > ul > li > a[aria-current='page']::after {
    content: none;
  }
  header.mnav-header nav.mnav.mnav-open > ul > li.nav-phone > a {
    color: var(--link);
    font-weight: 700;
  }
  header.mnav-header nav.mnav.mnav-open > ul > li.nav-social {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 12px 0 0;
  }
  header.mnav-header nav.mnav.mnav-open > ul > li.nav-social > a {
    width: 44px;
    min-height: 44px;
    padding: 0;
    justify-content: center;
    border: 0;
  }
  header.mnav-header nav.mnav > .mnav-scrim {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: 100vh;
    z-index: 1;
    background: var(--overlay);
  }
}

html.mnav-locked,
html.mnav-locked body {
  overflow: hidden;
}
/* While the menu sheet is open nothing floats over it. */
html.mnav-locked #as-chat-btn,
html.mnav-locked #mobile-sticky-cta,
html.mnav-locked #fz-music-player,
html.mnav-locked #theme-switcher,
html.mnav-locked .back-to-top {
  visibility: hidden;
}

/* ── Consent banner: a compact bar, never a card over the content ─────────
   Built by js/ui.js (cookie-consent module). Desktop: one full-width bar at
   the bottom edge, copy on the left and the two choices on the right, about
   70px tall, so it no longer lands on the hero form. Phone: a bottom sheet
   with the two choices side by side. "Accept all" and "Reject all" share one
   rule and one class, so they are EQUALLY prominent (same size, weight and
   colour): that parity is a legal requirement. The reader pages lift the bar
   above their toolbar with a more specific rule in css/reader.css, which
   this one deliberately does not out-specify. */
#cookie-banner {
  left: 0;
  right: 0;
  bottom: 0;
  max-width: none;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  box-shadow: 0 -8px 28px var(--shadow-tint-2);
  overflow-y: auto;
  overscroll-behavior: contain;
}
#cookie-banner .cookie-body {
  flex: 1 1 auto;
  min-width: 0;
}
#cookie-banner .cookie-title {
  margin: 0 0 2px;
  font-size: 15px;
}
#cookie-banner .cookie-text {
  margin: 0;
}
#cookie-banner .cookie-actions {
  display: flex;
  flex-wrap: nowrap;
  gap: 12px;
  margin: 0;
}
#cookie-banner .cookie-actions .cookie-choice {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: 132px;
  min-height: 44px;
  margin: 0;
  padding: 10px 20px;
  border: 2px solid var(--primary);
  border-radius: var(--r-sm, 8px);
  background: var(--primary);
  color: var(--on-accent);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
  text-transform: none;
  box-shadow: none;
  transform: none;
}
#cookie-banner .cookie-actions .cookie-choice:hover {
  background: var(--primary-dark);
  border-color: var(--primary-dark);
}
#cookie-banner .cookie-save {
  display: inline-flex;
  align-items: center;
  width: auto;
  min-height: 40px;
  margin: 10px 0 2px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  font-weight: 700;
}

@media (min-width: 768px) {
  #cookie-banner {
    flex-wrap: nowrap;
    align-items: center;
    gap: 16px 32px;
    padding: 12px max(24px, calc((100% - 1200px) / 2)) calc(12px + env(safe-area-inset-bottom, 0px));
    max-height: 70vh;
  }
  /* Title, copy and the "Customize choices" toggle run as one paragraph,
     so the closed bar is two lines; opening the details drops them below. */
  #cookie-banner .cookie-body {
    font-size: 14px;
    line-height: 1.5;
  }
  #cookie-banner .cookie-title,
  #cookie-banner .cookie-text {
    display: inline;
    font-size: 14px;
    line-height: 1.5;
  }
  #cookie-banner .cookie-details {
    margin: 2px 0 0;
  }
  #cookie-banner .cookie-details:not([open]) {
    display: inline-block;
    width: auto;
    margin: 0 0 0 12px;
  }
  #cookie-banner .cookie-details > summary {
    padding: 2px 0;
  }
  #cookie-banner .cookie-actions {
    flex: 0 0 auto;
  }
}

@media (max-width: 767px) {
  #cookie-banner {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 10px;
    padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px));
    border-radius: 14px 14px 0 0;
    max-height: 75vh;
  }
  #cookie-banner .cookie-details {
    margin: 4px 0 0;
  }
  #cookie-banner .cookie-actions .cookie-choice {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* Collapsible consent detail keeps the first-view banner short while
   preserving full granular control behind a single tap. */
#cookie-banner .cookie-details { width: 100%; margin: 8px 0 4px; }
#cookie-banner .cookie-details > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--link);
  list-style: none;
  padding: 6px 0;
}
#cookie-banner .cookie-details > summary::-webkit-details-marker { display: none; }
#cookie-banner .cookie-details > summary::before {
  content: "\25B8\00a0";
  display: inline-block;
}
#cookie-banner .cookie-details[open] > summary::before { content: "\25BE\00a0"; }

@media (max-width: 600px) {
  #cookie-banner .cookie-text { font-size: 13px; }
}

/* Readability floor for footnote/disclaimer copy on small screens. */
@media (max-width: 768px) {
  .compliance-footer,
  .disclaimer,
  .fine-print,
  footer small,
  .footer-legal {
    font-size: 14px !important;
    line-height: 1.55;
  }
}

/* ── Accessibility: WCAG 2.1 AA contrast (axe-core findings) ──────────────
   This file is concatenated after styles.css, so equal-specificity rules
   here win. Pinned by tests/e2e/a11y.spec.js. */

/* Gold-on-pale-gold badge measured 1.85:1, one of the worst on the site.
   A deep amber keeps the brand read at 5.40:1. */
.pill {
  color: var(--on-gold);
}

/* Field-guide labels were the brand blue at opacity .7, compositing to
   #5b93d3 on white (3.20:1). Full opacity restores 5.75:1; the visual
   hierarchy is already carried by the 10px uppercase treatment. */
.fg-label {
  opacity: 1;
}

/* The privacy link sat inside muted grey body copy at 1.18:1 relative to it,
   with no underline, so colour alone marked it as a link (WCAG 1.4.1). */
.jit-disclaimer a {
  text-decoration: underline;
}

/* Brand gold on the light page background measured 2.18:1. The eyebrow is a
   12px uppercase label, so it needs the full 4.5:1. Element+class outranks
   the resources.css rule, which is loaded after this bundle. --on-gold is
   the deep amber in light and a pale gold in dark, so the fix survives the
   theme instead of inverting into a second contrast failure. */
div.popular-eyebrow {
  color: var(--on-gold);
}

/* ── Sticky mobile CTA bar ────────────────────────────────────────────────
   js/mobile-cta.js injects #mobile-sticky-cta on every public page, but the
   only rules for it used to live in css/theme.css, which loads solely when
   the owner has switched display modes on. With display modes off (the
   default) the bar was injected unstyled. These rules belong in the always
   loaded bundle instead. */
#mobile-sticky-cta {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9990;
  background: var(--primary);
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -3px 16px var(--shadow-tint-3);
  transform: translateY(100%);
  transition: transform 0.3s ease;
}

#mobile-sticky-cta.visible {
  transform: translateY(0);
}

#mobile-sticky-cta .sticky-cta-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  max-width: 600px;
  margin: 0 auto;
}

#mobile-sticky-cta .sticky-cta-phone {
  color: var(--on-accent);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
}

#mobile-sticky-cta .sticky-cta-btn {
  background: var(--secondary);
  color: var(--on-secondary);
  font-weight: 700;
  font-size: 14px;
  padding: 10px 18px;
  border-radius: var(--r-sm, 8px);
  text-decoration: none;
  white-space: nowrap;
  border: none;
  cursor: pointer;
  flex-shrink: 0;
}

#mobile-sticky-cta .sticky-cta-dismiss {
  background: none;
  border: none;
  color: var(--on-accent);
  opacity: 0.75;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 6px;
  flex-shrink: 0;
}

#mobile-sticky-cta .sticky-cta-dismiss:hover {
  opacity: 1;
}

#mobile-sticky-cta a:focus-visible,
#mobile-sticky-cta button:focus-visible {
  outline: var(--focus-width, 3px) solid var(--on-accent);
  outline-offset: var(--focus-offset, 2px);
}

@media (max-width: 767px) {
  #mobile-sticky-cta {
    display: block;
  }
}

@media (min-width: 768px) {
  #mobile-sticky-cta {
    display: none !important;
  }

  .mobile-book-escape {
    display: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  #mobile-sticky-cta {
    transition: none;
  }
}

/* ── Back to top ──────────────────────────────────────────────────────────
   js/ui.js and js/page.js both toggle .is-visible, but css/styles.css only
   ever styled .visible, so the button stayed invisible on every page. Its
   position comes from the floating-widget dock in js/ui.js, which stacks it
   above the chat launcher instead of on top of it. */
.back-to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* ── Services grid with a card switched off ───────────────────────────────
   js/feature-flags.js hides the Wealth card after load when the owner has it
   off. In the auto-fit grid that left an empty cell beside the last row (3 +
   2 + a hole). It now stamps data-cards with the visible count, and the grid
   becomes a wrapping flex row whose short last row is centred. The widths
   track the auto-fit breakpoints of the original grid (280px minimum). */
.services-grid[data-cards] {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.services-grid[data-cards] > .service-card {
  flex: 0 1 100%;
  min-width: 0;
}
@media (min-width: 640px) {
  .services-grid[data-cards] > .service-card {
    flex-basis: calc((100% - 20px) / 2);
  }
}
@media (min-width: 940px) {
  .services-grid[data-cards] > .service-card {
    flex-basis: calc((100% - 40px) / 3);
  }
}

/* Consent category copy reads as body text; only the category name is bold
   (the global label weight made both lines shout). */
#cookie-banner .cookie-cat label {
  font-weight: 400;
}

/* Reader pages: css/reader.css lifts the consent bar above the reading
   toolbar (a more specific rule this file does not touch). Lifted off the
   bottom edge, an edge-to-edge strip reads as a glitch, so there it is inset
   as a floating panel instead. Same content, same two equal buttons.
   While the toolbar has stepped aside because a disclaimer is under it (the
   dock in js/ui.js sets html.dock-reader-yield), there is nothing to clear,
   so the bar stays the usual full-width strip at the bottom edge instead of
   a panel floating over the text. */
html:not(.dock-reader-yield) body[data-reader] #cookie-banner {
  left: 12px;
  right: 12px;
  border: 1px solid var(--border);
  border-radius: 14px;
}
@media (min-width: 768px) {
  html:not(.dock-reader-yield) body[data-reader] #cookie-banner {
    left: max(16px, calc((100% - 1240px) / 2));
    right: max(16px, calc((100% - 1240px) / 2));
    padding: 12px 24px;
  }
}
html.dock-reader-yield body[data-reader] #cookie-banner {
  bottom: 0;
  max-height: 75vh;
}
@media (min-width: 768px) {
  html.dock-reader-yield body[data-reader] #cookie-banner {
    max-height: 70vh;
  }
}

/* Header ground follows the theme. css/styles.css paints it translucent
   literal white and css/cinematic.css (header.cin-scrolled) does the same,
   so with dark mode on the nav text turned light on a light bar (1.03:1).
   Same translucency, drawn from the surface token; light mode is unchanged. */
header[role='banner'] {
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
}
header.cin-scrolled[role='banner'] {
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 97%, transparent);
}
