/*
Theme Name: Blacksilver Child
Theme URI: https://pscott.photo/
Description: Child theme for Blacksilver — all customizations for pscott.photo live here so the parent theme can be updated without losing changes.
Author: Paul Scott
Author URI: https://pscott.photo/
Template: blacksilver
Version: 0.9.1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: blacksilver-child
*/

/* Custom styles for pscott.photo go below this line. */

/*
 * Mobile layout fix
 * ---
 * The parent theme's style.css ends up loading AFTER css/responsive.css in this
 * install because the child theme's defensive enqueue re-registers the parent
 * stylesheet at a later priority. Both files have `.responsive-menu-wrap` rules
 * at identical specificity:
 *   responsive.css  @media (max-width:1050px) { display: block }
 *   style.css       display: none   (no media query)
 * Last one loaded wins, so the mobile wrap stayed hidden at narrow viewports,
 * which in turn meant common.js's `isMobileMenuActive()` check returned false
 * and `mobile-mode-active` never got added to <body>. Result: 300px left-margin
 * stayed on, hamburger never appeared, layout looked broken on mobile.
 *
 * Using !important inside the same @media query from the child stylesheet (which
 * loads last) so we don't need to touch either parent file.
 */
@media only screen and (max-width: 1050px) {
  #mobile-toggle-menu,
  .responsive-menu-wrap {
    display: block !important;
  }
}

/*
 * Vertical sidebar width
 * ---
 * Parent theme hardcodes the left-nav column at 300px across multiple selectors
 * (no customizer setting exists for it). Overriding with a single custom property
 * so the value lives in one place.
 *
 * The parent sets `.vertical-menu-wrap` 20px wider than `.vertical-menu-outer` and
 * clips the overflow on the outer — a trick meant to hide the scrollbar. That
 * renders inconsistently (Safari leaves a visible gray strip between where the
 * Instagram grid ends and where the image column begins). To avoid it entirely,
 * we collapse the wrap to the same width as the outer and hide the scrollbar
 * via CSS instead.
 */
:root { --vm-width: 260px; }

.vertical-menu-outer,
.vertical-menu-wrap,
.vertical-footer-wrap,
.vertical-menu-wrap .insta-grid-wrap,
.vertical-menu-wrap .instagram-first-three {
  width: var(--vm-width) !important;
}
/* Hide the scroll track that the parent's 20px overflow trick used to cover */
.vertical-menu-wrap { scrollbar-width: none; }            /* Firefox */
.vertical-menu-wrap::-webkit-scrollbar { display: none; } /* WebKit (Safari/Chrome) */

.menu-is-vertical:not(.mobile-mode-active) {
  margin-left: var(--vm-width) !important;
}
/*
 * Only the slideshow/fullscreen engines need an explicit narrowed width —
 * they're position:fixed and take viewport coords. Regular pages rely on the
 * body's margin-left to do the work and should NOT have container-wrapper or
 * outer-wrap shrunk further (that's what caused the ugly white strip on the
 * right edge of internal pages like Blog Small).
 */
.menu-is-vertical:not(.mobile-mode-active) #fotorama-container-wrap,
.menu-is-vertical:not(.mobile-mode-active) .fullscreen-slideshow-bg,
.menu-is-vertical:not(.mobile-mode-active) .fullscreen-slideshow {
  width: calc(100% - var(--vm-width)) !important;
}
/* Only the specific fullscreen-splitslider variant had a container-wrapper width rule in the parent */
.menu-is-vertical.page-is-fullscreen.fullscreen-splitslider:not(.mobile-mode-active) .container-wrapper {
  width: calc(100% - var(--vm-width)) !important;
}

/*
 * Slideshow/Fotorama left-offset
 * ---
 * Several parent rules also use `left: 300px` or `margin-left: 301px` (not just
 * width) to push the slideshow engine past the sidebar. Without these overrides,
 * the body's gray background peeks through between where the 260px sidebar ends
 * and where the 300px-offset slideshow begins. Shift them all by --vm-width.
 */
.menu-is-vertical:not(.mobile-mode-active) #supersized,
.menu-is-vertical:not(.mobile-mode-active) #supersized li,
.menu-is-vertical:not(.mobile-mode-active) #vertical-center-wrap {
  left: var(--vm-width) !important;
  width: calc(100% - var(--vm-width)) !important;
}
.menu-is-vertical:not(.mobile-mode-active) #fotorama-container-wrap {
  margin-left: var(--vm-width) !important;
}
/* Slideshow play/pause controls sat 50px inside the old 300 sidebar */
.menu-is-vertical:not(.mobile-mode-active) .slideshow-controls-wrap {
  left: calc(var(--vm-width) + 50px) !important;
}

/*
 * Sidebar vertical compaction + footer re-ordering
 * ---
 * The child theme overrides `template-parts/menu/vertical-menu.php` to put
 * the social icons ABOVE the Instagram grid and drop the copyright block
 * entirely. With that structure, `.vertical-footer-wrap` flex-column now
 * lays out as:
 *
 *     .vertical-footer-wrap-inner  (socials only)
 *     .footer-end-block            (Instagram grid, flush to bottom)
 *
 * Parent theme uses lavish vertical padding around the logo (90+50) and the
 * Instagram block (parent-rule `.vertical-menu-wrap .footer-end-block
 * { padding-bottom: 30px }` at style.css:10242). We zero those out so:
 *   - the logo sits tight against the top
 *   - the Instagram grid sits flush against the bottom of the viewport
 *   - the socials row gets a little breathing room below it before Instagram
 */
.vertical-logo-wrap {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}
.footer-end-block {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  /*
   * Pull the Instagram widget up by 5px so the visible gap between the bottom of
   * the social icon glyphs and the top of the first grid tile shrinks to ~5px.
   * The raw gap is ~10px: 7px of empty space below the 13px-tall glyph inside its
   * 20px anchor, plus 3px of stacked borders at the top of the widget.
   */
  margin-top: -5px;
  border: 2.5px solid #000;
  box-sizing: border-box;
}

/*
 * Instagram grid — border + per-tile spacing
 * ---
 * Target: 5px of solid black all the way around the widget AND 5px between any two tiles.
 *
 * Approach: give the wrapper a 2.5px border and every tile a 2.5px border. Borders on
 * adjacent edges stack visually:
 *   - between tiles: 2.5 (tile A right) + 2.5 (tile B left) = 5px
 *   - between outer edge of grid and tile: 2.5 (wrapper inside) + 2.5 (tile edge) = 5px
 *
 * `box-sizing: border-box` on the tiles keeps the 33.33% square-via-padding math intact
 * (parent sets `width: 33.3333%; padding-bottom: 33.3333%` with the photo as background-image).
 * Same color as the sidebar background so the gaps read as negative space.
 */
.vertical-menu-wrap .instagram-first-three li,
.vertical-menu-wrap .ri-grid ul li {
  border: 2.5px solid #000;
  box-sizing: border-box;
}

/*
 * Hide Smash Balloon's raw feed output in the sidebar
 * ---
 * Blacksilver's common.js waits for Smash Balloon's `[instagram-feed]` shortcode
 * to render (profile photo + header text + image grid + load-more button), then
 * scrapes image URLs from `#sbi_images img` and builds its own `.ri-grid` for
 * the visual sidebar widget. During that handoff the raw Smash Balloon output
 * flashes briefly — profile picture, bio snippet, Follow button — before the
 * custom grid replaces it visually.
 *
 * Hide the whole Smash Balloon container so the flash is gone. Use visibility +
 * position:absolute rather than `display: none`, because:
 *   - display:none can skip lazy-loaded images, which would break the scrape
 *   - visibility:hidden keeps layout-engine rendering intact so srcs populate
 *   - position:absolute with 0 height removes it from normal flow so it doesn't
 *     reserve space above the .ri-grid
 *
 * Scoped to the sidebar (`.vertical-menu-wrap`) so the same Smash Balloon feed
 * on other pages (if any get added later) isn't accidentally hidden.
 */
.vertical-menu-wrap #sb_instagram {
  position: absolute !important;
  visibility: hidden !important;
  height: 0 !important;
  width: 0 !important;
  overflow: hidden !important;
  pointer-events: none !important;
}
.vertical-footer-wrap-inner {
  /*
   * Parent rule `.vertical-menu-outer .vertical-footer-wrap-inner` sets
   * `padding: 0 32px 40px` (32px horizontal, 40px bottom). Fully override it:
   *   - no top or bottom padding (socials sit tight on the Instagram widget below)
   *   - 5px horizontal padding so the left-aligned label and the right-aligned
   *     social icons both sit 5px from the sidebar edge, mirroring the 5px inset
   *     of the Instagram grid below (2.5px wrapper border + 2.5px tile border)
   *
   * Flex row so the `.instagram-label` and `.login-socials-wrap` sit on the same
   * baseline — label left, icons right.
   */
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 5px !important;
}

/*
 * "@pscottphoto" Instagram label (anchor → instagram.com/pscottphoto)
 * ---
 * Matches the muted white used for social icons and the 11px type scale that
 * `style.css:8625` applies elsewhere in the vertical-footer-wrap. Kept on a
 * single line (white-space: nowrap) so it never wraps and shove the icons down.
 *
 * Since the element is now an <a>, also set `text-decoration: none` (parent
 * theme underlines anchors by default in some contexts) and a hover brighten
 * to full white so it reads as interactive. Matches the hover behavior the
 * parent theme gives to sidebar social icons.
 *
 * `position: relative; top: -2px` nudges the label up 2px from the flex
 * baseline without moving the social icons. The flex row's `align-items: center`
 * keeps the two flex items vertically centered on each other; this offset then
 * lifts the label alone so it visually sits slightly above the icon row rather
 * than on the same centerline.
 */
.vertical-footer-wrap-inner .instagram-label {
  color: rgba(255, 255, 255, 0.8);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.2px;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  position: relative;
  top: -2px;
}
.vertical-footer-wrap-inner a.instagram-label:hover,
.vertical-footer-wrap-inner a.instagram-label:focus {
  color: #fff;
  text-decoration: none;
}

/*
 * Socials — right-align, sit tight on top of the Instagram widget
 * ---
 * Parent `.social-header-wrap` defaults to `float: right` in header contexts but in the
 * vertical-menu sidebar it ends up centered/left because `.login-socials-wrap` has no
 * explicit alignment and the parent ul/li mix inline-block with inherited text-align.
 * Force right alignment on every layer (wrap, ul, li) and kill any float/padding that
 * would push the row away from the Instagram widget below it.
 */
