/*
  App-owned styles for braveheartfoods — same role as pfgc's pfgc.css and
  pfg-customized's pfg-customized.css.

  Everything else this site loads is a migrated Sitecore bundle under
  /-/media/Styles. This file holds only rules that CODE owns: patches for the
  places where React/Uniform emits subtly different DOM than Sitecore's
  pretty-printed HTML, so the rendered page still matches production.

  Loaded last in _document.tsx so these rules win over braveheart.css.
*/

/*
  next/image REQUIRES width/height attributes; the original <img> tags carried
  none. Those attributes render as presentational sizing hints, so with the
  site's global `box-sizing: border-box` every image is pinned to its natural
  size as a BORDER box, and any padding eats into the picture instead of growing
  the box. `height: auto` restores the original behaviour wherever CSS already
  governs the width (`width: 100%`, `max-width: 50%`, …).

  Specificity (0,0,1) — it loses to every class-based sizing rule in the
  migrated bundles, which keep their fixed crops.
*/
img {
  height: auto;
}

/*
  The two cases where the width attribute is wrong as well, because the original
  markup relied on the image's own intrinsic width:

  - `.rightAlign` (the article lead image) is a `float: right` box with
    `padding: 0 0 25px 25px`. Shrink-to-fit made prod's border box
    natural + padding (575x325 for a 550x300 image); the width attribute makes it
    natural INCLUDING the padding (550x300, picture squeezed to 525x275).
  - `.braveheart-hero__icon img` is capped by `max-height: 73px` with no width
    rule, so prod scaled it down proportionally (420x293 -> 105x73). A pinned
    width clamps only the height and stretches the icon (420x73).

  The lead image is rendered `unoptimized` (see Article.tsx) so it has no srcset:
  a srcset candidate the CDN cannot upscale reports a DENSITY-CORRECTED intrinsic
  width, which would halve an intrinsically-sized image on a 2x display. The hero
  icon keeps its srcset — `max-height` sizes it from the ASPECT RATIO, which
  density correction preserves.
*/
.rightAlign,
.rightAlign--sides,
.rightAlign--even,
.braveheart-hero__icon img {
  width: auto;
}

/*
  ...but only where prod's shrink-to-fit actually applied. Below 980px
  braveheart.css unfloats the lead image and stretches it to the column
  (`.rightAlign{float:none;width:100%;padding:20px}`); the `width: auto` above
  carries the same specificity (0,1,0) and loads later, so it was winning inside
  that media query too and pinning the image to its natural width — 590px in a
  375px viewport, running off the right edge of every article page.

  Restated as the bundle's own `max-width: 980px` rather than scoped to a
  `min-width: 981px` complement: the whole bundle is desktop-first, and mirroring
  the query it is undoing leaves no gap between the two breakpoints.

  `.rightAlign--sides` / `--even` are deliberately NOT restored here. They stand
  in for INLINE styles on the source markup, which outrank the bundle's mobile
  rule, so prod keeps those two images at natural width on mobile as well (a
  class named `rightAlign--*` is not matched by the bundle's `.rightAlign`
  selector, so they never picked the rule up in the first place).
*/
@media screen and (max-width: 980px) {
  .rightAlign {
    width: 100%;
  }

  /*
    Unfloating also exposes the one structural difference Article.tsx documents:
    the source nests the lead image INSIDE the body's opening <p>, and Rich Text
    cannot hold an inline image, so the port emits it as that paragraph's
    preceding sibling. While the image is floated (desktop) the two are
    indistinguishable, but once it is in flow the paragraph's own 17.6px
    margin-top opens a gap the source never had between the picture and the copy.
  */
  .rightAlign + p {
    margin-top: 0;
  }
}

/*
  Two article lead images are floated right by an INLINE style rather than by
  `.rightAlign`, with different spacing — Rich Text and asset params have nowhere
  to keep that, so Article picks the class from its `imageSpacing` parameter and
  the declarations live here, copied from the source markup:

    Gold Club / Rewards Details   class="article-rte-image-right"
                                  style="margin-right:25px; margin-left:25px; float:right"
    News Room / PathProven        style="float:right; margin:10px"

  Margin, not padding: unlike `.rightAlign` these clear space OUTSIDE the picture,
  so under the site's `box-sizing: border-box` the image keeps its natural size.
*/
.rightAlign--sides {
  display: block;
  float: right;
  margin: 0 25px;
}

