/* Forethought AI-agent chat widget -- sitewide side-panel docking behavior,
   plus the home page's own idle-state handling (hiding the widget there for
   now, and the #ft-search-spacer placeholder that stands in for it). Kept
   in its own file, separate from css-page-home.css, since most of the
   panel-docking behavior applies on every page, not just the home page,
   and this whole subsystem is easiest to iterate on together while it's
   still being finalized (see docs/brand-refresh/plan.md). Loaded sitewide
   via document_head.hbs despite the "page" naming convention shared with
   the other css-page-*.css files. */

/* The hero's "search bar" is the Forethought floating_bar widget itself (see
   templates/home_page.hbs), positioned and sized to line up with the
   left-aligned hero column via forethought-widget.js's
   --ft-search-top/-left/-width, measured from #ft-search-spacer.

   Why the previous attempt at this failed, since the note that used to live here
   blamed the wrong thing: it was never a specificity fight, and Forethought does
   not set these !important (a stylesheet !important would beat a plain inline
   style anyway). Read out of their embed.js, the floating_bar idle state gets
   `left: calc(0px + <offset-x>)`, `right: 0`, `margin-left: auto`,
   `margin-right: auto`, `width: 90%`, `max-width: 640px`. With left, right and
   width all non-auto *and* both margins auto, the box is over-constrained, so
   per CSS 2.1 10.3.7 the auto margins absorb the leftover space equally and
   re-center the widget in the viewport -- silently undoing whatever `left` we
   set, while `top` (unaffected by horizontal margins) kept working. That is
   exactly the reported "top works, left/width don't."

   So the fix isn't a stronger left/width override, it's releasing the
   over-constraint: zero the auto margins, and free right/max-width. Note the
   .ft-chat-open rule further down has always carried `margin: 0 !important`,
   which is precisely why the open state could override left/width when the idle
   state couldn't -- the two rules were never actually fighting the same battle.

   position is forced to absolute because their base style uses `fixed` unless
   the embed script carries position-absolute="true". Absolute is what we want:
   the bar belongs to the hero and should scroll away with it, and
   --ft-search-top/-left are measured in *document* coordinates (rect +
   scrollY/scrollX, see forethought-widget.js), which is what absolute resolves
   against. Neither html nor body sets position or transform, so the containing
   block is the initial one and those document coordinates land unmodified. */