.vertical-footer-wrap .login-socials-wrap {
  text-align: right;
  padding: 0;
  margin: 0;
}
.vertical-footer-wrap .social-header-wrap {
  float: none;
  text-align: right;
  width: 100%;
}
.vertical-footer-wrap .social-header-wrap ul {
  text-align: right;
  padding: 0;
  margin: 0;
}
.vertical-footer-wrap .social-header-wrap ul li {
  float: none;
  display: inline-block;
  text-align: right;
}
/*
 * Parent rule `.vertical-footer-wrap .social-header-wrap ul li.social-icon`
 * (style.css:10352) gives every social-icon `padding: 0 3px` AND a
 * `margin-top: 7px`. Three problems to correct:
 *   1. Between icons the 3px + 3px stacked up to a 6px gap — zeroed so the
 *      1px gap that remains comes only from inline-block whitespace (killed
 *      via `font-size: 0` on the ul below).
 *   2. The rightmost icon's 3px stacked with the wrap-inner's 5px right-padding,
 *      pushing it 8px from the sidebar edge. Zero the right padding on the last
 *      icon so it sits flush against the wrap's 5px inset, matching the Instagram
 *      grid (also 5px off the edge via 2.5px wrapper + 2.5px tile border).
 *   3. The 7px top margin leaves a band of black space above the icons, making
 *      them look like they float high in the socials row. Zero it so the icon
 *      anchors sit tight against the top of the row, directly above the IG grid.
 *
 * Also kill the inline-block whitespace gap between the two icons — `font-size: 0`
 * on the ul collapses the text-node whitespace to zero width; the icon anchor's
 * own font-size (set on the `<a>` / `<i>` by the parent theme) is unaffected.
 */
.vertical-footer-wrap .social-header-wrap ul {
  font-size: 0;
}
.vertical-footer-wrap .social-header-wrap ul li.social-icon {
  padding: 0;
  margin-top: 0 !important;
}
/*
 * The 20x20 anchor ("hit area") is wider than the Font Awesome glyph inside.
 * Each glyph is centered in its 20px anchor via `text-align: center`, leaving
 * 4–6px of empty space on each side. Result: anchors that are physically
 * touching still *look* ~10px apart. Pull adjacent anchors inward with a
 * negative left margin so the visible glyphs end up ~2px apart.
 */
.vertical-footer-wrap .social-header-wrap ul li.social-icon + li.social-icon {
  margin-left: -2px;
}

/*
 * Collapse vertical space above the Instagram widget
 * ---
 * Two sources of unwanted vertical gap between the socials row and the Instagram grid:
 *   1. `<h3 class="instagram-username">` — emitted by `grid-instagram.php` whenever the
 *      Customizer's `insta_username` option is non-empty. Defaults to a visible Instagram
 *      heading (with username) above the grid; default h3 margins add ~30-40px. We don't
 *      want it rendering in the sidebar at all, so hide it.
 *   2. Inherited `line-height: 1.4+` on the socials wrap/ul. The social-icon `<a>` itself
 *      is 20px tall (parent rule), but the ul's own line-height adds leading above and
 *      below. Collapsing to line-height: 1 removes that.
 */
.vertical-menu-wrap .instagram-username {
  display: none !important;
}
.vertical-footer-wrap .login-socials-wrap,
.vertical-footer-wrap .social-header-wrap,
.vertical-footer-wrap .social-header-wrap ul {
  margin: 0 !important;
  line-height: 1 !important;
}

/*
 * Mobile drawer background
 * ---
 * Parent stylesheet sets `.responsive-mobile-menu { background: none }` at
 * line 3489, overriding an earlier `background: #fff` on the same selector.
 * Result: when the hamburger is tapped the drawer slides onscreen correctly
 * (visibility + right:0 + opacity:1 all work) but is fully transparent, so
 * the slideshow bleeds through and the drawer looks broken/invisible.
 *
 * The Blacksilver demo uses an opaque dark panel; match that by giving the
 * drawer the same gray used by the body/sidebar so it reads as a solid
 * overlay over the slideshow.
 */
.responsive-mobile-menu {
  background: #505050 !important;
}

/*
 * Sidebar background test
 * ---
 * Parent sets `.vertical-menu-wrap { background: #505050 }` at style.css:10444.
 * Testing a solid-black sidebar to see how it reads against the photography.
 * Also flipping the body background to match so the slideshow doesn't show a
 * different-gray strip behind positioned elements during transitions, and the
 * mobile drawer (which sits over the slideshow) stays consistent.
 *
 * Revert by removing this block if the gray looks better.
 */
.vertical-menu-wrap {
  background: #000 !important;
}
body {
  background-color: #000 !important;
}
.responsive-mobile-menu {
  background: #000 !important;
}

/*
 * Homepage body background override
 * ---
 * The global `body { background-color: #000 }` rule above keeps the body
 * harmonized with the black sidebar on interior pages — it only ever shows
 * in narrow gaps behind positioned elements, and a dark strip there looks
 * intentional.
 *
 * The homepage has a different constraint. The Supersized slideshow is
 * pinned `position: fixed` at `top: 0` and is shifted upward by
 * `home-hero-fade.js` in lockstep with scroll, which exposes a strip of
 * bare body background between the bottom edge of the departing slideshow
 * and the top edge of the rising feed. The `.fj-home-hero-fade` overlay
 * sits on top of that exposed strip at a partial alpha (driven by the same
 * scroll position). Black body × ~27% white overlay composites to roughly
 * rgb(70,70,70) — a gray that visually reads as a solid rectangle and, by
 * coincidence, matches #454545 (the footer bg) closely enough to look
 * like stray footer chrome parked under the hero.
 *
 * Painting the body white on the homepage only makes that composite
 * white-over-white = white, which matches the feed's own background and
 * makes the slideshow-to-feed transition read as a clean dissolve to white
 * rather than an intermediate gray plate. Scoped to `body.home` so
 * interior pages keep the black-body harmonization with the sidebar.
 */
body.home {
  background-color: #fff !important;
}

/*
 * =============================================================================
 * Sidebar search form
 * =============================================================================
 * Parent theme does not render a search form inside `.vertical-menu` —
 * `blacksilver/template-parts/menu/vertical-menu.php` has no searchform call.
 * The child override at `blacksilver-child/template-parts/menu/vertical-menu.php`
 * adds it back via `get_template_part('mobile', 'searchform')`, reusing the
 * same markup/ids (`#mobile-searchform`, `#ms`, `#mobile-searchbutton`) as the
 * mobile drawer so parent's partial `.vertical-menu #mobile-searchform` hooks
 * (style.css:3549, 7059-7078) all apply unchanged.
 *
 * What the parent provides for `.vertical-menu` scope:
 *   - container padding 25px 0 40px 0
 *   - input: 1px solid rgba(255,255,255,.25) border, 100% width
 *   - icon color transitions
 *
 * What the parent only provides for `.simple-menu` / `.responsive-mobile-menu`
 * (and which we need to replicate here for the vertical sidebar):
 *   - input background, border-radius, text-indent, font sizing
 *   - absolute-positioned submit button
 *
 * Layout choices for the sidebar context:
 *   - Symmetric vertical padding on the form so the button's `top: 50%` anchor
 *     centers cleanly on the input.
 *   - Slightly smaller font + padding than the mobile drawer — the sidebar is
 *     ~300px wide vs. the mobile drawer's comfortable edge-to-edge space.
 *   - Right padding on the input reserves room for the icon button so user
 *     text never slides under the magnifier glyph.
 *   - Subtle rgba background on the input so the field reads as an affordance
 *     against the solid-black sidebar without shouting.
 */
.vertical-menu #mobile-searchform {
  position: relative;
  display: block;
  margin: 0 35px;
  /* Symmetric vertical padding — the submit button uses `top: 50%` absolute
   * positioning which measures against the form's padding box, so asymmetric
   * padding pulls the icon off the input's visual center. */
  padding: 15px 0;
  max-width: calc(100% - 70px);
  box-sizing: border-box;
}
.vertical-menu #mobile-searchform input {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 30px;
  box-sizing: border-box; /* include padding inside the 100% width */
  color: rgba(255, 255, 255, 0.85);
  font-size: 13px;
  font-weight: 400;
  height: auto;           /* override parent's #ms height: 16px */
  padding: 8px 34px 8px 16px;
  text-indent: 0;
  width: 100%;
}
.vertical-menu #mobile-searchform input:focus {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.45);
  outline: none;
}
.vertical-menu #mobile-searchform input::placeholder {
  color: rgba(255, 255, 255, 0.45);
}
.vertical-menu #mobile-searchbutton {
  position: absolute;
  top: 50%;
  right: 12px;
  transform: translateY(-50%);
  background: transparent;
  border: 0;
  padding: 0;
  line-height: 0;
  cursor: pointer;
}

/*
 * =============================================================================
 * Field Journal — parent theme wrapper overrides
 * =============================================================================
 * The parent theme applies 50px left/right padding and 56px bottom padding to
 * `.container` on all non-Elementor pages, and also renders a
 * `.title-container-outer-wrap` banner above the post body via
 * `template-parts/header-title.php`. For Field Journal single posts we want
 * the hero to run edge-to-edge (sidebar right edge → viewport right edge) and
 * the parent title banner to disappear entirely so our custom hero is the
 * first thing the reader sees.
 *
 * Scoped to `body.single-post` so it only affects posts (post_type='post'),
 * not pages or other post types that still want the default theme chrome.
 */
body.single-post .container {
  width: 100% !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  padding-bottom: 0 !important;
}
body.single-post .title-container-outer-wrap {
  display: none !important;
}

/*
 * =============================================================================
 * Search results — hero banner layout
 * =============================================================================
 * Scope class `.fj-search-has-hero` is added to the body by
 * `inc/search-hero.php` only when a search-hero image is configured in the
 * Customizer AND the current request is `is_search()`. See that file's
 * docblock for the mechanism; rules here are purely visual.
 *
 * Parent CSS gives `.title-container-outer-wrap` `padding: 100px 0 24px`
 * which is enough for a thin text banner but reads as cropped on a photo
 * background. We extend it to a proper hero-sized banner:
 *   - `min-height: 350px` — gives the featured image room to breathe
 *   - Flex center — the H1 sits visually centered in the banner instead of
 *     anchored to the top via padding
 *   - Bottom margin tightened — parent adds 50px (`styles-content.css:18304`);
 *     we knock it down so the hero flows into the results without a big gap
 */