/*
  The extra 23px on top is one line, not spacing: in the source this image sits
  AFTER the body's opening line break (`<h1>…</h1><br><span><img …>copy</span>`),
  so the float starts on the copy's second line. Rich Text cannot hold an inline
  image, so Article has to emit the lead image as a sibling BEFORE the body — the
  float would otherwise start one line too high and steal a line's worth of wrap
  from every paragraph beside it.
*/
.rightAlign--even {
  display: block;
  float: right;
  margin: 33px 10px 10px;
}

/*
  Reproduce the inline-block whitespace gap that Sitecore's pretty-printed markup
  renders between sibling <li>. React strips whitespace between elements, so each
  nav loses exactly one space per gap and its items creep left.

  Both values are the measured space width in the <ul>'s own font, expressed in
  em so they track the font-size across breakpoints exactly as a real space does:
    header nav  16px EB Garamond -> 3.203px = 0.2em
    .subNav     21.76px couturebold -> 8.594px = 0.395em

  The header nav uses PADDING, not margin: its <li> margin is responsive
  (21px / 12px / 10px / 9px across four breakpoints), so a `margin-left` here
  would replace it rather than add to it. The <li> has no background, border or
  pseudo-element — only the <a> inside it does — so padding on it is
  indistinguishable from the whitespace it stands in for. The `.subNav` <li>
  margin is a flat 0, so margin is additive there and leaves its `:before`
  divider positioned off the padding box exactly as prod does.
*/
.header .desktopNav nav ul li + li {
  padding-left: 0.2em;
}

.subNav ul li + li {
  margin-left: 0.395em;
}

/*
  ============================================================================
  BEYOND PARITY — mobile overflow

  Every rule above this line reproduces production. The four below correct
  places where PRODUCTION ITSELF runs off the right edge of a phone, so they
  are deliberate divergences from the source. Each is scoped to the widths
  where the overflow actually occurs; at every other width the ladder or
  natural size already fits and these are inert.
  ============================================================================
*/

/*
  1. The internal hero's headline is a single unbreakable word set in a display
  face at a fixed ladder of sizes (`braveheart.css`: 90px, 60px below 768px,
  40px below 500px). "EXTRAORDINARY" — the longest headline on the site, and
  the one all eleven /Why-Braveheart/ pages use — measures

      width = 8.93 x font-size + 26px

  (the constant is 2px of letter-spacing on each of 13 glyphs), so it outgrows
  the h1's content box in three bands: at or below 417px, 501-596px, and
  769-863px. At 375px it wants 383px in a 340px box, and because nothing clips
  it the whole document becomes 393px wide — a horizontal scroll on every one
  of those pages, the widest single overflow on the site.

  Capping each ladder step at the size that fits keeps the headline on one
  line, which is the point of the design, rather than breaking the word across
  two. The cap is that type metric solved for font-size: the viewport less a
  15px scrollbar, the h1's 20px of padding and the 26px of letter-spacing, over
  8.93 (rounded to 8.94 for margin). Wherever the ladder value is already the
  smaller of the two it wins untouched, so this changes nothing outside the
  three bands. Phones with overlay scrollbars have 15px more room than the
  formula assumes, never less.
*/
.hero.internal .hero-text {
  font-size: min(90px, calc((100vw - 61px) / 8.94));
}

@media only screen and (max-width: 768px) {
  .hero.internal .hero-text {
    font-size: min(60px, calc((100vw - 61px) / 8.94));
  }
}

@media only screen and (max-width: 500px) {
  .hero.internal .hero-text {
    font-size: min(40px, calc((100vw - 61px) / 8.94));
  }
}

/*
  2. `.pager` is `width: 100%` AND `min-width: 500px`, so on the News Room index
  it holds 500px inside a 320px column and drags 180px of EMPTY box off-screen.
  Its content — "1 2 3 >" — is 98px wide and sits left-aligned at the box's
  padding edge (the `margin: 0 auto` on `.pagination` does nothing to an
  inline-block), so the min-width positions nothing and dropping it moves no
  pixel that is actually drawn. Above ~500px `width: 100%` is already the larger
  of the two and the min-width is dead, which is why this is scoped narrowly.
*/
@media screen and (max-width: 980px) {
  .pager {
    min-width: 0;
  }
}