html.home-page {
  /* The gutter --ft-bar-width measures against: the grid gutter *plus* the hero
     column's own inset. .grid-content uses --gap-sm for --padding-inline, which is
     where .hero's content column starts, but the bar lives inside .hero-inner,
     which adds another 1rem either side below 44.9em (css-page-home.css).
     An earlier version subtracted --gap-sm alone, reasoning that it "makes the bar
     end exactly on the content column that the cards below line up to." It did
     not: the bar starts 1rem further in than that column, so measuring against the
     grid gutter alone over-measured the room available by that 1rem per side.
     Measured 2026-10-02 -- in the fluid branch the iframe's right edge landed at
     exactly 100vw + 1px at every width tested (401 and 604 both reported
     overflowR=1 with document scrollWidth > clientWidth), because
     16 - 24 + 18 - 9 = 1. That's 1px of horizontal scroll on macOS, where
     scrollbars are overlays and 100vw == clientWidth; it is ~17px, with a real
     scrollbar, anywhere classic scrollbars reserve width. The bug was invisible
     for so long because it only exists in the fluid branch, below 608px.
     Unconditional rather than scoped to .hero-inner's own 44.9em media query,
     because the fluid branch is only reachable below 608px (35rem + two gutters)
     and the hero's 1rem inset is always present by then, so the two cannot
     disagree anywhere it has an effect. If the 35rem below ever grew past ~43em
     the two ranges would start to overlap, and the failure direction there is a
     bar 1rem narrower than it strictly needed to be -- not an overflow -- so this
     stays the simpler expression. */
  --ft-bar-gutter: calc(var(--gap-sm) + 1rem);

  /* 35rem from the design prototype, shrinking to the gutter above once there
     isn't room for it. Deliberately one fluid expression rather than a width plus
     a mobile breakpoint: this never jumps at a threshold, and it never shrinks the
     bar on mid-size screens that still have room for the full 35rem (which a
     percentage width would). Same idiom as .hero-inner's
     `min(34.3rem, 100vw - 2rem)` in css-page-home.css.
     Matters more than it looks -- the iframe gets widened by twice the inset
     below, so a bar that already ran to the edge of its column pushes the iframe's
     right edge off the viewport and raises a horizontal scrollbar.
     100vw includes any classic scrollbar gutter, so it over-reports the usable
     width by up to ~17px on platforms that reserve one. Deliberately not corrected
     -- CSS can't ask for the scrollbar width, so it would take a JS-written
     --ft-viewport-width from documentElement.clientWidth, and the gutter above now
     leaves 31px of clearance across this whole branch, which absorbs it. */
  --ft-bar-width: min(35rem, 100vw - (2 * var(--ft-bar-gutter)));

  /* Forethought's iframe is padded around the pill it actually draws, to leave
     room for the pill's drop shadow. So positioning the *iframe* onto the
     placeholder's footprint lands the iframe perfectly while leaving the only
     part anyone can see inset by this much on every edge -- which reads as a bar
     that sits too low and too narrow.
     Measured rather than guessed: with the iframe placed exactly on the
     placeholder, devtools reported identical left/top/right/width for both and
     heights of 86px (iframe) against 50px (placeholder), and 50px is itself a
     devtools reading of their rendered pill (see the note on the pill styling
     further down). (86 - 50) / 2 = 18px of padding per edge.
     Re-confirmed 2026-10-02 against a second reading (86px / 50px again), after a
     stray 96px reading cast doubt on it. Their iframe is dynamically sized and
     reports mid-transition heights while the layout is still settling, so measure
     it on a settled idle page or not at all.
     Compensate by growing the iframe outwards by the inset on all sides, so the
     pill inside it lands on the footprint instead. If the pill ever looks
     vertically off, their padding isn't symmetric after all -- correct that with
     --ft-bar-nudge-y rather than by changing this.
     Capped at the grid gutter so the widened iframe can't push a horizontal
     scrollbar onto the page. The bar sits one gutter short of the right edge, so
     the iframe's right edge lands at (gutter - inset) short of it, which stays
     on-page for any inset up to one gutter, at any viewport width. --gap-sm only
     drops below 18px when the viewport's larger dimension is under ~533px, so
     this cap effectively never engages; when it does it trades a couple of px of
     alignment for not having a scrollbar, which is the right way round.
     The iframe's *left* edge does go slightly negative once nudge-x is applied
     (gutter - inset - 9 = -3px at a 24px gutter). That's fine and deliberate:
     only the transparent padding is off-screen, and inline-start overflow isn't
     scrollable in LTR, so it can't produce a scrollbar the way the right edge
     could. */
  --ft-bar-inset: min(18px, var(--gap-sm));

  /* Residual trim on top of the inset compensation above. Keep these in px/rem:
     they're used inside calc(), where a unitless 0 is invalid.

     nudge-x is -9px because their pill is not horizontally centred inside its
     iframe. The inset above assumes it is, which lands the pill 9px right of the
     hero column; correcting that by eye gave exactly -9px, which makes their
     real horizontal padding 27px left / 9px right. Note that still totals the
     same 36px of slack as the vertical axis -- so their iframe reserves an equal
     amount of room in both directions and simply sits the pill off-centre
     within it, rather than this being a stray magic number.

     Known limitation: -9px is a physical-left correction, so it would need
     mirroring to be correct under [dir='rtl'] (as would the `left` in the
     positioning rule below). Not handled, since the asymmetry is only
     discoverable by eye and there's no RTL preview to check it against. */
  --ft-bar-nudge-x: -9px;
  --ft-bar-nudge-y: 0px;
  --ft-bar-width-delta: 0px;
}