.fj-search-has-hero .title-container-outer-wrap {
  min-height: 350px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 28px;
}
.fj-search-has-hero .title-container-wrap {
  /* Flex centering on the outer wrap means the H1's wrapper can drop its
   * extra top padding — parent's 100px top padding no longer serves a layout
   * purpose when the content is vertically centered via flex. */
  width: 100%;
}
/*
 * White title text over the dark-overlaid photo, matching About/Contact
 * Elementor heroes (parent stylesheet's default is near-black — fine for the
 * plain banner, wrong on a darkened image). Values copied from
 * `uploads/elementor/css/post-12068.css` so all three hero styles read as a
 * single family.
 */
.fj-search-has-hero .title-container-outer-wrap .entry-title,
.fj-search-has-hero .title-container-outer-wrap .entry-title span {
  color: #ffffff;
}

/*
 * Search results — meta row spacing (author/date/category)
 * ---
 * Parent's `template-parts/postformats/post-data.php` renders the meta row as
 * two `display: inline-block` groups inside `.datecomment`:
 *     .post-single-meta-group-one → author + date
 *     .post-single-meta-group-two → category (+ comment count when enabled)
 * Each `.post-single-meta` span carries `margin-right: 14px` from
 * `styles-content.css:18905`, including the last span in each group — a
 * trailing margin that on desktop just adds air to the right of the row but
 * on narrow phone viewports was enough to tip group-two onto a second line.
 *
 * Two related issues in this layout:
 *   1. Trailing `margin-right` on the last span in group-two was pushing the
 *      meta row over the mobile line-width budget, wrapping `YOSEMITE` to a
 *      second row on ~375px viewports.
 *   2. Author→date lives inside group-one and picks up the 14px span margin;
 *      date→category crosses the group-one/group-two boundary and picks up
 *      (date's 14px span margin) + (inline-block whitespace between the two
 *      group `<div>`s) — ~18px vs ~14px — so the three items read as
 *      unevenly spaced side-by-side with the Journal index.
 *
 * Fix: make `.datecomment` and each inner group a flex container with a
 * uniform 14px `column-gap`, and zero the legacy per-span `margin-right`
 * within `.fj-search-results`. Flex `column-gap` only applies *between*
 * siblings, so there's no trailing margin to budget against the line width
 * (issue 1) and every gap — author↔date inside group-one, date↔category
 * across the group boundary — is exactly 14px (issue 2). `flex-wrap: wrap`
 * preserves the graceful wrap-to-two-lines behavior if the viewport does
 * still get too narrow (no overflow / no clipping).
 *
 * Applied at every viewport rather than behind a media query: the flex
 * treatment produces identical spacing to the desktop default rhythm
 * (14px + a hair of inline whitespace, collapsed to exactly 14px by flex)
 * so there's no visible change at wide widths.
 *
 * Scope is `.fj-search-results` so this never leaks to the Journal index
 * or single posts, which use the same `.datecomment` markup but are happy
 * with the parent's `margin-right` rhythm.
 */
.fj-search-results .datecomment {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 14px;
  row-gap: 4px;
}
.fj-search-results .post-single-meta-group-one,
.fj-search-results .post-single-meta-group-two {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 14px;
  row-gap: 4px;
}
.fj-search-results .datecomment .post-single-meta {
  margin-right: 0;
}

/*
 * Search results — page margins matching the Journal index
 * ---
 * The Journal index at `/journal/` is an Elementor page, so it carries
 * `body.elementor-page`. The parent theme's mobile rule
 *   body:not(.elementor-page) .container { padding: 0 30px }
 * at `responsive.css:990` therefore SKIPS Journal entirely. Its visible
 * side gutter comes from one level in instead — Elementor's
 * `.elementor-column-gap-wider > .elementor-column > .elementor-element-populated`
 * which adds 30px of padding on *every* viewport, not just mobile.
 *
 * On desktop the difference is concrete: Journal's content column is
 * `.container` (1120px) minus 30px on each side from the Elementor column
 * padding = 1060px. Search has no Elementor chain, so `.container` sits at
 * the full 1120px and our content reads ~60px wider than the Journal index.
 * That's the "wider page margins" Paul was seeing side-by-side: not wider
 * *outer* margins but a wider content column pushing everything closer to
 * the viewport edge than Journal does.
 *
 * Fix: mirror Journal's ancestor chain. Strip `.container`'s horizontal
 * padding on search-results, then move the 30px gutter down to our own
 * `.fj-search-results` wrapper so it applies at every viewport — matching
 * Elementor's always-on column padding instead of the parent theme's
 * mobile-only container padding.
 *
 * `body.search-results` scope on the `.container` override keeps the
 * rule from touching any other page that happens to use `.contents-wrap`.
 * `box-sizing: border-box` on `.fj-search-results` keeps the footprint
 * identical to the parent theme's assumption about `.container`'s
 * effective width.
 */
body.search-results .container {
  padding-left: 0;
  padding-right: 0;
}
.fj-search-results {
  padding-left: 30px;
  padding-right: 30px;
  box-sizing: border-box;
}

/*
 * Search hero title — two-line layout with About-style subline treatment
 * ---
 * Parent `header-title.php` renders the search title as:
 *     <h1 class="entry-title">Search Results for: <span>{query}</span></h1>
 * (prefix comes from the Customizer option `archive_search_notfoundtitleprefix`;
 *  the `<span>` always wraps just the query, per `header-title.php` line 88).
 *
 * We repurpose the existing prefix/span split to mimic the About page hero:
 *   - Big line: the prefix ("Search Results for:")
 *   - Small subline with horizontal dashes: the query itself
 * On the About page that subline ("— ABOUT —") is an Elementor-composed element;
 * here it's synthesized in CSS from the `<span>` so no markup changes are needed.
 *
 * Turning the H1 into a flex column stacks the prefix text and span vertically
 * and centers them both. `text-align: center` is a belt-and-braces for any
 * inherited alignment.
 */
.fj-search-has-hero .title-container-outer-wrap .entry-title {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 18px;
}
.fj-search-has-hero .title-container-outer-wrap .entry-title span {
  /* The query is shown as a small uppercase subline flanked by short rules,
   * echoing the About page's "— ABOUT —" treatment. `display: inline-flex`
   * puts the pseudo-element rules and the text on a single baseline-aligned
   * row regardless of the parent H1's font size.
   *
   * `font-size: 0.32em` and `letter-spacing: 0.35em` are eyeball-calibrated to
   * the About hero at the typical viewport width; adjust if the prefix title
   * size changes via Customizer (General → Typography → Page Title).
   */
  display: inline-flex;
  align-items: center;
  gap: 18px;
  font-size: 0.32em;
  font-weight: 400;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  line-height: 1;
}
.fj-search-has-hero .title-container-outer-wrap .entry-title span::before,
.fj-search-has-hero .title-container-outer-wrap .entry-title span::after {
  content: "";
  display: inline-block;
  width: 36px;
  height: 1px;
  background-color: currentColor;
}

/*
 * =============================================================================
 * Field Journal — single post styling
 * =============================================================================
 * Custom single-post render from `single.php` + `loop-single.php` in the child
 * theme. Two zones:
 *   1. `.fj-hero`  — full-viewport featured image with title + date + category overlay
 *   2. `.fj-body`  — reading column with inline images breaking out to full-width
 *
 * Key trick: text elements (p, h2/h3/h4, lists, quotes) get per-element
 * `max-width: 760px` for a readable column, but `.fj-body-inner` itself is NOT
 * capped. That lets `.wp-block-image` naturally span the full content width
 * without any full-width-escape CSS gymnastics.
 *
 * Inline photos cap at `max-height: 85vh` so the whole frame fits the viewport
 * vertically without scrolling — Paul's explicit pain point with the parent
 * theme's default behavior.
 *
 * All selectors are prefixed `.fj-*` to avoid colliding with parent theme or
 * block-editor default classes.
 */

.fj-entry {
  margin: 0;
  padding: 0;
}

/* --- Hero --------------------------------------------------------------- */

/*
 * Two-layer hero: `.fj-hero-image` holds the background photo, `.fj-hero-overlay`
 * holds the text. Separating them makes it easy to tune image positioning and
 * overlay gradient independently. The `::after` on `.fj-hero-image` is a subtle
 * dark gradient (15% top, 50% bottom) to keep white title text readable over
 * bright or busy photos without muddying the image on the rest of the frame.
 */
/*
 * Hero height is intentionally less than 100vh so a sliver of the body
 * content (white background + start of the first paragraph/heading) peeks
 * above the fold. That visual cue signals "keep scrolling" without
 * sacrificing the hero's visual impact. 85vh leaves ~15% of the viewport
 * (roughly 100–130px on typical laptop screens) showing the body below.
 */
.fj-hero {
  position: relative;
  width: 100%;
  height: 85vh;
  overflow: hidden;
}
/*
 * Anchor wraps the hero so clicking anywhere on the image opens the Simple
 * Lightbox gallery (wired up via `wp_footer` JS in functions.php which forwards
 * the click to the hidden `.fj-hero-lightbox-anchor` injected into the_content).
 * Absolute positioning + inset:0 makes it fill the hero without changing the
 * layout of its absolute children.
 */
.fj-hero-link {
  display: block;
  position: absolute;
  inset: 0;
  color: inherit;
  text-decoration: none;
}
.fj-hero-link:hover,
.fj-hero-link:focus {
  color: inherit;
  text-decoration: none;
}
.fj-hero-image {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}
.fj-hero-image::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.50) 100%);
  pointer-events: none;
}
.fj-hero-overlay {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 24px;
  color: #fff;
  text-align: center;
}
.fj-hero-text {
  max-width: 800px;
}
.fj-hero .fj-hero-title,
.fj-hero h1.fj-hero-title {
  font-size: clamp(2rem, 5vw, 4rem);
  font-weight: 700;
  line-height: 1.15;
  margin: 0 0 20px;
  color: #fff;
  text-shadow: 0 2px 14px rgba(0,0,0,0.35);
}
.fj-hero .fj-hero-meta {
  font-size: 0.95rem;
  font-style: italic;
  opacity: 0.9;
  color: #fff;
  text-shadow: 0 1px 8px rgba(0,0,0,0.35);
}
.fj-hero-sep {
  display: inline-block;
  margin: 0 0.5em;
  opacity: 0.6;
  font-style: normal;
}
.fj-hero-category {
  font-style: italic;
}

/* --- Body reading column ----------------------------------------------- */

/*
 * White background for high-contrast readable text against the black sidebar.
 * Tight top padding (32px) so the first content block reads as continuous with
 * the hero rather than floating in a big white void. Generous bottom padding
 * keeps the tail of the entry from colliding with the nav.
 */
