/* Styles the reference applied at RUNTIME (Embla inline styles, React-rendered
 * nodes) plus our own accessibility floor. Kept out of styles.css so the
 * vendor stylesheet stays pristine for the reskin. */

/* Embla sets this inline on the viewport; without it all 9 slides spill out */
[aria-roledescription="carousel"] .overflow {
  overflow: hidden;
}

[aria-roledescription="carousel"] .overflow > div {
  will-change: transform;
}

/* The reference does NOT dim its disabled carousel arrow - it keeps opacity 1
   and changes only the cursor. Dimming it was mine, and the scroll sweep
   caught it as a 27/27-frame divergence. */
[aria-roledescription="carousel"] button[disabled] {
  cursor: not-allowed;
}

/* Mobile menu - the reference renders no panel server-side, so this is ours.
 * ‼ Must be :not([hidden]). A bare `.ot-mobile-menu{display:flex}` has the same
 * specificity as the preflight `[hidden]{display:none}` and loads after it, so
 * it WINS and the menu renders open - it measured +125px of layout at 390. */
.ot-mobile-menu:not([hidden]) {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.75rem 0 0.25rem;
}

.ot-mobile-menu a {
  padding: 0.75rem 0.25rem;
  font-weight: 700;
  color: #1f368d;
  text-decoration: none;
  border-bottom: 1px solid rgba(31, 54, 141, 0.12);
}

.ot-mobile-menu a:hover {
  text-decoration: underline;
}

@media (min-width: 640px) {
  .ot-mobile-menu { display: none !important; }
}

/* faq.html / support.html answer blocks must obey [hidden] for the same reason */
.ot-faq-answer[hidden] { display: none !important; }

/* faq.html answer blocks */
.ot-faq-answer p { margin: 0.5rem 0; }
.ot-faq-answer { line-height: 1.6; }

/* "Straight answers" accordion - a NATIVE <details>, so it opens with JS off
 * and needs no radix runtime. These rules are ours because the compiled
 * stylesheet ships no `list-none`, no `open:` variant and no `group-open:`
 * variant: a Tailwind class that is not in the build is a silent no-op, not a
 * style, so the marker would have stayed and the chevron would never have
 * turned. Motion here is a plain transition, so the reduced-motion block below
 * already flattens it. */
.ot-q > summary {
  list-style: none;
}

.ot-q > summary::-webkit-details-marker {
  display: none;
}

.ot-q > summary::marker {
  content: "";
}

.ot-q-chev {
  transition: transform 300ms cubic-bezier(0.87, 0, 0.13, 1);
}

.ot-q[open] > summary .ot-q-chev {
  transform: rotate(180deg);
}

/* Mirrors the radix FAQ's `data-[state=open]:rounded-b-none` - the open header
 * must join its answer panel rather than float above it. */