/* Set on the placeholder, not on the widget, because the widget's width is
   *measured* from the placeholder (see forethought-widget.js) -- so driving both
   from this one declaration keeps the real bar and the docked stand-in identical
   by construction instead of by two values someone has to keep in step.

   Note 35rem is wider than .hero-inner's 34.3rem text column, so on wide screens
   this intentionally overflows its parent to the right. Harmless: .hero-inner is
   an explicitly-sized inline-flex column so the overflow doesn't resize it, and
   the bar still ends well inside .grid-content's 71.5rem content column, which is
   what the cards below line up to. (Both were stated in `ch` until 2026-10-25 --
   see css-utilities.css:750. The 0.7rem of clearance here is unchanged, because
   both numbers were pinned to the same Open Sans baseline they already had.) */
html.home-page #ft-search-spacer {
  width: var(--ft-bar-width);
}

html.home-page:not(.ft-chat-open) #forethought-chat {
  position: absolute !important;
  top: calc(
    var(--ft-search-top, 0px) - var(--ft-bar-inset) + var(--ft-bar-nudge-y)
  ) !important;
  left: calc(
    var(--ft-search-left, 0px) - var(--ft-bar-inset) + var(--ft-bar-nudge-x)
  ) !important;
  width: calc(
    var(--ft-search-width, 100%) + (2 * var(--ft-bar-inset)) +
      var(--ft-bar-width-delta)
  ) !important;
  /* The three doing the actual work -- see the over-constraint note above. */
  right: auto !important;
  margin-inline: 0 !important;
  max-width: none !important;
}

/* Hidden while the real widget is the thing in the hero, visible only once a
   conversation opens and the widget docks away as the side panel -- at which
   point this is what's left standing in for it. `visibility` rather than
   display/opacity so it keeps its box in both states: that box is what
   forethought-widget.js measures the widget's position from, so it has to stay
   in the layout even while unseen.

   The pill styling below deliberately applies in both states, so becoming
   visible never changes the measured footprint. Either way it stays `inert`
   (see home_page.hbs): there's only ever one live widget instance and it's the
   real iframe.

   The tradeoff accepted here: embed.js is a third-party fetch that then builds
   its iframe and fades it in, so there's a gap on load where the hero has no
   search bar in it at all. Leaving the placeholder visible to cover that gap
   was tried and rejected -- any imperfection in the overlap shows up as two
   stacked pills, which is worse than a brief absence. */
html.home-page:not(.ft-chat-open) #ft-search-spacer {
  visibility: hidden;
}