/*
  3. Standalone body images carry their natural width with nothing to cap it:
  the Marketing Materials pair are 585px and run 245px past a 360px screen —
  the page called out as broken on prod as well. A max-width on article imagery
  is the general guard rather than a fix for those two, and it is slack at every
  width where a picture already fits, desktop crops included.

  The News Room listing thumbnails are excluded because braveheart.css already
  caps them, at `.listing-image > img { max-width: 255px }` — the same
  specificity as this rule, which loading last would quietly replace. That is
  not a near miss: `.listing-image` is a `table-cell` sized by its own content,
  so a PERCENTAGE max-width there has no width to resolve against and collapses
  the thumbnail to 0x0. It is the same trap as the `.rightAlign` regression at
  the top of this file — a patch here outranking the bundle it is patching — so
  the exclusion is written to defer to that cap rather than to restate its
  value.
*/
.main-content img:not(.listing-image > img) {
  max-width: 100%;
}

/*
  4. `.rightAlign--sides` and `--even` stand in for INLINE styles, and an inline
  style outranks the bundle's mobile rule — so production never unfloats those
  two lead images. On the PathProven news article that leaves a 480px picture at
  x=-150, with a third of it off the LEFT edge. Giving them what the bundle
  gives `.rightAlign` at the same breakpoint settles all three variants into one
  mobile behaviour. The margins go with the float: they only ever existed to
  hold the copy off a floated picture, and `padding` is what `.rightAlign` uses
  to inset an unfloated one.
*/
@media screen and (max-width: 980px) {
  .rightAlign--sides,
  .rightAlign--even {
    float: none;
    width: 100%;
    margin: 0;
    padding: 20px;
  }

  .rightAlign--sides + p,
  .rightAlign--even + p {
    margin-top: 0;
  }
}

/*
  5. The footer's contact logo is a fixed 277px picture in a column that the
  three-across footer grid squeezes to 208-268px between roughly 800px and
  1050px wide — so it breaks out of its own column across that whole band, and
  out of the VIEWPORT between about 800px and 940px. Same guard as the article
  images above, and equally slack once the column is wide enough to hold it.
*/
footer .column-content img {
  max-width: 100%;
}

/*
  6. reCAPTCHA renders at a fixed 304px, which does not fit the 265px form
  column on a 320px screen — the last thing on the site to overflow at that
  width, and not something a width can fix, since the widget's own layout is
  inside a cross-origin iframe. Scaling from the top-left corner is the
  remedy Google documents for narrow columns. 0.87 is 265/304, the ratio at the
  narrowest screen this applies to. A transform does not change the space an
  element reserves, so the scaled widget leaves a little slack beneath it —
  which is the right way round, and deliberately NOT tightened with a fixed
  height here: doing that fought fix 10 below and put the submit button back on
  top of the widget at this width.
*/
@media screen and (max-width: 349px) {
  .captcha-field > div {
    transform: scale(0.87);
    transform-origin: 0 0;
  }
}

/*
  7. The secondary hero's logo is `width: 80vw`, but `vw` counts the scrollbar
  and the flex column around it adds 34px of padding on each side, so the pair
  can never fit: at 320px the image asks for 256px inside 237px of room and
  widens its own parent to 324px against a 305px viewport. That one is a real
  horizontal scroll rather than a clipped overflow, because nothing above it
  hides what spills.

  Capping the image at the room that exists — viewport less the 68px of padding
  and 15px of scrollbar — costs nothing until 80vw actually exceeds it, which is
  below 415px. The rule stops at 799px because braveheart.css swaps the cap for
  `max-width: 50%` from 800px up, and an unscoped rule here would outrank it.
*/
@media screen and (max-width: 799px) {
  .braveheart-hero__image img {
    max-width: min(350px, calc(100vw - 83px));
  }
}

/*
  ============================================================================
  BEYOND PARITY — the four-block hover flicker
  ============================================================================

  Hovering the bottom edge of TASTE / QUALITY / TRIM / CONSISTENCY started the
  label animation, then cancelled it, over and over — measured at 50 hover
  enters in 2 seconds against one hover for the rest of the tile.

  The tiles are only PARTLY hoverable. `.four-block-carousel__block-container`
  pulls the next section up with `margin-bottom: -150px` and the carousel below
  covers the difference with `padding-top: 150px`, so the swiper container —
  transparent, but `position: relative; z-index: 1` — lies over the bottom 150px
  of every tile and takes the pointer there. On a 1440px viewport the tile runs
  628-965 and the swiper starts at 815, so only 628-815 hovers.

  The resting `h2` is `z-index: 2`, which is how the loop starts: it spans
  777-816, so its last pixel is the one place that outranks the swiper and makes
  the tile hoverable BELOW 815. Hovering there moves the label to `top: 131px`
  (777-816 -> roughly 728-790), the pixel under the cursor goes back to the
  swiper, the tile un-hovers, the label animates home under the cursor again,
  and round it goes.

  Lifting the swiper over the resting label costs nothing visible: it paints no
  background and its first content sits 150px down, past the overlap, so the
  only thing that changes is which element answers a hit test in that sliver.
  The tile then hovers over exactly the region it actually owns, which does not
  move, and the loop has nowhere to start. The hovered and `.active` label is
  `z-index: 101` and still sits above.

  Sited here rather than as `pointer-events: none` on the `h2`, which fixes the
  same sliver but would also cost the heading its click-to-edit in the Canvas
  editor — it is a UniformText field.
*/
.four-block-carousel .swiper-container {
  z-index: 3;
}