.fj-body {
  background: #fff;
  padding: 32px 0 80px;
  color: #555;
}
.fj-body-inner {
  font-size: 1.0625rem; /* ~17px */
  line-height: 1.75;
  font-weight: 400;
  /*
   * 840px = 760px reading column + 40px padding each side. Constraining the
   * container (rather than individual elements) keeps text, images, and floats
   * all within the same visual column without needing per-element overrides.
   */
  max-width: 1120px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 40px;
  padding-right: 40px;
  box-sizing: border-box;
}

/*
 * Clearfix so trailing floats (alignleft/alignright) don't bleed past the
 * body into the nav block below.
 */
.fj-body-inner::after {
  content: "";
  display: block;
  clear: both;
}

/* Per-element inset for text. max-width and margin:auto are now effectively
 * no-ops (the container is already 760px content width) but the 24px padding
 * gives text a comfortable inset that images intentionally don't share. */
.fj-body-inner > p,
.fj-body-inner > h1,
.fj-body-inner > h2,
.fj-body-inner > h3,
.fj-body-inner > h4,
.fj-body-inner > h5,
.fj-body-inner > h6,
.fj-body-inner > ul,
.fj-body-inner > ol,
.fj-body-inner > blockquote,
.fj-body-inner > figure.wp-block-pullquote,
.fj-body-inner > .wp-block-quote {
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 24px;
  padding-right: 24px;
}

/* Applied by JS only to siblings that are visually beside an alignleft float.
   overflow:hidden forms a BFC so the browser sizes the block to fit the
   remaining space beside the float rather than running underneath it.
   Both margins must be 0: margin-left:auto (from the base reading-column rule)
   would otherwise absorb the space and push the block rightward. */
.pscott-float-adjacent {
  margin-left: 0;
  margin-right: 0;
  overflow: hidden;
}

/*
 * Force left-align on headings and paragraphs in the body. Gutenberg heading
 * blocks that were authored with center alignment add `has-text-align-center`,
 * and the parent theme has a bunch of `text-align: center` rules that can
 * bleed in. The `!important` flags override both at once.
 */
.fj-body-inner > h1,
.fj-body-inner > h2,
.fj-body-inner > h3,
.fj-body-inner > h4,
.fj-body-inner > h5,
.fj-body-inner > h6,
.fj-body-inner > p {
  text-align: left !important;
}

.fj-body-inner h1,
.fj-body-inner h2,
.fj-body-inner h3,
.fj-body-inner h4 {
  color: #111;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-top: 1.5em;
  margin-bottom: 0.6em;
}
.fj-body-inner h1 { font-size: 2.5rem; }
.fj-body-inner h2 { font-size: 2rem; }
.fj-body-inner h3 { font-size: 1.5rem; }
.fj-body-inner h4 { font-size: 1.2rem; }

/*
 * First heading in the body — typically the post's title, embedded as a
 * heading block by the migration. Pull its top margin to 0 so it sits
 * tight against the hero/body boundary.
 */
.fj-body-inner > h1:first-child,
.fj-body-inner > h2:first-child,
.fj-body-inner > h3:first-child {
  margin-top: 0;
}

.fj-body-inner p {
  margin: 0 0 1.5em;
}

/*
 * Lead paragraph — first paragraph of the body gets slightly bolder/darker
 * type to match the demo's visual hierarchy (bold intro, lighter body).
 * Applies only to the very first paragraph child, not every paragraph after
 * a heading.
 */
.fj-body > .fj-body-inner:first-of-type > p:first-of-type {
  color: #222;
  font-weight: 600;
  font-size: 1.15rem;
  line-height: 1.6;
}

/*
 * Hidden anchor injected at the top of post content (see `the_content` filter
 * in functions.php). Simple Lightbox auto-activates it as the first entry in
 * the post's image gallery so the featured image is reachable via the
 * lightbox. Visually hidden with the standard screen-reader-only pattern;
 * aria-hidden + tabindex=-1 in the markup keep it out of keyboard/AT flow.
 * `.click()` calls from JS still fire even when pointer-events: none, so
 * the hero-click forwarder in functions.php can trigger it programmatically.
 */
.fj-hero-lightbox-anchor {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  opacity: 0;
  pointer-events: none;
}
.fj-hero-lightbox-anchor img {
  width: 1px;
  height: 1px;
}

/* --- Inline photos ------------------------------------------------------ */

/*
 * Image and figure blocks sit as direct children of `.fj-body-inner` without
 * the reading-column cap, so they naturally span the full content width
 * (= viewport width minus the left sidebar). The `<img>` inside is capped at
 * `max-height: 85vh` with `width: auto` so aspect ratio is preserved and the
 * whole frame fits the viewport vertically — no scrolling required to see
 * the full photo.
 *
 * Figcaptions reuse the 760px reading column so caption text stays comfortable
 * to read even when the photo above is much wider.
 */
.fj-body-inner .wp-block-image,
.fj-body-inner figure.wp-block-image,
.fj-body-inner > figure {
  margin: 3em 0;
  width: 100%;
  max-width: 100%;
  text-align: center;
}

/*
 * When classic-editor / pasted HTML images end up as naked <img> inside a <p>,
 * WordPress doesn't wrap them in a figure. Break the containing paragraph out
 * to the full content width (matching our figure.wp-block-image treatment) so
 * the image has room to render at its capped height without being pinched by
 * the paragraph's reading-column constraints.
 */
.fj-body-inner p:has(> img) {
  max-width: 100% !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  text-align: center;
  margin: 3em 0;
}

/*
 * Cap inline photos using a viewport-minus-chrome calculation rather than a
 * straight percentage. 100vh minus 140px reserves room for: browser toolbar
 * (~90px on typical setups), the image block's top margin (~48px), and the
 * caption line below (~30px). The practical result is that any inline photo
 * sits fully inside the viewport without scrolling, across common viewport
 * heights from ~700px up.
 *
 * `!important` on max-height / width / height is load-bearing: Gutenberg
 * image blocks render with explicit `width` and `height` HTML attributes
 * matching the image's intrinsic dimensions, and some parent-theme and
 * WP-core rules also touch img sizing. Without `!important` those can win
 * the specificity race and bypass the cap.
 *
 * Selector covers three cases:
 *   1. `<figure class="wp-block-image">` — proper Gutenberg image block
 *   2. naked `<figure>` without wp-block-image (rare)
 *   3. `<p><img></p>` — classic-editor or pasted-HTML inline image
 */
.fj-body-inner .wp-block-image img,
.fj-body-inner figure img,
.fj-body-inner p > img,
.fj-body-inner > img {
  display: block;
  margin: 0 auto;
  max-width: 100% !important;
  max-height: calc(100vh - 140px) !important;
  width: auto !important;
  height: auto !important;
  object-fit: contain;
}
.fj-body-inner > .wp-block-image figcaption,
.fj-body-inner > figure figcaption {
  max-width: 760px;
  margin: 0 auto 0;
  padding: 0 24px;
  text-align: center;
  font-size: 0.875rem;
  color: #888;
  font-style: italic;
  line-height: 1.5;
}

/*
 * Aligned inline images — `.alignleft` and `.alignright` float so body text
 * wraps alongside them. Cap at 45% of the content block so the wrap column
 * stays readable. Explicit side margins give the image breathing room away
 * from the wrapped text. The body-inner's horizontal padding supplies the
 * gap between the image and the content area's outer edge.
 *
 * These rules sit after the default `.wp-block-image` figure rule so they
 * override its `width: 100%` / `margin: 3em 0` / `text-align: center` when
 * an alignment class is present. Specificity: `.fj-body-inner .wp-block-image.alignright`
 * (0,2,1) beats `.fj-body-inner .wp-block-image` (0,2,0).
 */
.fj-body-inner .wp-block-image.alignright,
.fj-body-inner figure.alignright,
.fj-body-inner > .alignright {
  float: right;
  clear: right;
  width: auto;
  max-width: 45%;
  margin: 0.5em 0 1.5em 2em;
  text-align: right;
}
.fj-body-inner .wp-block-image.alignleft,
.fj-body-inner figure.alignleft,
.fj-body-inner > .alignleft {
  float: left;
  clear: left;
  width: auto;
  max-width: 45%;
  margin: 0.5em 2em 1.5em 0;
  text-align: left;
}

/* Fix: prevent pscott-btp figure from expanding wider than its image */
.fj-body-inner figure.pscott-btp,
.fj-body-inner figure.pscott-btp.alignleft,
.fj-body-inner figure.pscott-btp.alignright {
  width: fit-content !important;
}

/*
 * Figcaption inside a floated image — keep it tight to the photo, left- or
 * right-aligned to match the float direction rather than centered.
 */
.fj-body-inner .alignright figcaption {
  text-align: right;
  max-width: none;
  padding: 0;
  margin: 0.5em 0 0;
}
.fj-body-inner .alignleft figcaption {
  text-align: left;
  max-width: none;
  padding: 0;
  margin: 0.5em 0 0;
}

/*
 * On narrow screens, floating a 45%-wide photo leaves the wrap column
 * uncomfortably skinny. Below 800px, drop floats and let aligned images
 * stack like regular inline photos.
 */
@media (max-width: 800px) {
  .fj-body-inner .wp-block-image.alignright,
  .fj-body-inner figure.alignright,
  .fj-body-inner > .alignright,
  .fj-body-inner .wp-block-image.alignleft,
  .fj-body-inner figure.alignleft,
  .fj-body-inner > .alignleft {
    float: none;
    max-width: 100%;
    margin: 2em 0;
    text-align: center;
  }
}

/* --- Prev/next nav at bottom ------------------------------------------- */

.fj-nav {
  background: #fff;
  padding: 40px 0 80px;
  border-top: 1px solid #eee;
}

/* --- Mobile ------------------------------------------------------------ */

/*
 * On narrow viewports a 100vh hero pushes the body out of first-scroll reach,
 * which hurts scan-ability. Drop the hero to 70vh and tighten body padding.
 * Also pulls the lead paragraph's font-size down slightly so it doesn't feel
 * shouty at phone widths.
 */
@media (max-width: 1050px) {
  .fj-hero { height: 70vh; }
  .fj-body { padding: 40px 0; }
  .fj-body-inner > .wp-block-image,
  .fj-body-inner > figure {
    margin: 2em 0;
  }
  .fj-body-inner > p:first-of-type {
    font-size: 1.05rem;
  }
}

/*
 * =============================================================================
 * Home page — two-layer hero + feed
 * =============================================================================
 * Render logic is in `front-page.php`; this section is layout + the crossfade
 * surface. Scroll-driven opacity on `.fj-home-hero-fade` is set by
 * `js/home-hero-fade.js` (see `inc/home-feed.php` for the enqueue).
 *
 * Z-order, bottom → top:
 *   1. #supersized         — Supersized slideshow (parent: z-index -30..-10, position:fixed)
 *   2. .fj-home-hero-fade  — white crossfade overlay (fixed, opacity scroll-driven)
 *   3. .fj-home-scroll-hint — chevron affordance, pinned to bottom of hero
 *   4. .fj-home-feed       — the content grid, scrolls up over the hero
 *
 * Mobile: `.fj-home-hero` isn't rendered at all (`wp_is_mobile()` gate in
 * front-page.php) and is CSS-hidden defensively for narrow viewports that
 * slip past the UA check. Feed sits at top:0 and IS the page.
 */