/* Forethought's border-radius isn't overridable from our CSS (confirmed
   against their docs — their MUI input's radius wins regardless of
   selector/specificity/!important, see git history on this branch for the
   failed attempts). So instead of forcing their widget to match our old
   square-ish bar, this cosmetic placeholder is restyled to match *their*
   pill shape instead — values below are read off their rendered widget
   via devtools (min-height 50px, padding 6px 8px 6px 16px, box-shadow
   0px 2px 8px rgba(0,0,0,.25), white background). border-radius is set
   well past the pill threshold (half of min-height) so it fully rounds
   regardless of the exact height.

   Left on light values deliberately when the dark tier landed (2026-10-20), and
   this is the one place on the home page where that is the right answer. These
   four colours are not a design choice we own -- they are a *measurement* of
   Forethought's rendered widget, and the point of the rule is that the stand-in
   and the real thing are indistinguishable when the widget docks away and this
   takes its place. The widget is a third party we cannot restyle (see the
   border-radius note above: not even with !important), so it stays a white pill
   in dark mode whatever we do here. Theming only the placeholder would mean the
   hero's search bar visibly changed colour at the moment the two swapped --
   trading a consistent mismatch for an inconsistent one.

   So this diverges from the dark frame (6501:3224), which draws the hero search
   dark like everything else, and it will keep diverging until Forethought's own
   theme can be configured. Flagged rather than fixed: it needs whoever owns the
   Forethought config, not CSS.

   DO NOT MOVE THESE ONTO THE FORM TOKENS. That was tried on 2026-10-30 as part
   of Phase 5's legacy sweep, on the understanding that Forethought had been
   reconfigured to the brand palette, and it was reverted the same day because
   Joy spotted the stand-in no longer matching. Re-measured off a screenshot of
   the live widget that day, by sampling pixels rather than by eye:

     their border  #888888   vs  --form-border  #809094  (ours lighter, cooler)
     their fill    #ffffff   vs  --form-bg      #faffff  (ours faintly teal)
     their glyph   #333333   vs  --neutral-icon #384649  (ours faintly teal)

   All three drift, in the same direction -- the form tokens are a cool-grey
   ramp and Forethought's chrome is neutral grey, so there is no token in the
   system that matches. --form-border is the CLOSEST of all 200-odd brand
   tokens to #888888 and it is still visibly off. Hence literals here, with
   the measurement recorded, rather than a token that merely looks adjacent.
   If their config ever does become themeable, re-measure before changing
   anything; do not assume a token is right because the gap looks small.

   The legacy `--clr-*` references are still gone, which was the sweep's actual
   goal: this rule used to read --clr-neutral-40 / --clr-white /
   --clr-neutral-160. The last of those was #333333, i.e. value-right and
   name-wrong, so the glyph below is unchanged in appearance.

   One real fix came out of the round. The border was never part of the
   measurement above -- that list covers min-height, padding, box-shadow and
   the white background, but not the border, which was borrowed from
   --card-border (css-root.css, `1px solid var(--clr-neutral-40)` = #c2c2c2).
   That is far lighter than Forethought's #888888, and the mismatch had been
   shipping since this rule was written; it is what Joy was seeing. #c2c2c2 on
   the white pill was also 1.78:1, under the 3:1 that 1.4.11 asks of a form
   field's own boundary. The measured #888888 is 3.54:1 and clears it. Note the
   inline `var(--card-border, ...)` fallback never applied either way, since
   --card-border is in fact declared. */
html.home-page #ft-search-spacer .search-wrapper input {
  /* Measured, not --form-border: see the note above before touching this. */
  border: 1px solid #888888;
  border-radius: 3.125rem;
  min-height: 50px;
  /* Logical rather than the physical `padding: t r b l` this replaced, so the
     inset follows the writing direction like the rest of this file.
     padding-inline-start clears the icon: that sits 24px in (css-search.css)
     and is ~18px wide, so anything under ~3rem reads as the text touching it.
     3.25rem leaves ~10px of gap. 1rem = 16px if this needs nudging again.
     There is deliberately no padding-inline-end: the end of the pill is empty
     now that the decoy chat button is gone, and the placeholder never runs long
     enough to reach it. Add one back if that stops being true. */
  padding-block: 0.375rem;
  padding-inline-start: 3.25rem;
  background-color: #ffffff;
  /* Measured too, and worth saying why it is not --shadow-regular: the token
     tier's regular shadow assembles as
     `0 var(--shadow-y-offset) var(--shadow-blur) 0 var(--shadow-regular)`,
     which is 0 2px 6px 0 #10171e1a -- the same y-offset, but a 6px blur
     instead of 8px and roughly a tenth of the opacity instead of a quarter.
     Visibly softer than what Forethought draws. */
  box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
}

html.home-page #ft-search-spacer .search-button {
  /* #333333 measured off Forethought's own sparkles glyph. This was the legacy
     --clr-neutral-160, which held exactly this value, so dropping the token
     reference changed nothing on screen. NOT --neutral-icon (#384649) -- see
     the measurement note on the input rule above. */
  color: #333333;

  /* Centre the icon on the pill. The base `.search-button` rule in
     css-search.css pins a fixed `inset-block-start: 20px`, calibrated for the
     theme's taller square search bar -- in a 50px pill that puts the icon's centre at ~28px against
     the pill's 25px, so it reads a few px low.
     50% plus a translate rather than a corrected px value, so it stays centred
     if min-height ever changes (and min-height is matched to Forethought's
     rendered pill, so it can). Scoped to #ft-search-spacer: the same class
     styles the real search bars on every other page, which still want the 20px.
     Note the icon is an <svg> by the time this applies, not the <i> in
     home_page.hbs -- the Font Awesome kit replaces the element and copies its
     classes across, so target the class, never the tag. */
  inset-block-start: 50%;
  transform: translateY(-50%);
}

