/*
 * THE BRIDGE — the only CSS this project writes for a theme-markup page.
 *
 * GENERATED into public/theme/css/bridge.css by scripts/vendor-theme.mjs, and
 * SERVED FIRST, before every one of the theme's own stylesheets. The ordering
 * is load-bearing for the `img` rule below; read its note before moving it.
 */
picture {
  display: contents;
}

/*
 * ── The one exception, and why it is not a second rule but the same one ─────
 *
 * `display: contents` is not quite transparent inside a FLEX container in
 * Chrome: the `<picture>`'s child no longer supplies the container's baseline.
 * On this page that happens once. `.blog__single-thumb` is a block whose only
 * child is an `inline-flex` `<a>`, so the link sits on a line box and is
 * aligned on its baseline; on the live page that baseline is the image's bottom
 * edge and the line box's strut adds 8px of descender below it, making the
 * thumb 288px. With the image inside a `display: contents` `<picture>` the
 * baseline is synthesised differently and the thumb is 280 — 8px per card, 24px
 * down the page at 390, and it cascades into every offset below the teaser.
 *
 * `display: flex` on that one `<picture>` restores the live 288. Applying it to
 * EVERY picture was tried and made things worse: it closed this difference and
 * opened twenty others (156 differing roles against 136), because a flex
 * `<picture>` becomes the item the theme's grid and flex parents size instead
 * of the `<img>`.
 *
 * `width: 100%` is the second half and it is not decoration. Without it the
 * `<picture>` is a flex item sized by its content, and `.blog .blog__single-
 * thumb a img { width: 100% }` then resolves against the picture instead of
 * against the card: at 900 and 768, where the card goes full width, the image
 * measured 467px against the live 656. That showed at five of the fourteen
 * widths and at none of the three the first probe ran — which is the argument
 * for sweeping all fourteen before believing a fix.
 *
 * With both, this box measures [288, 656, 280] at 900, which is the live
 * page's own triple.
 *
 * So: `contents` everywhere, `flex` in the one place a theme selector reads a
 * baseline through it. If a third case appears, measure both before choosing.
 */
.blog__single-thumb picture {
  display: flex;
  width: 100%;
}

/*
 * ── The `<source>` in an entry body's `<picture>` ───────────────────────────
 *
 * Chrome computes `display: inline` on `<source>`, and with its `<picture>` at
 * `display: contents` it becomes a real box in the parent's formatting context
 * (register S38 — why the retired Base layer's `base.css` hid it outright).
 * In `.text-blocks` it is today a zero-width inline box on the image's own line
 * and moves nothing: every body image and caption measured identical with and
 * without this rule at 1848, 1280 and 390. It is here so that stays true when
 * a body image ends up in a flex or grid context, where an extra empty item is
 * exactly what moved the sidebar thumbnails. Scoped to the body on purpose: the
 * theme components' own `<picture>`s were measured against the live page as
 * they are — including the flex one above, whose `<source>` is a flex item.
 */
.text-blocks picture > source {
  display: none;
}

/*
 * ── The `width` attribute is a presentational hint, and the theme did not
 *    expect one ───────────────────────────────────────────────────────────
 *
 * `src/lib/images.ts` puts the source's real `width` and `height` on every
 * `<img>`, which is what reserves the box before the image arrives. The live
 * page's `<img>` elements carry NEITHER, and the theme's CSS was written for
 * that: `.navbar-logo img` gets a height and no width, so the live logo takes
 * its width from the ratio.
 *
 * A `width` attribute is a presentational hint — weaker than any author rule,
 * stronger than nothing at all. With it, the logo took `width: 186px`, hit
 * `max-width: 160px`, and came out 160px wide where the live one is 95.7 at a
 * 390px viewport. That is 64px of extra header content, and it made the mobile
 * bar WRAP to a second row: 146px tall against the live 98, which pushed the
 * hero down and hid the first line of its eyebrow behind the header. The
 * fourteen-width numbers never showed it, because `homeprobe` models the page
 * and `headerprobe` models the bar — the screenshot is what showed it.
 *
 * `width: auto` restores exactly the live behaviour: it beats the hint and it
 * loses to every rule in the theme's own stylesheets, INCLUDING `width: 100%`,
 * because this file is served before all of them. That ordering is the whole
 * mechanism — move this rule after the theme and it does the opposite of what
 * it says. It is also why this file is vendored into `public/theme/css/`
 * rather than imported from `src/styles/`, which Astro would place last.
 *
 * The box is still reserved: `height` and the attribute-derived `aspect-ratio`
 * both survive, so a browser still knows the shape before the bytes land.
 *
 * ── AND IT IS SCOPED, because the global version was measurably worse ───────
 *
 * `img { width: auto }` for every image closed the header and opened the
 * impact collage: its large photograph went from the live 520x262 to 475x240
 * at five widths, because that image has no CSS width either and WANTS its
 * intrinsic one — which is exactly what the `width` attribute supplies. The
 * two cases pull in opposite directions and only measurement separates them.
 *
 * So the rule names the four places the theme sets a HEIGHT and expects the
 * width to follow: the logo in the bar, in the mobile drawer, in the footer's
 * copyright row, and in the preloader. Everywhere else the attribute stands.
 */
.navbar-logo img,
.mobile-menu__header .logo img,
.footer__copyright-logo img,
.preloader img {
  width: auto;
}