/*
 * Unlock scrolling on the homepage.
 *
 * The parent theme injects an inline style for every fullscreen slideshow
 * engine (see `blacksilver/functions.php` ~L598–641, the `wp_add_inline_style`
 * calls attached to `blacksilver-ResponsiveCSS`). For the Supersized
 * `slideshow` variant we're on, the injected rule is:
 *
 *   body { position: absolute; top: 0; left: 0; height: 100%; width: 100%;
 *          min-height: auto; min-width: 100%; }
 *
 * That pins <body> to viewport dimensions and takes it out of document flow,
 * so <html> has no content to scroll past — wheel/trackpad/touch events
 * simply can't scroll the page. (Anchor-link jumps still appear to "work"
 * because the browser scrolls the viewport to an in-viewport fragment, which
 * happens to reveal our feed, but there's no scrollable overflow behind it.)
 *
 * We specifically want scroll on the front page because the whole interaction
 * is "hero pinned, feed rises from below." Override only for `body.home` so
 * the parent's fullscreen behavior continues to apply to every OTHER
 * fullscreen page (single-fullscreen portfolios, etc.) where scroll really
 * should stay locked.
 *
 * Specificity: `body.home` (0,1,1) beats the parent's inline `body` (0,0,1).
 * No !important needed.
 */
body.home {
  position: static;
  height: auto;
  width: auto;
  min-height: 100vh;
}

/*
 * Belt-and-suspenders: the parent theme also sets
 *   .page-is-fullscreen .container-wrapper { height: 100%; }
 * on a wrapper that's body's direct child. With body pinned, that 100% was
 * a viewport-clamped wrapper; once body grows with our content, height:100%
 * resolves against an auto-height body and collapses unpredictably. Force
 * it to grow with content on the homepage.
 */
body.home .container-wrapper {
  height: auto;
  min-height: 100vh;
}

.fj-home-hero {
  /*
   * Zero layout footprint — the hero MUST NOT push the feed down the page.
   *
   * Why: the hero's visible children (Supersized #supersized UL, .fj-home-hero-fade,
   * .fj-home-scroll-hint, captions, audio player) are all `position: fixed` relative
   * to the viewport. Reserving 100vh of layout space here would mean the feed sits
   * at (100vh + feed's own margin) = 200vh from the document top, creating a dead
   * scroll band between the fade completing and the feed arriving. We want feed
   * and fade to animate on the SAME scroll range, so the hero wrapper is a pure
   * semantic container with no layout size; the 100vh "slideshow zone" at the top
   * of the page is reserved by `.fj-home-feed`'s margin-top instead.
   *
   * `pointer-events: none` so this invisible wrapper can't accidentally intercept
   * scroll or clicks. Individual fixed children (like the scroll-hint link) set
   * `pointer-events: auto` to opt back in.
   */
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0;
  pointer-events: none;
}
.fj-home-hero > * {
  pointer-events: auto;
}

/*
 * Crossfade overlay — fixed, starts transparent and uniformly fades to
 * solid white as the user scrolls. Opacity is scroll-driven via the
 * `--fj-fade-alpha` custom property, set every frame by home-hero-fade.js.
 *
 * Scoped to the slideshow's footprint via `left: var(--vm-width)` so the
 * left vertical sidebar is never covered — the sidebar stays fully visible
 * throughout the scroll, consistent with every other page on the site.
 *
 * Default alpha `0` keeps the overlay invisible before JS runs — safe
 * for FOUC / no-JS fallback, since the correct pre-scroll state is just
 * "slideshow visible".
 */
.fj-home-hero-fade {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(255, 255, 255, var(--fj-fade-alpha, 0));
  pointer-events: none;  /* never intercept clicks on the slideshow or the scroll hint */
  z-index: 1;            /* above #supersized (-30..-10), below .fj-home-feed (2) */
  will-change: background;
}

.menu-is-vertical:not(.mobile-mode-active) .fj-home-hero-fade {
  left: var(--vm-width);
}

/*
 * Scroll affordance — pinned to the bottom of the visible hero. Label +
 * bouncing chevron, anchor-linked to `#fj-home-feed` so keyboard users can
 * activate it via tab+enter. Uses calc() on `left` to center inside the
 * slideshow's footprint (viewport minus sidebar), not the full viewport.
 */
.fj-home-scroll-hint {
  position: fixed;
  bottom: 40px;
  left: calc(var(--vm-width) + ((100vw - var(--vm-width)) / 2));
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  /*
   * Gray pseudo-stroke around the label so it stays readable over busy
   * slideshow frames (bright skies, high-contrast rock, white-capped
   * waves). Built from 8 directional 1px solid shadows forming a ring
   * around each glyph, plus a soft shadow beneath for depth. Gray
   * (#555) rather than black so the outline reads as a subtle lift,
   * not a hard stencil.
   *
   * Why not `-webkit-text-stroke` instead: that property paints stroke
   * INSIDE the glyph outline, eating into already-thin uppercase
   * letterforms at this size. Multi-shadow stays outside the glyph so
   * the letters keep their weight.
   */
  text-shadow:
    -1px -1px 0 #555,
     0   -1px 0 #555,
     1px -1px 0 #555,
     1px  0   0 #555,
     1px  1px 0 #555,
     0    1px 0 #555,
    -1px  1px 0 #555,
    -1px  0   0 #555,
     0    1px 4px rgba(0, 0, 0, 0.5);
  transition: color 0.2s ease, opacity 0.2s ease;
}
.fj-home-scroll-hint:hover,
.fj-home-scroll-hint:focus {
  color: #fff;
  text-decoration: none;
}
.fj-home-scroll-hint-label {
  /* Slight weight so the small caps don't dissolve against busy slides. */
  font-weight: 500;
}
/*
 * Chevron built from two 1.5px borders on a rotated square. Scales with
 * currentColor (inherits from the anchor), so the hover-brighten above
 * covers the chevron too. Pure CSS — no icon font, no SVG fetch.
 */
.fj-home-scroll-hint-chevron {
  width: 12px;
  height: 12px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  animation: fj-scroll-hint-bounce 2s ease-in-out infinite;
  /* Same readability concern as the label above — a white chevron on a
   * white cloud/sky disappears. `drop-shadow` on the element hugs the
   * actual L-shape of the two borders (unlike `box-shadow`, which would
   * wrap the padded square bounding box). Two layered shadows: a tight
   * 1px gray for the outline (matching the label's stroke color), and
   * a looser soft shadow for depth. */
  filter:
    drop-shadow(0 0 1px #555)
    drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
}
@keyframes fj-scroll-hint-bounce {
  0%, 100% { transform: rotate(45deg) translate(0, 0);   opacity: 0.85; }
  50%      { transform: rotate(45deg) translate(3px, 3px); opacity: 1;    }
}

/* Hint sits on top of the fade overlay. When the user scrolls far enough
 * that the hero is fully hidden behind white, the hint shouldn't remain
 * visible on the white background — fade it out in tandem with scroll.
 * Pinned to viewport bottom (position: fixed), so once the fade has reached
 * full opacity it would otherwise look like a floating label on white, AND
 * stay painted on top of the gray footer at the bottom of the page.
 *
 * Reuses `--fj-hero-controls-opacity` — the same body-level custom property
 * home-hero-fade.js already writes to dim the Supersized pause/progress
 * chrome. That property is `1` at scrollY === 0 and `0` on any scroll, which
 * is exactly the behavior we want for the hint: visible while the user is
 * still looking at the slideshow, gone the instant they commit to scrolling.
 * `pointer-events` is matched so the hint stops intercepting clicks too.
 *
 * CSS variable already cascades from <body>, so no extra selector plumbing
 * or JS change is needed here. The existing `opacity 0.2s ease` transition
 * on `.fj-home-scroll-hint` (above) handles the smooth fade-out. */
.fj-home-scroll-hint {
  opacity: var(--fj-hero-controls-opacity, 1);
  pointer-events: var(--fj-hero-controls-pointer, auto);
}

/* Admin bar adds 32px (46px on mobile) of chrome at the top of the viewport.
 * The bottom-pinned scroll hint isn't affected, but leaving this guard here
 * in case we reposition it to the top later. */

/*
 * Homepage-only: anchor Supersized's slide <li> elements to #supersized.
 * ---
 * Supersized's own stylesheet sets `#supersized li { position: fixed }`
 * so every slide is pinned to the viewport rather than to #supersized.
 * That's fine for the default single-page fullscreen layout, but it
 * fights our scroll-out effect — moving #supersized with inline `top`
 * (via home-hero-fade.js) doesn't drag the slides along because fixed
 * positioning ignores the ancestor's position.
 *
 * Switching the slide <li> to `position: absolute` on the homepage
 * anchors them to the nearest positioned ancestor, which is #supersized
 * (itself `position: fixed`). Now when the JS moves #supersized upward
 * as the user scrolls, the slides ride along and #supersized's
 * `overflow: hidden` naturally clips them at the top edge.
 *
 * Scoped to `body.home` so single-fullscreen portfolio pages, the
 * slideshow CPT, and any other Supersized-using template keep the
 * parent's default fixed positioning. `!important` beats Supersized's
 * own stylesheet declaration without resorting to even-higher
 * specificity trickery.
 */
/*
 * Selector specificity note
 * ---
 * The vertical-menu offset rule earlier in this file uses the selector
 * `.menu-is-vertical:not(.mobile-mode-active) #supersized li` which has
 * specificity (0,1,2,1). A plain `body.home #supersized li` — (0,1,1,2)
 * — loses to it even with `!important`, because `!important` ties are
 * still decided by specificity. So we mirror the menu-is-vertical
 * scoping to beat it: (0,1,3,2) > (0,1,2,1).
 *
 * The secondary plain `body.home #supersized li` below handles the
 * (rare) case where the site isn't rendering the vertical-menu class
 * — keeps the position: absolute override in place for any homepage
 * variant, since the scroll-out effect depends on it.
 */
body.home.menu-is-vertical:not(.mobile-mode-active) #supersized li,
body.home #supersized li {
  position: absolute !important;
  /*
   * The vertical-menu offset rule higher in this file sets
   * `left: var(--vm-width); width: calc(100% - var(--vm-width))` on
   * `#supersized li` as well as `#supersized`. That made sense when
   * the li was `position: fixed` (same viewport coordinate space as
   * its parent), but now that we've moved it to `position: absolute`
   * its positioning context IS #supersized — which already has the
   * menu-width left inset applied. Inheriting the same inset on the
   * child would double-offset it and leave a black gap between the
   * menu and the slideshow image. Reset to 0/100% so each slide fills
   * its (already-inset) parent.
   */
  left: 0 !important;
  width: 100% !important;
}