.ot-q[open] > summary {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

/* ‼ Restore the PAGE's focus pair on the summary.
 * The theme derives --ot-focus from the surface the ring is DRAWN ON, and
 * excludes controls - `:not(a):not(button):not(input):not(select):not(textarea)
 * :not(label):not([role="button"])` - so a control's own fill cannot hijack the
 * pair. That list predates this page having any <summary>, so
 * `.bg-green-lighter:not(...)` MATCHES the summary and hands it the LIGHT-surface
 * pair (dark ink for an ice card) while the ring actually lands on the violet
 * page outside the card: measured 1.65:1, coverage 0.398, five FAILs, and the
 * near-white alt band vanished into the ice card so the gate read it 1-tone.
 * The identical radix FAQ button beside it is excluded, inherits the page pair
 * and scores 13.48:1.
 * Taken from the <details> - which carries no surface class, so it still holds
 * the page pair - rather than written as a hex, so it survives a theme change.
 * Specificity (0,3,2) beats the theme rule's (0,2,6) on the b component. */
details.ot-q {
  --ot-q-page-focus: var(--ot-focus);
  --ot-q-page-focus-alt: var(--ot-focus-alt);
}

details.ot-q > summary.ot-q-sum.bg-green-lighter {
  --ot-focus: var(--ot-q-page-focus);
  --ot-focus-alt: var(--ot-q-page-focus-alt);
}

/* Visible placeholder for content nobody has supplied yet. Same bracketed
 * convention the likeness scrub already uses ("[Reviewer name]"), plus a dotted
 * rule in currentColor - no new colour, and no reliance on colour alone - so an
 * empty company detail cannot ship unnoticed. */
.ot-tbd {
  border-bottom: 1px dotted currentColor;
}

/* ---- signal bands: the full-bleed mechanics only --------------------------
 * The COLOUR lives in themes/theme-N.css (.ot-band), so a theme change moves
 * the band with everything else and nothing here needs editing. This file
 * carries only the geometry that makes the band reach the viewport edge.
 *
 * ‼ The idiom is the page's OWN. The hero already paints past the 1024px
 * container with an absolutely-positioned `w-screen` child at a negative
 * z-index; copying it means the bands behave identically under the same
 * `main.overflow-x-clip` that already absorbs the 100vw-vs-scrollbar overhang,
 * rather than introducing a second mechanism that has to be reasoned about
 * separately.
 *
 * ‼ The wrapper declares NO padding, margin, border or width, so the section it
 * wraps keeps its own box exactly: the child's top margin still collapses
 * through it and the band starts at the section's border box, not at its
 * margin. Background extent is the only thing that changes. */
.ot-band-wrap {
  position: relative;
}

.ot-band-bg {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  /* above the fixed `.bg-green-white` page wash (-z-10), below all content */
  z-index: -1;
  pointer-events: none;
}

/* ---- sticky mobile CTA, <768px -------------------------------------------
 * ‼ It must not cover the end of the page, and "it looks fine" is not the test:
 * a fixed bar is out of flow, so the last element simply sits underneath it.
 * The reserved strip is on `main` and is the bar's real measured height, so the
 * page can always be scrolled clear of it. */
.ot-sticky-cta {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  justify-content: center;
  padding: 0.5rem 0.75rem;
  padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px));
}

/* ‼ The bar's FILL is not set here. It carries `.bg-green-light` in the markup
 * - the page register - so the theme paints it, it follows a theme change, and
 * `classify_surfaces` already lists that class as a LIGHT surface, which is
 * what hands the button's focus ring the dark tone it needs. `background:
 * inherit` was the first attempt and is wrong: the bar sits outside `main`,
 * whose parent is transparent, so it inherited transparency and the page
 * scrolled visibly underneath it. */

/* ‼ ONE constant for the strip the bar owns. It is needed in two places that
 * look unrelated and drifted apart once already:
 *   `main`'s padding keeps the bar off the end of the page AT REST
 *   `scroll-padding-bottom` keeps it off a control the browser SCROLLS TO
 * Measured, not chosen: the bar renders 68px tall at 390x844, and the focus
 * indicator adds outline-offset 2px + outline 3px outside the control's box,
 * so the strip has to clear 73px. 5.5rem = 88px. */
:root {
  --ot-sticky-cta-reserve: 5.5rem;
}

@media (max-width: 767.98px) {
  main {
    padding-bottom: var(--ot-sticky-cta-reserve);
  }

  /* ‼ WCAG 2.4.11 Focus Not Obscured. The bar is `position: fixed`, so it is
   * out of flow and sequential focus navigation does not know it is there:
   * Chrome scrolls the focused control flush to the bottom of the viewport,
   * which is precisely the strip the bar occupies. Six stops at 390px landed
   * fully underneath it, one of them a BOOK NOW.
   *
   * This is NOT a ring-styling bug and restyling the ring cannot fix it - all
   * six controls already carry `outline: 3px solid`. The ring was painted; the
   * bar was on top of it. `scroll-padding-bottom` on the scrolling box makes
   * the browser stop short by that much, so the control and its ring land above
   * the bar. Nothing moves at rest.
   *
   * The bar is OURS, not the reference's, so this defect is not inherited. */
  :root {
    scroll-padding-bottom: var(--ot-sticky-cta-reserve);
  }
}

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