/*
 * ── The skip link, when it has focus ─────────────────────────────────────────
 *
 * ThemeShell renders WordPress's `a.skip-link.screen-reader-text`, and the
 * theme hides `.screen-reader-text` with no `:focus` exception — WordPress's
 * own default stylesheet carries that exception, the theme dropped it — so a
 * keyboard reader's first Tab landed on a link nobody could see. This is
 * WordPress's rule, in plain black on white: the live site has no skip link,
 * so there is nothing of the theme's to match. It overrides both hiding rules
 * (the theme's `clip`, Elementor's `top: -10000em` and `margin: -1px`) and sits
 * above the fixed header and the search overlay (z-index 99999). Nothing
 * changes until the link is focused, so a mouse reader sees exactly the page
 * the live site paints.
 */
.skip-link.screen-reader-text:focus {
  top: 5px;
  left: 5px;
  z-index: 100000;
  display: block;
  width: auto;
  height: auto;
  margin: 0;
  padding: 15px 23px 14px;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
  background-color: #fff;
  color: #000;
  font-size: 0.875rem;
  font-weight: 700;
  line-height: normal;
  text-decoration: none;
  box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);
  /* The theme transitions `all` on links: without this the link slid in from
     Elementor's `top: -10000em` for 300ms instead of appearing. */
  transition: none;
}

/*
 * ── The keyboard focus ring ──────────────────────────────────────────────────
 *
 * The theme zeroes the outline on every link, button and field — `a:focus,
 * button:focus { outline: 0 }`, `input { outline: 0 }` in main.css — and puts
 * nothing in its place, so 44 of 45 Tab stops measured on five pages showed no
 * sign of focus at all, here and on the live site. This ring
 * is for the keyboard only: `:focus-visible` does not match a link or button
 * a mouse clicked, so a mouse reader sees the page the live site paints. A
 * text field is the exception — Chrome matches `:focus-visible` on a field
 * however it got focus — so fields also require `data-focus-by="keyboard"`,
 * which src/lib/keyboard.ts writes on `<html>` when focus moves; with no
 * script they simply keep the live site's no-ring.
 *
 * Specificity, not order, is what makes this win from the FIRST stylesheet,
 * and it has to clear Bootstrap as well as the theme: `.nav-link:focus-visible`
 * and `.accordion-button:focus` (the entry pages' «Попередня/Наступна стаття»,
 * the About accordions) zero the outline at `(0,2,0)`, which a bare
 * `:is(…, [tabindex]):focus-visible` only ties — and a tie goes to the later
 * file. `:root` lifts both rules to `(0,3,0)`/`(0,3,1)`. Nothing else in the
 * vendored CSS zeroes a focused element's outline at that weight except
 * selectors no page here renders (`.btn-check`, `.wp-block-search__input`,
 * Elementor's form fields, the comment form). The skip link's `#content`
 * target keeps its inline `outline: none`, which beats any rule without
 * `!important`.
 *
 * The cyan is the child theme's own `#00A8E2` (its `--hover-color`).
 */
:root :is(a, button, [tabindex]):focus-visible,
:root[data-focus-by='keyboard'] :is(input, select, textarea):focus-visible {
  outline: 2px solid #00a8e2;
  outline-offset: 2px;
}
:is(a, button, input, select, textarea, [tabindex]):focus:not(:focus-visible) {
  outline: none;
}

/*
 * ── The search overlay's results ─────────────────────────────────────────────
 *
 * The live search form posts to WordPress's `/?s=` page, so the theme has no
 * results list to copy; `.search-popup__results` is this project's own
 * element (ThemeShell's search script). Unstyled, its rows were bare
 * `<p><a>` in the page's black at the overlay's top-left corner, under the
 * header and nearly invisible on the 90% black.
 *
 * So the list takes the theme's OWN geometry for the form above it —
 * `.search-popup form` is absolute at `top: 50%`, `margin-top: -35px`,
 * 70px tall (60px below 768px, responsive.css), `max-width: 700px` between
 * 15px insets — and starts 20px below the field, scrolling rather than
 * running off the bottom of the viewport. It sits on the form's own `#111111`
 * with the input's 5px radius and 30px text inset, because on the bare 90%
 * overlay the hero's white headline showed through between the rows. The
 * rows keep the body type they already inherit (16/30 Inter) in the
 * overlay's foreground white; the kind is a smaller muted label; the hover is
 * `--base-color`, the amber of the overlay's own close button. The «Нічого не
 * знайдено» line is the same row.
 *
 * Classes, not order, make it win from this first-served file: no theme
 * selector names these elements.
 */
.search-popup .search-popup__results {
  position: absolute;
  top: 50%;
  inset-inline: 15px;
  max-width: 700px;
  max-height: calc(50% - 85px);
  margin: 55px auto 0;
  padding: 0 30px;
  border-radius: 5px;
  background-color: #111111;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: rgba(255, 255, 255, 0.4) transparent;
}
.search-popup .search-popup__results p {
  margin: 0;
  padding: 10px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  color: var(--white);
}
.search-popup .search-popup__results p:last-child {
  border-bottom: 0;
}
.search-popup .search-popup__results a {
  /* The gap belongs to the link, not the label: where the label wraps to its
     own line (at 390), it then starts flush with the title, not 12px in. */
  margin-inline-end: 12px;
  color: var(--white);
}
.search-popup .search-popup__results a:hover {
  color: var(--base-color);
}
.search-popup .search-popup__kind {
  font-size: 14px;
  white-space: nowrap;
  color: rgba(255, 255, 255, 0.6);
}
@media only screen and (max-width: 767.98px) {
  .search-popup .search-popup__results {
    max-height: calc(50% - 75px);
    margin-top: 45px;
  }
}