/*
 * Supersized slideshow controls — homepage scroll-out
 * ---
 * The parent theme renders pause/prev/next as `.slideshow-controls-wrap` and
 * the progress bar as `#progress-back`, both `position: fixed`. Its default
 * visibility rule is `.preloader-done:hover .slideshow-controls-wrap { opacity: 1 }`
 * — once the user's cursor is anywhere over the page, the controls stay lit.
 * That's fine for a single-page fullscreen slideshow, but here the feed
 * scrolls up over the slideshow and those fixed controls end up floating
 * over feed copy and card buttons as stray chrome.
 *
 * On the homepage we tie the controls' opacity to the inverse of the hero
 * fade curve (set on <body> by home-hero-fade.js). At scrollY = 0 the
 * controls are fully visible and clickable; by scrollY = 100vh they're
 * invisible and click-through. We also kill the parent's transition so
 * the opacity tracks scroll in real time instead of lagging 0.5s behind.
 *
 * `.slideshow-list-wrap` is the slide-thumbnail tray (right-side dots). Not
 * every preset renders it, but include it for safety — same fixed-position
 * chrome, same scroll-dismiss rule.
 */
body.home .slideshow-controls-wrap,
body.home #progress-back,
body.home .slideshow-list-wrap {
  opacity: var(--fj-hero-controls-opacity, 1) !important;
  transition: none !important;
  pointer-events: var(--fj-hero-controls-pointer, auto);
}

/*
 * =============================================================================
 * Home feed — grid of cards
 * =============================================================================
 */
.fj-home-feed {
  position: relative;
  z-index: 2;           /* above the crossfade overlay (z-index 1) */
  /*
   * Scroll-driven background fade — the feed rises from below the viewport
   * with a transparent-to-white background that tracks scroll progress.
   * `--fj-feed-bg-opacity` is updated by home-hero-fade.js on every scroll
   * frame, using the same 0→1 / 0→100vh curve as the .fj-home-hero-fade
   * overlay. Combined effect: the slideshow fades (via the fixed overlay)
   * AND the rising feed darkens from transparent to opaque, in lockstep.
   *
   * Default `1` is a safety fallback — if JS fails or is disabled the feed
   * ends up fully opaque (correct final state) instead of transparent. The
   * fallback never visibly flashes on load because the feed sits at
   * `margin-top: 100vh`, which keeps it entirely below the viewport at
   * scroll=0, so nobody sees it until JS has already set the custom prop.
   *
   * Mobile (`--standalone` class and the narrow-viewport @media rule below)
   * pins this back to a solid `#fff` — on mobile the slideshow isn't
   * rendered, so there's nothing the feed could tastefully "fade in over."
   */
  background: rgba(255, 255, 255, var(--fj-feed-bg-opacity, 1));
  /*
   * Reserve exactly 100vh at the top of the page for the pinned slideshow.
   * Because `.fj-home-hero` has zero layout size, this margin measures from
   * the document top, so the feed's top edge sits flush against the bottom
   * of the viewport at scroll=0 and reaches the top at scroll=100vh. The
   * fade overlay's opacity (set by home-hero-fade.js) uses the same scroll
   * range, so fade-out and feed-rise progress in lockstep.
   */
  margin-top: 100vh;
  padding: 80px 0 120px;
  color: #222;
}

/*
 * Phones only: skip the whole hero. Tablets (iPads, ≥768px) get the
 * slideshow. The server-side gate in front-page.php matches this breakpoint.
 */
@media (max-width: 767px) {
  .fj-home-hero,
  .fj-home-hero-fade,
  .fj-home-scroll-hint {
    display: none !important;
  }
  /* Supersized slideshow + chrome stays hidden on narrow viewports.
   *
   * The hero wrapper our child theme renders (`.fj-home-hero`) isn't
   * emitted on mobile UAs (see front-page.php's wp_is_mobile() gate),
   * but the parent theme injects `#supersized` into the DOM unconditionally
   * on the homepage — it's wired into the Imaginem Blocks II plugin, not
   * the front-page template we override. That fixed-position slideshow
   * sits behind everything at `top: 0`, `position: fixed`, filling the
   * viewport, with the feed scrolling over it.
   *
   * On narrow viewports the feed's mobile rules below strip its 100vh top
   * margin and paint it solid white, so when the viewport exactly matches
   * the feed's coverage you see only the feed. The problem shows up at the
   * edges: iOS rubber-band overscroll, the footer area below the last
   * feed card, and brief moments during scroll where the feed hasn't fully
   * covered the viewport — all expose the slideshow image pinned behind it,
   * which reads as a broken layout.
   *
   * Simplest fix: hide `#supersized` itself on narrow viewports, homepage-
   * scoped. The element stays in the DOM so the parent theme's Supersized
   * init JS can still find and operate on it without erroring — we just
   * never paint it. Chrome selectors below are kept for the same reason
   * they were before: the parent theme's pause/progress controls are
   * positioned independently and would otherwise float over the feed. */
  body.home #supersized,
  body.home .slideshow-controls-wrap,
  body.home #progress-back,
  body.home .slideshow-list-wrap {
    display: none !important;
  }
  .fj-home-feed {
    /* `!important` here because the unconditional `.fj-home-feed`
     * declaration (with `margin-top: 100vh` and a var-driven bg) is
     * defined *later* in this stylesheet than this media query block.
     * Media queries don't add specificity, so without !important the
     * later rule wins by source order and the feed stays pinned 100vh
     * down even at narrow widths. Same story for the background. */
    margin-top: 0 !important;
    /* JS-driven bg fade only makes sense when the feed is rising over a
     * slideshow. On narrow viewports the hero is hidden, so the feed is
     * the whole page — use a solid white background and ignore the
     * custom property the desktop JS would otherwise drive. */
    background: #fff !important;
  }
  /* Same reasoning for the content fade — without a hero behind it, the
   * feed's content shouldn't start invisible. The `opacity: var(...)`
   * declaration for `.fj-home-feed-inner` further down the stylesheet
   * would otherwise beat this override by source order (see note on
   * `.fj-home-feed` above), hence `!important`. JS may still be enqueued
   * on narrow-desktop viewports (the enqueue is gated on wp_is_mobile(),
   * not on window width), so this also defensively neutralizes any
   * var-driven opacity the desktop JS would otherwise apply. */
  .fj-home-feed-inner {
    opacity: 1 !important;
  }
}

/*
 * iPad portrait: hide the slideshow, same treatment as phones. Landscape
 * iPads (width > height) keep the slideshow. min-width: 768px excludes
 * phones in landscape (which share the portrait block's max-width: 767px).
 */
@media (min-width: 768px) and (max-width: 1050px) and (orientation: portrait) {
  .fj-home-hero,
  .fj-home-hero-fade,
  .fj-home-scroll-hint {
    display: none !important;
  }
  body.home #supersized,
  body.home .slideshow-controls-wrap,
  body.home #progress-back,
  body.home .slideshow-list-wrap {
    display: none !important;
  }
  .fj-home-feed {
    margin-top: 0 !important;
    background: #fff !important;
  }
  .fj-home-feed-inner {
    opacity: 1 !important;
  }
}

/*
 * When the hero is server-side skipped (mobile UA match), front-page.php
 * adds `.fj-home-feed--standalone` to the feed. This covers the edge case
 * of a phone in landscape wider than 1050px — no hero in DOM, but also no
 * 100vh gap at the top, and no rising-over-slideshow interaction to fade
 * the background for.
 */
.fj-home-feed.fj-home-feed--standalone {
  margin-top: 0;
  background: #fff;
}
.fj-home-feed.fj-home-feed--standalone .fj-home-feed-inner {
  /* No fade-in on mobile — content is the whole page, not a reveal. */
  opacity: 1;
}

.fj-home-feed-inner {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 40px;
  /*
   * Feed content (heading + cards) fades in on the same scroll curve as
   * the feed's background — see `--fj-feed-content-opacity` set by
   * home-hero-fade.js. Inherits from `.fj-home-feed`, which is where the
   * JS writes the property. Default `1` keeps the content fully visible
   * if JS never runs (mobile / narrow, where the fade choreography
   * doesn't apply anyway).
   *
   * Using CSS `opacity` (not alpha on individual elements) because it
   * fades the entire content tree — kicker, title, meta, image, excerpt
   * — uniformly as one layer. The feed background rgba fade handles the
   * "emerging from white" backdrop; this handles the "content emerging
   * from invisibility" foreground. Together they read as a single
   * unified reveal rather than a backdrop crossfade with already-
   * visible content painted on top.
   */
  opacity: var(--fj-feed-content-opacity, 1);
}

.fj-home-feed-heading {
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #222;
  margin: 0 0 48px;
}

.fj-home-feed-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 56px 32px;
}
@media (max-width: 1200px) {
  .fj-home-feed-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .fj-home-feed-grid { grid-template-columns: 1fr; gap: 40px; }
  .fj-home-feed-inner { padding: 0 24px; }
}

/*
 * --- Card ---
 * Entire card is a single anchor for generous click-target. Image on top,
 * body below. Hover state is a quiet image zoom + title color darken —
 * no lift/shadow gymnastics that would feel template-y.
 */