/* Once a conversation is actually opened (Enter, an intention bubble, or
   the widget's own launcher), it docks as a side panel — sitewide, not
   just on the home page, so the experience is consistent whether the
   conversation was opened from the home page's floating_bar or another
   page's icon launcher (see document_head.hbs and home_page.hbs — same
   config-ft-persistence-id, different launch-style) — instead of sitting
   wherever Forethought's own default idle placement put it. Full body
   height, right-aligned, page content narrows to make room but stays
   fully interactive (no `inert`, unlike the fullscreen-takeover variant).
   forethought-widget.js toggles `ft-chat-open` on <html> from
   Forethought's open/close postMessage events; minimizing removes it and
   the panel/layout revert together. */
html {
  --ft-panel-width: 26rem;
}

/* The panel's space is reserved on the page grid's end gutter, not as a margin
   on <body>. <body> stayed full width as of 2026-10-19; before that it took
   `margin-inline-end: var(--ft-panel-width)` here, which reserved the space by
   making the whole document narrower.

   That worked for content and failed for everything full-bleed. The header and
   footer wrappers are `grid-content full-width`, so their background bands and
   border rules are as wide as <body> -- which meant they stopped 26rem short
   and the panel appeared to slice the page off rather than sit on top of it.
   The footer's border-top ending in mid-air was the clearest symptom.

   Widening the grid's end gutter does the same reservation one level in:
   <body> keeps its full width so the bands reach the window edge and run
   underneath the panel, while the centred `content` column shifts clear of it.
   See css-utilities.css:704 for the track and why both gutters stay 1fr.

   No transition. The margin version animated over 300ms; a custom property
   consumed inside grid-template-columns is not interpolable unless it is
   registered with @property, so the reflow is instant. Left that way on
   purpose -- it is one step, under a panel that is itself animating in, and
   registering a property to animate a grid track is a lot of machinery for it.
   Worth revisiting only if the snap reads as a glitch rather than as the page
   making room. */
html.ft-chat-open .grid-content {
  --padding-inline-end: calc(var(--padding-inline) + var(--ft-panel-width));
}

/* HISTORICAL -- kept because it is the reason `main { width: 100vw }` must not
   come back, and that hazard is easy to reintroduce once the cause is gone.

   While the panel's space was reserved as a margin on <body>, narrowing <body>
   was only half the job: everything inside it had to notice. `main` measured
   against the viewport (100vw) kept its full width while <body> shrank, and
   `place-items: center` on <body> split the overflow across both sides, sending
   the leading ~184px of the hero off the left edge at every docked width with
   `overflow-x: hidden` leaving no scrollbar to recover it. Full diagnosis in
   plan.md, Phase 2. The fix was `main { width: 100% }` in style.css, resolving
   against <body>.

   <body> no longer narrows at all (see the .grid-content rule above), so there
   is nothing for `main` to track and that failure can no longer occur -- but
   `width: 100vw` on a full-bleed element is still wrong for the original
   reason: vw counts the classic scrollbar gutter, so it overshoots the
   container by ~15px. The `place-items: center` that used to halve that
   overshoot and send half of it off the left edge was deleted on 2026-10-21
   (style.css, the <body> rule), so the overshoot would now land entirely on the
   right -- a different symptom, not a fix, and still clipped by
   `overflow-x: hidden` with no scrollbar to recover it. */