/*
  ============================================================================
  BEYOND PARITY — the black bar beside an opening mobile submenu
  ============================================================================

  Expanding a mobile submenu painted a 40px black bar down its right edge for
  the length of the slide, then snapped it away. Prod does it too.

  The submenu slides by animating its height under `overflow: hidden`, and
  `overflow: hidden` makes the <ul> establish a new block formatting context. A
  BFC may not overlap a float, and the caret toggle beside the parent item is
  `float: right` — so for exactly as long as the animation runs, the <ul>
  shrinks by the toggle's 40px to get out of its way and the black `.mobile-nav`
  behind it shows through. Measured 479px wide while `overflow` is `hidden`,
  519px the instant it returns to `visible`.

  What makes them overlap at all is ONE pixel. The parent row is 47px of
  inline-block anchor, but the toggle is 48px — its FontAwesome caret sits in a
  taller line box — so the float hangs 1px below the row it belongs to and just
  catches the top edge of the submenu underneath.

  `clear` says what was always meant: the submenu starts below the toggle, not
  beside it. With no float left to avoid, the BFC has nothing to shrink for and
  the <ul> keeps its full width for the whole animation. The cost is that same
  1px — the submenu now starts at the float's bottom edge rather than 1px above
  it — which is why this is `clear` on the submenu rather than trimming a pixel
  off the toggle: it holds regardless of what the icon font does to the line box.
*/
.mobile .mobile-nav .nav li ul {
  clear: both;
}

/*
  The home footer's Performance Foodservice logo sat 15px below where production
  puts it. The source has the logo INSIDE the paragraph that carries "Available
  Exclusively From"; Rich Text cannot hold a link with an image, so Footer emits
  it as that paragraph's next sibling instead (the same constraint Article has
  with its lead image). Outside the <p> it lands after the paragraph's
  `margin-bottom: 15px` and stops inheriting its 15px/22px type, so the logo
  dropped by exactly that margin and the two spacer breaks after it grew by 2px
  each.

  Closing the margin and restating the type puts the picture back where the
  source draws it. Scoped to the news column, which is the only place the logo
  is emitted after a <p> — the other footer variant renders the same intro as
  INLINE rich text with no paragraph around it, and already matches production
  element for element.
*/
footer .column-news > p:has(+ a) {
  margin-bottom: 0;
}

footer .column-news > a,
footer .column-news > br {
  font-size: 15px;
  line-height: 22px;
}

/*
  ============================================================================
  BEYOND PARITY — the captcha overlapping the submit button
  ============================================================================

  On the contact form the SUBMIT button was drawn across the bottom third of
  the reCAPTCHA. Prod does it too.

  reCAPTCHA sizes its own box — `width: 304px; height: 78px` — but inside it the
  wrapper holding the iframe comes out 118px tall with the iframe sitting at its
  BOTTOM, 40px below where the box begins:

    div[width:304px;height:78px]   offsetHeight 78, scrollHeight 118
      div                          118px
        iframe                     78px, offsetTop +40

  Layout downstream honours the 78px the box declares, not the 118px it draws,
  so the submit button is placed 78px after the captcha starts and 35px of it
  lands on top of the checkbox.

  The fix is to make the form reserve what the widget actually draws, so the
  submit button is placed after it. Containing the box's overflow does exactly
  that — the captcha's slot grows to the full 118px and the button clears it.

  Three alternatives were measured and rejected, all of which look right in the
  numbers and are wrong on screen:
  `display: block` on the iframe — the usual remedy when an inline iframe is
  inflated by a baseline — only takes the wrapper from 124px to 118px, so the
  40px is not the line box. Pinning that wrapper to its parent's height and
  clipping it reports a perfect box and renders NOTHING, because the iframe is
  still 40px down and gets cropped out entirely. Making it a flex container does
  land the iframe at the top, but squeezes the widget to 300px.

  So the 40px stays, and the layout stops pretending it is not there.
*/
.captcha-field > div {
  overflow: hidden;
}