/* ‼ DELIBERATE DIVERGENCE - accessibility beats pixel-match.
   The reference's focus treatment measures ~1.0:1 against the backgrounds it
   sits on, which is a WCAG 2.4.7 failure. A visible focus indicator is not
   something to copy away. Expressed as a SHAPE, not a list of selectors, so
   elements nobody thought of are covered by default. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
[role="button"]:focus-visible {
  outline: 3px solid #1f368d !important;
  outline-offset: 2px !important;
}

/* ‼ A RING NEEDS A BOX TO WRAP, AND AN INLINE ANCHOR WITH NO TEXT HAS NONE.
   The footer logo is `<a href="/#"><img></a>`: the anchor keeps the default
   `display:inline`, and Tailwind's preflight makes the image `display:block`.
   A block child splits the inline box around it and the fragments either side
   hold no content, so `outline` - which paints around an inline element's own
   fragments - has nothing to paint. Computed style read `outline: 3px solid`
   the whole time, which is why this read as a styling bug for two sessions; it
   is a box-generation bug. Giving the anchor its own box fixes it.

   Written as the SHAPE (an anchor whose entire content is one image), not as a
   selector for this one link, so the next text-less icon link is covered.
   vendor/inline-anchor-probe.py measures ONE anchor with the missing-box
   property but the shape MATCHES FIVE - the logo plus the four social links,
   which already had rings. That is deliberate and it is measured, not assumed:
   vendor/computed-diff.py reports 0 differences over 978 elements x 20
   properties at 390 and 1440, boxes included, so nothing else moved.

   ‼ `block`, NOT `inline-block`. inline-block puts the anchor back on a line
   box, whose strut reserves descender space under it: measured +8.67px, which
   pushed the whole footer down. The ring is the same either way because the
   anchor was already the full width of its container. */
a:has(> img:only-child) {
  display: block;
}

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

/* ---- Jamie's review, 2026-08-17 -----------------------------------------
 * ‼ (1) The CTA that closes the sticky card stack sat FLUSH against the last
 * card - measured 0px between the button's top and the card's bottom at 1440.
 * It is the only `.w-52` that is a DIRECT child of the page container; the
 * other two sit inside a link or a flex row that already spaces them, which is
 * why this one alone has nothing above it. Selected by that structural fact
 * rather than by nth-child, so re-ordering the section cannot silently move the
 * rule onto a different button. */
.max-w-screen-lg > .w-52 {
  margin-top: 2rem;
}

/* ‼ (2) SCROLL SPEED, MATCHED TO THE SECTION JAMIE NAMED - not to a number I
 * picked. He asked for the "More reasons you'll love traveling" stack to match
 * the "Simple booking process" reveal. Measured advance per card at 1440:
 *     Simple booking process   margin 0     700px, 620px
 *     More reasons             margin 810px 1440px, 1408px, 1376px
 * i.e. 2.1x slower. The reference section's advance IS its card height, because
 * its cards carry no spacer at all. Setting these to 0 gives an advance of
 * 630px against that section's 620-700px, so the two now read at the same rate.
 * This also removes ~2,430px of desktop page length and ~2,279px of mobile,
 * which settles the long-open `mt-[90vh]` question in the same stroke. */
.mt-\[90vh\].sticky {
  margin-top: 0;
}

/* ---- stats band: dividers, not a box ------------------------------------
 * Jamie, 2026-08-17: "This section looks a little odd with the outline bit.
 * Maybe each can just have | between them."
 *
 * He is right about the cause. The band is already a full-bleed panel in its own
 * lighter violet, and the reference's rounded 2px outline INSIDE it made two
 * competing containers - a box drawn on a box. That outline earned its keep when
 * the band was the same colour as the page and the border was the only thing
 * separating them; once the band got its own fill, the border became redundant
 * decoration.
 *
 * So: drop the border, and separate the three claims the way a row of stats
 * normally is - with a rule between them.
 *
 * ‼ No !important anywhere. `.md\:border-2` is a single class (0,1,0); these
 * selectors are (0,2,0) and (0,3,0), so they win on specificity alone. A media
 * query does not change specificity, which is why the desktop-only border is
 * beaten by an unconditional rule here.
 *
 * ‼ The divider colour is derived, not typed: `currentColor` is the band's own
 * published ink, so it follows a theme change instead of pinning a hex that the
 * generator would not know to update. */
.ot-band-wrap > .rounded-2xl {
  border-width: 0;
  border-radius: 0;
}

@media (min-width: 768px) {
  .ot-band-wrap .flex > .w-\[33\%\] + .w-\[33\%\] {
    border-left: 1px solid color-mix(in srgb, currentColor 28%, transparent);
  }
}