/* `:not(.product-page)` is belt-and-braces. forethought-widget.js is the only
   thing that ever adds `ft-chat-open` and it bails out on the custom product
   pages before it can (see the guard at the top of that file), so in principle
   this exclusion is unreachable. It is here because the one time that guard
   broke, this is the rule that did the damage: it silently shrank the custom
   pages' widget to 26rem. Cheaper to make that structurally impossible than to
   re-diagnose it.

   The damage would be narrower now than it was then. At the time those pages
   declared no width at all, so `width: var(--ft-panel-width)` had nothing to
   beat; css-page-custom.css gives the widget an explicit width as of
   2026-10-30, at equal specificity and also `!important`, so source order would
   decide it rather than the rule simply landing uncontested. The `position`,
   `top`/`bottom` and `z-index` here are still unopposed, so the exclusion keeps
   its job. */
/* THE TOP EDGE IS THE HEADER'S BOTTOM, NOT THE VIEWPORT'S TOP, as of
   2026-10-30. Joy on the day of the soft launch: "the Forethought chatbot is
   just a bit too tall -- can we adjust it so that the top aligns with the
   header?" At `top: 0; height: 100vh` the panel ran the full viewport and
   covered the right-hand end of the header while a conversation was open.

   --ft-dock-top is written by updateDockTop in forethought-widget.js, as the
   header's bottom edge in *document* coordinates. Measured rather than written
   here because the header has three heights -- 1.5rem padding at the base band,
   1rem around a 40px control row in the wide one, and ~139px with the mobile
   search row open -- so any constant in this file would be right in one band
   and wrong in the others, and would be a second copy of the header's geometry
   to keep in step. Document coordinates are also what makes it correct for
   signed-in agents, whose Guide admin bar sits above the header and pushes it
   ~48px down; the same expression covers both audiences.

   THE OFFSET IS CONSTANT AND DOES NOT TRACK SCROLL. The header is
   `position: relative` (css-page-header.css), so it scrolls away and leaves the
   page showing through the strip above the panel. That is Joy's explicit choice,
   2026-10-30, over a JS scroll listener that would grow the panel back to full
   height as the header left the viewport: a fixed offset is one declaration and
   cannot drift, where the tracking version is a listener running on every scroll
   frame for a strip of page nobody is looking at. Revisit only if that gap reads
   as a bug rather than as the panel sitting under the header.

   The `0px` fallback is the pre-2026-10-30 behaviour, so a page where the script
   has not run (or has bailed) gets a full-height panel rather than a broken one.
   It needs the unit: `calc(100vh - 0)` is invalid, where `calc(100vh - 0px)` is
   not.

   `height` has to stay explicit and cannot be left to top/bottom. #forethought-chat
   *is* the iframe, and on a replaced element `height: auto` means "use your
   intrinsic height" rather than "stretch between my insets" -- the same trap
   documented on `width` in the fullscreen rule below. `bottom` is kept only
   because it is what clears Forethought's own inline value; with `top` and
   `height` both set it is over-constrained and ignored (CSS 2.1 10.6.4). */
html.ft-chat-open:not(.product-page) #forethought-chat {
  position: fixed !important;
  top: var(--ft-dock-top, 0px) !important;
  bottom: 0 !important;
  /* Forethought's own script sets `left` inline; with left, width, and
     right all non-auto, left wins and right is ignored (CSS2.1 10.3.7) —
     so left must be explicitly cleared here, not just right set. */
  left: auto !important;
  right: 0 !important;
  width: var(--ft-panel-width) !important;
  height: calc(100vh - var(--ft-dock-top, 0px)) !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  z-index: 2000 !important;
}