.fj-home-feed-card {
  margin: 0;
}
.fj-home-feed-card-link {
  display: block;
  color: inherit;
  text-decoration: none;
}
.fj-home-feed-card-link:hover,
.fj-home-feed-card-link:focus {
  color: inherit;
  text-decoration: none;
}
.fj-home-feed-card-media {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: #f2f2f2;
  margin-bottom: 16px;
}
.fj-home-feed-card-media .fj-home-feed-card-image {
  width: 100%;
  height: 100% !important;
  object-fit: cover;
  display: block;
  transition: transform 0.6s ease;
}
.fj-home-feed-card-link:hover .fj-home-feed-card-image,
.fj-home-feed-card-link:focus .fj-home-feed-card-image {
  transform: scale(1.03);
}
.fj-home-feed-card-kicker {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #888;
  margin-bottom: 6px;
}
.fj-home-feed-card-title {
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.25;
  color: #111;
  margin: 0 0 8px;
  transition: color 0.2s ease;
}
.fj-home-feed-card-link:hover .fj-home-feed-card-title,
.fj-home-feed-card-link:focus .fj-home-feed-card-title {
  color: #000;
}
.fj-home-feed-card-meta {
  font-size: 0.8rem;
  font-style: italic;
  color: #888;
  margin-bottom: 10px;
}
.fj-home-feed-card-excerpt {
  font-size: 0.9rem;
  line-height: 1.55;
  color: #555;
  /* Clamp to three lines so mixed-length excerpts don't throw off the grid. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.fj-home-feed-all {
  display: inline-block;
  margin-top: 56px;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #111;
  text-decoration: none;
  border-bottom: 1.5px solid #111;
  padding-bottom: 2px;
  transition: opacity 0.2s ease;
}
.fj-home-feed-all:hover,
.fj-home-feed-all:focus {
  opacity: 0.65;
  color: #111;
  text-decoration: none;
}

.fj-home-feed-empty {
  color: #666;
  font-style: italic;
}

/*
 * Homepage gray footer — lift above the fade overlay AND re-apply the
 * parent theme's footer styling that gets dropped on fullscreen pages.
 * ---
 * Two problems, both scoped to the homepage:
 *
 * 1) Stacking
 *    `front-page.php` inlines the parent's `.footer-outer-wrap` copyright
 *    block so the homepage closes with the same gray bar every other page
 *    has (parent `footer.php` suppresses its own render when
 *    `blacksilver_is_fullscreen_post()` is true). `.fj-home-hero-fade` is
 *    `position: fixed; z-index: 1` and becomes fully opaque white once the
 *    user scrolls past the hero — a statically-positioned footer paints
 *    BEFORE positioned elements in the root stacking context regardless of
 *    DOM order, so it ends up hidden behind the white overlay at the
 *    bottom of the page. `position: relative; z-index: 2` promotes the
 *    footer into the same layer as `.fj-home-feed`.
 *
 * 2) Missing content styles
 *    Blacksilver only enqueues `styles-content.css` — the parent theme's
 *    big stylesheet that includes `.footer-outer-wrap { background:#454545 }`,
 *    `#copyright { padding:40px 0; text-align:center }`, and the
 *    `.horizontal-footer-copyright` typography — on NON-fullscreen pages.
 *    The homepage has `body.page-is-fullscreen` so that stylesheet never
 *    loads. The footer markup we inlined from the parent renders but gets
 *    zero styling — transparent background, left-aligned default-font
 *    black text, no padding. We re-declare the parent's exact rules here
 *    so the homepage footer is visually identical to every other page's
 *    (About, Contact, single posts, Journal index, …) without having to
 *    enqueue the whole 20k-line parent stylesheet. Values mirror
 *    `blacksilver/css/styles-content.css:7967–8004` + overrides at
 *    `:18063–18067`. If the parent theme ever changes its footer styling
 *    the source of truth stays those files — bump these in tandem.
 *
 * Scoped to `body.home` so this only affects the homepage. Every other
 * page gets its footer from the parent's own `footer.php` under
 * `styles-content.css`, which is already loaded there. */
body.home .footer-outer-wrap {
  position: relative;
  z-index: 2;
  background: #454545;
}
body.home #copyright {
  display: block;
  padding: 40px 0 40px;
  text-align: center;
  box-sizing: border-box;
}
body.home #copyright.footer-logo-absent {
  padding-top: 22px;
}
body.home #copyright .footer-logo {
  display: block;
  text-align: center;
  color: #7a7a7a;
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
}
body.home .footer-logo-image {
  width: 123px;
  max-width: 100%;
}
body.home .horizontal-footer-copyright {
  display: block;
  text-align: center;
  color: #b8b8b8;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 4px;
  line-height: 1.2;
}
body.home .horizontal-footer-copyright a {
  color: inherit;
}
body.home .horizontal-footer-copyright a:hover {
  color: #fff;
}

/* ==========================================================================
   Yosemite Map page
   ========================================================================== */

/* Zero out whatever top gap the parent theme's #home wrapper adds */
.yosemite-map-page {
  margin-top: 0 !important;
  padding-top: 0 !important;
}

.page-template-page-templates-yosemite-map-php #goto-top,
.page-template-yosemite-map-php #goto-top,
.page-template-page-templates-yosemite-map-php .progress-wrap,
.page-template-yosemite-map-php .progress-wrap {
  display: none !important;
}

/* Intro text between hero and map */
.yosemite-map-intro {
  padding: 48px 0 40px;
  font-size: 16px;
  line-height: 1.75;
  color: #444;
}
.yosemite-map-intro p:last-child {
  margin-bottom: 0;
}

/* Controls bar — toggle pill + location dropdown on one line */
.yosemite-map-panel {
  position: relative;
  margin-top: 20px;
  margin-bottom: 20px;
}
.yosemite-map-panel::after {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px solid #aaa;
  pointer-events: none;
  z-index: 9999;
}
.yosemite-map-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 0;
  padding: 10px 14px;
  background: #f5f5f3;
  border-bottom: 1px solid #222;
  position: relative;
  z-index: 1001;
}

/* Map mode toggle pill — order: 2 pushes it to the right; dropdown stays left */
.yosemite-map-toggle {
  display: flex;
  gap: 0;
  order: 2;
  flex-shrink: 0;
}
@media (max-width: 600px) {
  .yosemite-map-controls {
    flex-direction: column;
    align-items: flex-start;
  }
  .yosemite-map-toggle {
    order: 2;
  }
  .yl-loc-select {
    order: 1;
    width: 100%;
  }
  .yl-loc-select__trigger {
    width: 100%;
    justify-content: space-between;
  }
}
.yosemite-toggle-btn {
  padding: 5px 16px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: transparent;
  border: 1px solid #ccc;
  color: #777;
  cursor: pointer;
  line-height: 1.4;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.yosemite-toggle-btn:first-child {
  border-radius: 2px 0 0 2px;
}
.yosemite-toggle-btn:last-child {
  border-radius: 0 2px 2px 0;
  border-left: none;
}
.yosemite-toggle-btn.is-active {
  background: #222;
  border-color: #222;
  color: #fff;
}
.yosemite-toggle-btn:hover:not(.is-active) {
  background: rgba(0,0,0,0.05);
  color: #444;
  border-color: #aaa;
}

/* Map page hero banner */
.yosemite-map-hero {
  position: relative;
  width: calc(100% + 100px);
  margin-left: -50px;
  margin-right: -50px;
  height: 260px;
  background: #1a1a1a;
  background-size: cover;
  background-position: center;
  overflow: hidden;
  margin-bottom: 0;
}
.yosemite-map-hero__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.6) 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding: 28px 32px;
  text-align: center;
}
.yosemite-map-hero__text {
  max-width: 700px;
  text-align: center;
}
.yosemite-map-hero__eyebrow {
  position: relative;
  display: inline-block;
  color: #fff !important;
  text-shadow: 0 1px 8px rgba(0,0,0,0.4);
  margin: 0 0 10px;
  opacity: 0.9;
}
.yosemite-map-hero__eyebrow::before,
.yosemite-map-hero__eyebrow::after {
  content: '';
  position: absolute;
  bottom: calc(50% - 1px);
  width: 30px;
  height: 1px;
  background: rgba(255,255,255,0.7);
}
.yosemite-map-hero__eyebrow::before { left: -45px; }
.yosemite-map-hero__eyebrow::after  { right: -45px; }
.yosemite-map-hero__title {
  font-size: clamp(1.8rem, 3.5vw, 3rem);
  font-weight: 700;
  color: #fff !important;
  margin: 0 0 8px;
  line-height: 1.1;
  text-shadow: 0 2px 14px rgba(0,0,0,0.35);
}
.yosemite-map-hero__sub {
  font-size: 14px;
  color: rgba(255,255,255,0.8);
  margin: 0;
  font-style: italic;
  text-shadow: 0 1px 8px rgba(0,0,0,0.35);
}

.yosemite-map-container {
  width: 100%;
  height: calc(100vh - 114px);
  min-height: 400px;
  background: #1a1a1a;
}
/* Allow pin card popups to overflow the map container without clipping.
   Leaflet sets overflow:hidden on .leaflet-container for tile rendering,
   but the popup pane doesn't need that constraint. */
.yosemite-map-container .leaflet-popup-pane {
  overflow: visible;
}
.yosemite-map-container.leaflet-container {
  overflow: hidden;
}
.admin-bar .yosemite-map-container {
  height: calc(100vh - 114px - 32px);
}

/* Prevent Leaflet's default focus outline from flashing on click */
.yosemite-map-container:focus {
  outline: none;
}

/* Reset and fullscreen buttons — match Leaflet's zoom control style */
.yosemite-reset-btn,
.yosemite-fullscreen-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  background: #fff;
  border: none;
  cursor: pointer;
  padding: 0;
  margin-top: 4px;
}
.yosemite-reset-btn:hover,
.yosemite-fullscreen-btn:hover {
  background: #f4f4f4;
}
.yosemite-reset-btn svg,
.yosemite-fullscreen-btn svg {
  width: 14px;
  height: 14px;
  display: block;
  fill: #444;
}

/* Fullscreen — map fills the whole screen */
.yosemite-map-container:fullscreen {
  width: 100vw;
  height: 100vh;
}
.yosemite-map-container:-webkit-full-screen {
  width: 100vw;
  height: 100vh;
}

.yosemite-map-attribution {
  margin: 0 !important;
  padding: 6px 14px;
  background: #f5f5f3;
  border-top: 1px solid #222;
  font-size: 10px;
  color: #aaa;
  letter-spacing: 0.04em;
}

/* Markers */
.yosemite-marker {
  background: none;
  border: none;
  cursor: pointer;
  overflow: visible !important;
}
.yosemite-pin-svg {
  filter: drop-shadow(0 2px 5px rgba(0,0,0,0.55));
  transition: transform 0.1s ease;
  transform-origin: bottom center;
  transform: scale(calc(var(--marker-scale, 0.45) * var(--marker-hover, 1)));
  display: block;
}
.yosemite-marker:hover .yosemite-pin-svg {
  --marker-hover: 1.25;
}
.yosemite-pin-body {
  fill: #22c55e;
}
.yosemite-pin-hole {
  fill: rgba(0, 0, 0, 0.28);
}
.yosemite-marker-label {
  display: none;
  position: absolute;
  left: 32px;
  top: 4px;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,0.9);
  pointer-events: none;
}
.yosemite-marker:hover .yosemite-marker-label {
  display: block;
}

/* Pin hover tooltip card */
/* Pin popup card — shared by hover preview and pinned-click state */
/* pointer-events: auto always so mouseenter/mouseleave fire on the popup,
   enabling hover-to-keep-open behaviour. */