/* Below this width there isn't room to dock a panel *beside* the page, so it
   covers the page instead. 54.89em (878px) less the 26rem panel leaves ~460px of
   content, which is already narrower than the theme's own mobile layout assumes;
   anything below that was being crushed rather than narrowed. Deliberately the
   same breakpoint as the hamburger nav (css-page-header.css) and the z-index
   guard below: at this width the theme has already switched to its mobile
   layout, so this subsystem has one threshold to reason about instead of three.

   Paired with FT_FULLSCREEN_QUERY in forethought-widget.js, which must hold the
   same width. This half makes the iframe cover the viewport; that half tells the
   chat UI *inside* it to use its mobile layout at the same point, since otherwise
   Forethought only switches at their own 480px and we'd be stretching their
   desktop layout across the whole screen. Neither value can be derived from the
   other, so editing one without the other drifts silently.

   Must stay *after* the docked rule above -- both are `!important` at equal
   specificity, so this only wins by source order.

   The width is an explicit `100%`, and `right` is released, because
   #forethought-chat *is* the iframe (it has no iframe child -- see
   forethought-widget.js) and an iframe is a replaced element. On a replaced
   element `width: auto` means "use your intrinsic width", not "fill from left to
   right": the first version of this rule used left:0/right:0/width:auto and the
   panel collapsed to nothing, which reads on screen as the whole widget vanishing
   on open. The docked rule above never hit this only because it names an explicit
   26rem. `100%` rather than `100vw` since vw counts the scrollbar gutter.

   `height` is declared twice on purpose. dvh tracks mobile browser chrome as it
   collapses; with vh alone the panel is sized to the *largest* viewport, which
   puts its input row underneath the URL bar -- the one part of a chat panel that
   must stay reachable. The vh line is the fallback for anything without dvh.

   Scrolling is locked on the covered page rather than left live: it's invisible
   under the panel, and scrolling it would drag the hero bar (positioned in
   document coordinates) out from under the panel so it reappears somewhere else
   on close. Note the covered page is *not* `inert`, so keyboard and screen-reader
   focus can still walk into it -- `inert` can't go on <body> here because the
   widget is a child of it, so it needs JS and a wrapper to target. Worth doing if
   it proves to matter; not worth hand-written DOM surgery around this widget
   pre-emptively. */
@media screen and (max-width: 54.89em) {
  html.ft-chat-open {
    overflow: hidden;
  }

  /* The panel is a full-screen takeover here, so there is nothing to make room
     for -- give the end gutter back. (This undid `body`'s margin-inline-end
     until 2026-10-19; same job, new mechanism.) */
  html.ft-chat-open .grid-content {
    --padding-inline-end: var(--padding-inline);
  }

  /* Excluded from the custom product pages for the same reason as the docked
     rule above, and it has to be excluded in lockstep with it: this one is the
     mobile half of the same pair and relies on matching the same elements. */
  /* `top: 0` has to be restated here, and this is the one declaration in this
     block that is undoing rather than adding. The docked rule above now starts
     the panel at --ft-dock-top so it sits below the header; a takeover has no
     header to sit below -- it covers everything -- and inheriting that offset
     would push it off the bottom of the viewport by the header's height, taking
     the message input with it. Same reason the heights below are plain 100vh/dvh
     rather than the subtraction above. */
  html.ft-chat-open:not(.product-page) #forethought-chat {
    top: 0 !important;
    left: 0 !important;
    right: auto !important;
    width: 100% !important;
    height: 100vh !important;
    height: 100dvh !important;
  }
}

/* The same mobile hamburger-nav conflict already handled for the custom pages in
   css-page-custom.css, which cannot cover this case: that rule is scoped to
   `html.product-page`, a class only the three templates in
   templates/custom_pages/ set, so it never applies to the home page (it was
   scoped to `body:has(#forethought-widget-embed-script)` until 2026-10-21, with
   the same outcome by a less direct route -- see the note at the top of
   css-page-custom.css). Forethought's base style puts the iframe at z-index 999999, so
   without this the nav overlay opens *behind* the hero bar. Force it below the
   header's own stacking context (z-index: 10, see css-page-header.css) while the
   nav is open.

   Excluded while a conversation is open, because at these widths that panel now
   covers the whole viewport (see above) and burying it under the nav overlay
   would leave an open conversation unreachable. Hard to reach in practice -- the
   overlay drops the launcher behind it, so there's no way to open the chat while
   the nav is open -- but the failure mode if it ever is reached is a dead panel,
   whereas the failure mode of this exclusion is a nav overlay underneath a panel
   that's covering it anyway. */
@media screen and (max-width: 54.89em) {
  html:has(.header-nav.is-open):not(.ft-chat-open) #forethought-chat {
    z-index: 1 !important;
  }
}