.leaflet-popup.yl-pin-card-popup,
.leaflet-popup.yl-pin-card-popup * {
  pointer-events: auto;
}
.leaflet-popup.yl-pin-card-popup .leaflet-popup-content-wrapper {
  padding: 0;
  border-radius: 8px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.22);
  overflow: hidden;
  border: none;
}
.leaflet-popup.yl-pin-card-popup .leaflet-popup-content {
  margin: 0;
}
.leaflet-popup.yl-pin-card-popup .leaflet-popup-tip {
  background: #fff;
  box-shadow: none;
}
/* When popup opens below the pin: hide the default bottom tip and draw an
   upward-pointing triangle at the top of the card with a pseudo-element. */
.leaflet-popup.yl-pin-card-popup.popup-below .leaflet-popup-tip-container {
  display: none;
}
.leaflet-popup.yl-pin-card-popup.popup-below::before {
  content: '';
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 10px solid #fff;
  pointer-events: none;
}
.yl-pin-card {
  position: relative;
  width: 190px;
}
.yl-pin-card__close {
  position: absolute;
  top: 7px;
  right: 7px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0;
  z-index: 1;
  background: rgba(255, 255, 255, 0.75);
}
.leaflet-popup.yl-pin-card-popup.is-pinned .yl-pin-card__close {
  display: flex;
}
.yl-pin-card__close:hover {
  background: rgba(255, 255, 255, 0.95);
}
.yl-pin-card__close svg {
  width: 10px;
  height: 10px;
  display: block;
  stroke: #222;
}
.yl-pin-card--no-thumb .yl-pin-card__close {
  background: transparent;
}
.yl-pin-card--no-thumb .yl-pin-card__close svg {
  stroke: #888;
}
.yl-pin-card--no-thumb .yl-pin-card__close:hover svg {
  stroke: #111;
}
.yl-pin-card__thumb-link {
  display: block;
}
.yl-pin-card .yl-pin-card__thumb {
  display: block;
  width: 100%;
  height: 112px;
  object-fit: cover;
}
.yl-pin-card__body {
  padding: 10px 12px 13px;
}
.yl-pin-card__title {
  font-size: 13px;
  font-weight: 700;
  color: #111;
  line-height: 1.3;
  margin: 0 0 8px;
}
.yl-pin-card__link {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #555;
  text-decoration: none;
}
.yl-pin-card__link:hover {
  color: #111;
}

/* Location dropdown */
.yl-loc-select {
  position: relative;
}
.yl-loc-select__trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: transparent;
  border: 1px solid #ccc;
  border-radius: 2px;
  color: #777;
  cursor: pointer;
  white-space: nowrap;
  line-height: 1.4;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.yl-loc-select__trigger:hover {
  background: rgba(0,0,0,0.05);
  color: #444;
  border-color: #aaa;
}
.yl-loc-select__chevron {
  width: 10px;
  height: 6px;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}
.yl-loc-select__trigger[aria-expanded="true"] .yl-loc-select__chevron {
  transform: rotate(180deg);
}
.yl-loc-select__menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 200px;
  max-height: 260px;
  overflow-y: auto;
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(208, 208, 208, 0.6);
  border-radius: 3px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  list-style: none;
  margin: 0;
  padding: 4px 0;
  z-index: 1000;
}
.yl-loc-select__item {
  padding: 8px 14px;
  font-size: 13px;
  color: #333;
  cursor: pointer;
  list-style: none;
}
.yl-loc-select__item:hover {
  background: rgba(0, 0, 0, 0.07);
  color: #111;
}

/* ==========================================================================
   Yosemite Location detail page (single-yosemite_location.php)
   ========================================================================== */

/* Hero breakout — escapes .container's 50px horizontal padding so the hero
   spans the full content area (sidebar right edge to viewport right edge).
   The centering trick (calc(50% - 50vw)) doesn't work here because the
   sidebar shifts the content area off-center by var(--vm-width)/2. */
.yl-entry .fj-hero {
  width: calc(100vw - var(--vm-width));
  margin-left: -50px;
  margin-right: -50px;
}
/* At mobile the sidebar hides and content goes full-width; reset to flow. */
@media (max-width: 1050px) {
  .yl-entry .fj-hero {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
  }
}
.yl-entry .fj-body {
  padding-top: 12px;
}
.yl-entry .yl-details-section {
  margin-top: 12px;
}

/* Eyebrow label above the location title — inherits h5 styles (16px, uppercase, letter-spaced) */
.fj-hero-text .yl-eyebrow {
  position: relative;
  width: fit-content;
  margin: 0 auto 12px;
  color: #fff;
  text-shadow: 0 1px 8px rgba(0,0,0,0.35);
  opacity: 0.9;
}
.fj-hero-text .yl-eyebrow::before,
.fj-hero-text .yl-eyebrow::after {
  content: '';
  position: absolute;
  bottom: calc(50% - 1px);
  width: 30px;
  height: 1px;
  background: rgba(255,255,255,0.7);
}
.fj-hero-text .yl-eyebrow::before { left: -45px; }
.fj-hero-text .yl-eyebrow::after  { right: -45px; }

.yl-eyebrow--no-hero {
  position: relative;
  color: #888;
  text-shadow: none;
  margin-top: 40px;
}

/* Title when there is no featured-image hero */
.yl-title-no-hero {
  font-size: 2rem;
  font-weight: 700;
  margin: 0 0 24px;
  line-height: 1.2;
}

/* Details panel — GPS, elevation, area, seasons, time of day */
.yl-details-section {
  border-bottom: 1px solid #e5e5e5;
  padding: 20px 0;
  margin: 32px 0;
  overflow: hidden;
}

.yl-detail-row {
  display: flex;
  gap: 16px;
  padding: 6px 0;
  font-size: 0.95rem;
  line-height: 1.4;
}

.yl-detail-label {
  flex: 0 0 110px;
  font-weight: 600;
  color: #555;
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  padding-top: 2px;
}

.yl-detail-value {
  flex: 1;
  color: #222;
}

/* Detail map preview */
.yl-detail-map {
  float: right;
  width: 312px;
  height: 250px;
  margin-left: 24px;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  position: relative;
}
.yl-detail-map::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
  pointer-events: none;
}
.yl-detail-map:hover::after {
  box-shadow: inset 0 0 0 2px #555;
}
@media (max-width: 600px) {
  .yl-detail-map {
    float: none;
    width: 100%;
    height: 200px;
    margin-left: 0;
    margin-bottom: 16px;
  }
}

/* Location map modal */
.yl-map-modal {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.72);
  z-index: 9999;
  align-items: center;
  justify-content: center;
}
.yl-map-modal.is-open {
  display: flex;
}
body.yl-modal-open {
  overflow: hidden;
}
.yl-map-modal__inner {
  position: relative;
  width: min(860px, 92vw);
  height: min(600px, 80vh);
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 8px 40px rgba(0,0,0,0.5);
}
.yl-map-modal__map {
  width: 100%;
  height: 100%;
}
.yl-map-modal__close {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1000;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,0.9);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.yl-map-modal__close:hover {
  background: #fff;
}
.yl-map-modal__close svg {
  width: 12px;
  height: 12px;
  stroke: #222;
  display: block;
}

/* Access notes */
.yl-access-notes {
  margin-top: 12px;
}

.yl-access-title {
  font-size: 0.78rem !important;
  font-weight: 600 !important;
  margin: 0 0 8px !important;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #555 !important;
}

.yl-access-notes p {
  font-size: 0.95rem;
  line-height: 1.65;
  color: #444;
  margin: 0 0 12px;
}

/* All-locations collapsible index */
.yl-location-index {
  margin: 28px 0;
  border-top: 1px solid #e5e5e5;
  border-bottom: 1px solid #e5e5e5;
}
.yl-location-index__details {
  padding: 0;
}
.yl-location-index__summary {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  list-style: none;
  padding: 14px 0;
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: #555;
  user-select: none;
}
.yl-location-index__summary::-webkit-details-marker { display: none; }
.yl-location-index__summary::before {
  content: '';
  display: inline-block;
  width: 0;
  height: 0;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-left: 6px solid #aaa;
  margin-right: 8px;
  flex-shrink: 0;
  transition: transform 0.2s ease;
}
.yl-location-index__details[open] .yl-location-index__summary::before {
  transform: rotate(90deg);
}
.yl-location-index__count {
  color: #aaa;
  font-weight: 400;
  letter-spacing: 0;
}
.yl-location-index__body {
  padding-bottom: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.yl-location-index__group-heading {
  font-size: 0.72rem !important;
  font-weight: 600 !important;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #999 !important;
  margin: 8px 0 4px !important;
}

/* Location card */
.yl-loc-card {
  display: flex;
  align-items: stretch;
  text-decoration: none;
  color: inherit;
  border: 1px solid #e0e0e0;
  border-radius: 6px;
  overflow: hidden;
  transition: box-shadow 0.15s, border-color 0.15s;
}
.yl-loc-card:hover {
  box-shadow: 0 2px 14px rgba(0,0,0,0.1);
  border-color: #bbb;
  color: inherit;
  text-decoration: none;
}
.yl-loc-card__info {
  flex: 1;
  padding: 16px 20px;
}
.yl-loc-card__title {
  font-size: 1rem !important;
  font-weight: 600 !important;
  margin: 0 0 10px !important;
  color: #111;
  line-height: 1.3 !important;
}
.yl-loc-card__meta {
  margin: 0;
  padding: 0;
}
.yl-loc-card__row {
  display: flex;
  gap: 10px;
  margin-bottom: 5px;
}
.yl-loc-card__row dt {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #999;
  min-width: 82px;
  flex-shrink: 0;
  padding-top: 1px;
}
.yl-loc-card__row dd {
  font-size: 0.85rem;
  color: #444;
  margin: 0;
  line-height: 1.4;
}
.yl-loc-card__image {
  width: 200px;
  flex-shrink: 0;
  background-size: cover;
  background-position: center;
}
@media (max-width: 600px) {
  .yl-loc-card {
    flex-direction: column-reverse;
  }
  .yl-loc-card__image {
    width: 100%;
    height: 160px;
  }
}

/* Back to map link */
.yl-back-link {
  margin: 24px 0;
}
.yl-back-link--bottom {
  border-top: 1px solid #e5e5e5;
  padding-top: 20px;
  margin-bottom: 0;
}

.yl-back-link a {
  font-size: 0.875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: #555;
  text-decoration: none;
}

.yl-back-link a::before {
  content: '\2190\00a0';
}

.yl-back-link a:hover {
  color: #111;
}

