/* ============================================================
   Palmer About Sections Widget — palmer-about-sections.css

   Fully responsive layout. Designed to look correct from
   ~320px phones up through 4K. No Elementor styling controls
   feed into this file — layout, typography and spacing are
   all handled here.

   Typography uses clamp(min, fluid, max) so sizes scale
   linearly with viewport width across the full range.

   Hero section removed — use a dedicated hero widget instead.
   ============================================================ */

/* ── CSS variables for the one place to tune things ── */
.pas-wrap {
    /* Edge inset is 0: every horizontal gutter in this file resolves from
       this one variable, so text columns, the pull-quote and captions all
       now run flush to the left and right edges of the parent. Use the
       Elementor container's own padding to inset the whole widget. */
    --pas-gutter: 0px;
    --pas-text-color: #1a1a1a;
    --pas-muted-color: #444;
    --pas-link-color: #4a7c6f;
    --pas-accent-color: #9ec5bd;       /* teal accent — title rule, quote bar */
    --pas-caption-color: #555;
    --pas-section-gap: clamp(60px, 10vw, 140px);

    /* Fills its Elementor container: no cap, no side padding, so the
       container's width/padding controls do the sizing. */
    width: 100%;
    max-width: none;
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
    overflow-x: hidden;
    color: var(--pas-text-color);
    font-family: inherit;
    box-sizing: border-box;
}

.pas-wrap *,
.pas-wrap *::before,
.pas-wrap *::after {
    box-sizing: border-box;
}

/* ============================================================
   HERO PULL-QUOTE
   ============================================================
   A single large teal italic quote that sits above the about
   sections. The bold phrases inside come from <strong> tags in
   the editor — they switch to upright (non-italic) and a heavier
   weight to create the rhythm shown in the design.

   The italic style uses the inherited sans-serif (italicized via
   font-style) — NOT a serif. This matches the modern humanist
   italic look in the reference comp.

   IMPORTANT: every property here uses !important on visual
   resets (border, background, box-shadow, list-style) because
   themes routinely style <blockquote> with a left bar, dark
   background, or quote-mark pseudo-elements that would otherwise
   leak through. We do not want any of that.
   ============================================================ */

.pas-wrap .pas-pullquote {
    /* Layout — left-aligned with the section title below it.
       The block starts at the left gutter (same x as the section
       title), but is capped narrower than the full content width
       so the quote reads as a tighter, more deliberate measure.
       `margin-right: auto` pushes any remaining space to the right
       so the block stays pinned left, NOT centered. */
    display: block;
    position: relative;             /* anchor for the spotlight overlay */
    margin: clamp(80px, 10vw, 160px) auto clamp(60px, 8vw, 120px) 0;
    padding: 0 clamp(20px, 3vw, 48px) 0 var(--pas-gutter);
    width: 100%;
    /* Cap the quote width. The actual value is set inline on the
       blockquote via --pas-pq-max-width from the Elementor slider;
       the value here is the fallback for any saved widget content
       that pre-dates the slider control. Includes the left gutter,
       so the inner text width is roughly max-width minus the gutter. */
    max-width: var(--pas-pq-max-width, 900px);

    /* Cursor-tracked spotlight position — updated live from JS via
       --mx / --my as the cursor moves. Defaults park it off-screen
       so nothing shows before first interaction. */
    --mx: -50%;
    --my: -50%;

    /* Hard-reset everything a theme might put on <blockquote> */
    background: none !important;
    background-color: transparent !important;
    border: 0 !important;
    border-left: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    quotes: none;
    list-style: none;

    /* Typography */
    color: var(--pas-accent-color);
    font-family: inherit;       /* sans-serif from the theme */
    font-style: italic;
    font-weight: 400;
    text-align: left;
    letter-spacing: 0;
}

/* Kill any ::before / ::after quote glyphs that themes add. */
.pas-wrap .pas-pullquote::before,
.pas-wrap .pas-pullquote::after {
    content: none !important;
    display: none !important;
    background: none !important;
    border: 0 !important;
}

.pas-wrap .pas-pullquote__text {
    margin: 0;
    padding: 0;
    /* Position relative so the spotlight ::before can anchor here.
       (We attach it to __text rather than .pas-pullquote because the
       theme-nuke rule earlier wipes any ::before/::after on the
       blockquote itself.) */
    position: relative;
    color: var(--pas-accent-color);
    font-family: inherit;
    font-style: italic;
    font-weight: 400;
    font-size: clamp(18px, 1.9vw, 28px);
    line-height: 1.5;
    overflow-wrap: break-word;
    word-wrap: break-word;
}

/* ────────────────────────────────────────────────────────────
 *  CURSOR-TRACKED SPOTLIGHT
 *  A soft warm glow that follows the cursor while it's over the
 *  quote on desktop. Position is driven by --mx / --my (set by
 *  JS on the parent .pas-pullquote). Opacity ramps up via
 *  .is-hovering and back down on mouseleave for a graceful fade.
 *  pointer-events: none so the overlay can't swallow clicks.
 * ──────────────────────────────────────────────────────────── */
.pas-wrap .pas-pullquote__text::before {
    content: '';
    position: absolute;
    /* Spill beyond the text box so the gradient stays smooth at
       the edges and the glow looks "alive" rather than clipped. */
    inset: -20% -10%;
    background: radial-gradient(
        circle at var(--mx, 50%) var(--my, 50%),
        rgba(158, 197, 189, 0.18) 0%,
        rgba(158, 197, 189, 0.10) 20%,
        rgba(158, 197, 189, 0)    50%
    );
    opacity: 0;
    transition: opacity 0.6s ease;
    pointer-events: none;
    z-index: 0;
}

.pas-wrap .pas-pullquote.is-hovering .pas-pullquote__text::before {
    opacity: 1;
}

/* Make sure word spans render above the spotlight overlay. */
.pas-wrap .pas-pullquote__word {
    position: relative;
    z-index: 1;
}

/* ────────────────────────────────────────────────────────────
 *  WORD-BY-WORD REVEAL
 *  JS splits the quote text into .pas-pullquote__word spans on
 *  init, each with a `--i` index. Initial state is hidden +
 *  slightly translated; .is-revealing on the parent triggers the
 *  transition with a per-word delay computed from --i.
 *
 *  Bold phrases (.pas-pullquote__word--strong) get a second,
 *  later-arriving treatment: a teal underline that draws itself
 *  in from left to right via a scaleX(0) → scaleX(1) on a pseudo.
 * ──────────────────────────────────────────────────────────── */
.pas-wrap .pas-pullquote__word {
    display: inline-block;
    opacity: 0;
    transform: translateY(0.4em);
    transition:
        opacity     0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
        transform   0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
    /* Stagger: each word reveals 60ms after the previous one.
       calc() reads the --i custom prop set inline on each span. */
    transition-delay: calc(var(--i, 0) * 60ms);
    /* Keep the underline pseudo from extending past the word's
       natural width on the rare wrap-around case. */
    will-change: opacity, transform;
}

.pas-wrap .pas-pullquote.is-revealing .pas-pullquote__word {
    opacity: 1;
    transform: translateY(0);
}

/* Underline-draw on bold phrases. The pseudo sits on the lower
   edge of each strong word and scales in from the left. We delay
   it slightly past the word's own fade so the line "draws" after
   the word arrives — that two-step is what makes the moment land. */
.pas-wrap .pas-pullquote__word--strong {
    position: relative;
}

.pas-wrap .pas-pullquote__word--strong::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -0.06em;
    height: 2px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.55s cubic-bezier(0.65, 0, 0.35, 1);
    /* Underline lags ~280ms behind the word's own fade-up so the
       reveal feels like two coordinated beats rather than a blur. */
    transition-delay: calc(var(--i, 0) * 60ms + 280ms);
    opacity: 0.65;
}

.pas-wrap .pas-pullquote.is-revealing .pas-pullquote__word--strong::after {
    transform: scaleX(1);
}

/* Quote-mark words: same fade-up as regular words, no underline. */
.pas-wrap .pas-pullquote__word--mark {
    /* Inherits the standard __word transition. Nothing extra. */
}

/* Reduced motion: instant, no transitions, no spotlight. */
@media (prefers-reduced-motion: reduce) {
    .pas-wrap .pas-pullquote__word {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .pas-wrap .pas-pullquote__word--strong::after {
        transform: scaleX(1);
        transition: none;
    }
    .pas-wrap .pas-pullquote__text::before {
        display: none;
    }
}

/* Bold phrases inside the quote — slightly heavier, still italic.
   Two selectors so the styling applies both:
   (a) before JS runs / if JS fails — via the real <strong>/<b> tags;
   (b) after JS splits the text — via the .pas-pullquote__word--strong
       spans that the JS emits in place of the <strong> wrapper. */
.pas-wrap .pas-pullquote__text strong,
.pas-wrap .pas-pullquote__text b,
.pas-wrap .pas-pullquote__word--strong {
    font-style: italic;
    font-weight: 700;
    color: var(--pas-accent-color);
}

/* Inline smart-quote marks. Pin them to the quote's own font-size
   (independent of any wrapper the reveal JS nests them in, which was
   leaving them tiny) and sit them on the text baseline so they no
   longer float out of line. Small side margins keep them from
   crowding the first and last words. */
.pas-wrap .pas-pullquote__mark {
    display: inline;
    font-style: italic;
    font-weight: 400;
    color: var(--pas-accent-color);
    font-size: clamp(18px, 1.9vw, 28px);
    line-height: 1;
    vertical-align: baseline;
}

.pas-wrap .pas-pullquote__mark--open {
    margin-right: 0.05em;
}

.pas-wrap .pas-pullquote__mark--close {
    margin-left: 0.04em;
}

/* Attribution line — right-aligned, dark text, italic name +
   lighter role. Built on a <div> instead of <footer> to avoid
   any theme styling targeting the <footer> element. Visual
   resets here too so a theme's <footer> background can't leak. */
.pas-wrap .pas-pullquote__attribution {
    display: block;
    margin: clamp(28px, 3vw, 48px) 0 0 0;
    padding: 0 !important;
    background: none !important;
    background-color: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    text-align: right;
    font-family: inherit;
    font-style: normal;
    font-size: clamp(15px, 1.2vw, 20px);
    line-height: 1.4;
    color: var(--pas-text-color);
}

.pas-wrap .pas-pullquote__author {
    font-family: inherit;
    font-style: italic;
    font-weight: 500;
    color: var(--pas-text-color);
}

.pas-wrap .pas-pullquote__sep {
    font-style: normal;
    color: var(--pas-text-color);
}

.pas-wrap .pas-pullquote__role {
    font-family: inherit;
    font-style: normal;
    font-weight: 400;
    color: var(--pas-muted-color);
}

/* ============================================================
   CONTENT SECTIONS
   ============================================================
   Desktop: two columns spanning the full viewport. The IMAGE
   column has no padding so its image touches the viewport edge.
   The TEXT column carries the gutter padding on the outer side.
   Mobile: stacks text → image; image stays full-bleed.
   ============================================================ */

.pas-section {
    display: grid;
    align-items: center;
    gap: clamp(24px, 3vw, 48px);
    width: 100%;
    margin: 0 0 var(--pas-section-gap);
    /* Default text-column percentage. Each section can override
       via an inline `--pas-text-pct: NN%` style emitted by PHP
       from the Elementor slider control. The image column auto-
       fills the rest using `calc(100% - --pas-text-pct)`. */
    --pas-text-pct: 40%;
}

.pas-section:last-child {
    margin-bottom: clamp(60px, 8vw, 120px);
}

.pas-text-col,
.pas-img-col {
    min-width: 0;
}

/* ── Image-right variant (default): text on left, image on right.
   Text column has the gutter on its left; image touches the
   right viewport edge with no padding on the right.
   The 1px floor and 1fr in calc() guards against negative widths
   if --pas-text-pct ever overshoots 100%. ── */
.pas-section--img-right {
    grid-template-columns: var(--pas-text-pct) minmax(0, 1fr);
}

.pas-section--img-right .pas-text-col {
    padding-left: var(--pas-gutter);
    padding-right: clamp(20px, 3vw, 48px);
}

.pas-section--img-right .pas-img-col {
    padding: 0;
}

/* ── Image-left variant: image on left, text on right.
   Mirrored grid template so the IMAGE lands in the wider track
   on the left and the TEXT in the narrower track on the right.
   `order` swaps the visual position of the DOM children to
   match the design while keeping the source order
   text → image (semantic / mobile-friendly). ── */
.pas-section--img-left {
    grid-template-columns: minmax(0, 1fr) var(--pas-text-pct);
}

.pas-section--img-left .pas-text-col {
    order: 2;
    padding-right: var(--pas-gutter);
    padding-left: clamp(20px, 3vw, 48px);
}

.pas-section--img-left .pas-img-col {
    order: 1;
    padding: 0;
}

/* ── No-image variant: text spans full width with gutter on left. ── */
.pas-section--img-none {
    grid-template-columns: 1fr;
}

.pas-section--img-none .pas-text-col {
    padding-left: var(--pas-gutter);
    padding-right: var(--pas-gutter);
    /* Constrain to a readable measure so the text doesn't stretch
       absurdly wide on big screens. */
    max-width: 760px;
}

.pas-title {
    display: flex;
    align-items: center;
    gap: clamp(12px, 1.2vw, 18px);
    margin: 0 0 clamp(20px, 2.4vw, 32px) 0;
    font-size: clamp(28px, 3vw, 44px);
    line-height: 1.15;
    font-weight: 500;
    color: var(--pas-text-color);
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.pas-title-text {
    /* Allow the title to shrink below its content width on small
       viewports so long titles wrap to multiple lines instead of
       overflowing the container. min-width: 0 unlocks shrinking
       inside the flex parent (which would otherwise honor the
       intrinsic text width as a minimum). */
    flex: 0 1 auto;
    min-width: 0;
}

/* Italicized portions of the title get a serif look so emphasized
   words read with the elegance shown in the design comp. */
.pas-title em,
.pas-title i {
    font-style: italic;
    font-family: Georgia, "Times New Roman", serif;
    font-weight: 500;
}

/* Horizontal accent rule that sits next to the title text and
   stretches to fill the remaining space out to the container edge.
   When the title wraps to multiple lines, align-self: flex-end drops
   the rule down so it sits beside the LAST line of the title rather
   than floating up next to the first line. */
.pas-title-rule {
    flex: 1 1 0;
    height: 4px;
    background-color: var(--pas-accent-color);
    min-width: 0;
    /* Align to the bottom line of the title, nudged up slightly so it
       lands around the baseline of the last line rather than under
       its descenders. */
    align-self: flex-end;
    /* Center the bar on the last line of the title. 0.3em sat too low
       (near the baseline) and 0.62em too high (near the cap tops), so the
       caps' true optical center lands at ~0.48em up from the line-box
       bottom; subtracting half the bar's height (2px) centers the bar
       itself. flex-end keeps it beside the LAST line when a title wraps. */
    margin-bottom: calc(0.48em - 2px);
}

.pas-content {
    font-size: clamp(14px, 0.95vw, 15px);
    line-height: 1.7;
    color: var(--pas-muted-color);
}

/* ── Two-column body layout (desktop only).
   When the paragraphs field has more than one <p>, PHP emits
   `pas-content--split` and renders the first paragraph in one
   sub-column and the remaining paragraphs in another. The gap
   sits between them. On mobile they restack via the @media
   block further down. ── */
.pas-content--split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(20px, 2.4vw, 36px);
    align-items: start;
}

.pas-content-col {
    min-width: 0;
}

.pas-content p {
    margin: 0 0 14px 0;
}

.pas-content p:last-child {
    margin-bottom: 0;
}

/* Drop cap on the first letter of the first paragraph.
   Scoped to .pas-content-col--first so the right column never
   gets a drop cap on its own first paragraph. */
.pas-content-col--first > p:first-child::first-letter {
    float: left;
    font-family: Georgia, "Times New Roman", serif;
    font-size: 3.4em;
    line-height: 0.9;
    font-weight: 500;
    color: var(--pas-text-color);
    padding: 0.05em 0.12em 0 0;
    margin: 0.04em 0 0 0;
}

/* ── Pull-quote: teal vertical bar on the left, italic text.
   Sits below the body paragraphs (and spans the full width of
   the text column even when the body is split). ── */
.pas-quote {
    margin: clamp(24px, 3vw, 40px) 0 0 0;
    padding: 0 0 0 clamp(14px, 1.2vw, 20px);
    border-left: 3px solid var(--pas-accent-color);
    font-style: italic;
    font-family: Georgia, "Times New Roman", serif;
    font-size: clamp(17px, 1.3vw, 22px);
    line-height: 1.45;
    color: var(--pas-text-color);
}

.pas-quote p {
    margin: 0;
}

/* ── Main image wrap: width is driven by --pas-img-size (set
   inline per section by PHP from the Elementor slider). When
   < 100%, the image shrinks inside its column and is pinned to
   the OUTER edge of the section — the viewport-bleed edge —
   so it stays anchored to the page edge instead of drifting
   toward the text. The image column TRACK width is unchanged,
   so adjusting this slider does not move the text column. ── */
.pas-img-col {
    line-height: 0;
    display: flex;
}

.pas-section--img-right .pas-img-col {
    /* image-right → outer edge is the right edge → pin image right */
    justify-content: flex-end;
}

.pas-section--img-left .pas-img-col {
    /* image-left → outer edge is the left edge → pin image left */
    justify-content: flex-start;
}

.pas-main-img-wrap {
    width: var(--pas-img-size, 100%);
    overflow: hidden;
}

.pas-main-img {
    width: 100%;
    height: auto;
    display: block;
    transition: opacity 0.4s ease;
}

/* ── Caption beneath the main image. Inherits the wrap's width
   (so it shrinks with --pas-img-size) and aligns with the image
   on the outer/viewport-edge side. ── */
.pas-main-img-caption {
    margin-top: clamp(10px, 1vw, 16px);
    font-size: clamp(12px, 0.85vw, 14px);
    line-height: 1.5;
    color: var(--pas-caption-color);
    font-style: italic;
}

/* Image-right: caption aligns to the LEFT side of the image
   (the inner edge near the text) — matches the reference comp. */
.pas-section--img-right .pas-main-img-caption {
    text-align: left;
    padding-left: clamp(20px, 3vw, 40px);
}

/* Image-left: mirror — caption aligns to the right side. */
.pas-section--img-left .pas-main-img-caption {
    text-align: right;
    padding-right: clamp(20px, 3vw, 40px);
}

/* ============================================================
   ACCENT GALLERY  (desktop / tablet only)
   ============================================================
   Two square thumbnails side by side, spanning the full width
   of the text column above them. Only the first 2 images are
   used; any additional gallery images are ignored on render.
   ============================================================ */
.pas-masonry {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(8px, 0.8vw, 14px);
    margin-top: clamp(20px, 3vw, 36px);
    width: 100%;
}

.pas-masonry-item {
    aspect-ratio: 1 / 1;
    border-radius: 2px;
}

/* Hide any items past the first 2 — the layout only shows two. */
.pas-masonry-item:nth-child(n + 3) {
    display: none;
}

.pas-masonry-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    border-radius: 2px;
}

/* Black & White accent gallery — simple on/off filter, toggled per
   section in the Elementor editor via the "Black & White Gallery"
   switch. Applies only to the accent gallery thumbs, never the main
   feature image. */
.pas-masonry--bw .pas-masonry-item img {
    filter: grayscale(100%);
}

/* No-op aliases so old saved widget content that emits these
   aspect-ratio classes doesn't break the new layout. */
.pas-masonry-item.ar-1x1,
.pas-masonry-item.ar-3x4,
.pas-masonry-item.ar-4x5,
.pas-masonry-item.ar-2x3,
.pas-masonry-item.ar-4x3,
.pas-masonry-item.ar-3x2,
.pas-masonry-item.ar-16x9,
.pas-masonry-item.ar-2x1 {
    aspect-ratio: 1 / 1;
}

/* ============================================================
   TABLET / NARROW DESKTOP  — stack everything below 900px
   ============================================================ */
@media (max-width: 900px) {

    /* Sections stack: text first, image second.
       Both columns get the gutter on both sides on mobile. */
    .pas-section {
        grid-template-columns: 1fr;
        gap: clamp(24px, 5vw, 40px);
        margin-bottom: clamp(48px, 9vw, 100px);
    }

    /* Hide the horizontal accent rule next to the title on mobile.
       With a wrapped multi-line title, the rule would sit alongside
       one of the wrapped lines and look awkward — better to give
       the title the entire width and drop the accent altogether
       at this breakpoint. */
    .pas-title-rule {
        display: none;
    }

    .pas-title {
        /* Wrapped titles on mobile read better with a tighter line
           height than the default 1.15. */
        line-height: 1.2;
    }

    .pas-section--img-right .pas-text-col,
    .pas-section--img-left .pas-text-col,
    .pas-section--img-none .pas-text-col {
        padding-left: var(--pas-gutter);
        padding-right: var(--pas-gutter);
        max-width: 100%;
        justify-self: stretch;
        order: 1;
    }

    /* Image stays edge-to-edge on mobile (full-width). Overrides:
       - .pas-img-col justify-content from the desktop img-right /
         img-left variants (which would otherwise pin the image to
         one edge and leave a gap on the other).
       - .pas-main-img-wrap width, which on desktop uses the
         --pas-img-size slider (e.g. 80%) — on mobile we always
         want full bleed, so we force 100% here. */
    .pas-section--img-right .pas-img-col,
    .pas-section--img-left .pas-img-col {
        padding-left: 0;
        padding-right: 0;
        justify-content: stretch;
        order: 2;
    }

    .pas-section--img-right .pas-main-img-wrap,
    .pas-section--img-left .pas-main-img-wrap {
        width: 100%;
    }

    /* Two-column body collapses to a single column on mobile so
       paragraphs read top-to-bottom in their natural order. The
       row gap restores breathing room between the stacked blocks:
       column one's only paragraph is its :last-child (margin-bottom
       0), so without this the drop-cap block sits flush against the
       block below it. 14px matches the inter-paragraph rhythm. */
    .pas-content--split {
        grid-template-columns: 1fr;
        gap: 14px;
    }

    /* Mobile caption: center under the full-bleed image with
       gutter padding on both sides, regardless of image side. */
    .pas-section--img-right .pas-main-img-caption,
    .pas-section--img-left .pas-main-img-caption {
        text-align: left;
        padding-left: var(--pas-gutter);
        padding-right: var(--pas-gutter);
    }

    /* Hide accent gallery on small screens — JS swaps one of these
       into the main image slot at random on page load. */
    .pas-masonry {
        display: none;
    }

    /* Pull-quote on tablet: tighten the generous desktop margins
       and ignore the desktop max-width slider so the quote uses
       the full content width on smaller viewports — a tight
       measure that looks deliberate on desktop reads cramped on
       a phone. */
    .pas-wrap .pas-pullquote {
        margin-top: clamp(48px, 10vw, 100px);
        margin-bottom: clamp(40px, 8vw, 80px);
        max-width: none;
    }
}

/* ============================================================
   MOBILE — under 500px
   ============================================================ */
@media (max-width: 500px) {

    .pas-title {
        font-size: clamp(24px, 7vw, 34px);
        gap: 14px;
    }

    .pas-content-col--first > p:first-child::first-letter {
        font-size: 3em;
    }

    /* Small phones: tighten the quote font and line-height. */
    .pas-wrap .pas-pullquote__text {
        font-size: clamp(17px, 4.6vw, 22px);
        line-height: 1.5;
    }

    .pas-wrap .pas-pullquote__attribution {
        font-size: clamp(14px, 3.8vw, 17px);
    }
}
/* ============================================================
   SCROLL REVEAL ANIMATIONS  (mobile + desktop)
   ============================================================
   Progressive enhancement. The hidden starting state lives under
   .pas-wrap.pas-anim. PHP prints .pas-anim on the wrap so the
   hidden state is present at first paint (no flash-then-hide).
   The JS then either drives the reveals via IntersectionObserver,
   or — under reduced motion / no IO support / a script error —
   strips .pas-anim so everything shows immediately.

   Two further safety nets below cover JS being disabled entirely
   (@media scripting:none) and reduced-motion preferences.

   Each target carries .pas-reveal plus a per-section
   --pas-reveal-i stagger index, so elements that scroll into view
   together arrive in a quick, readable sequence rather than all
   at once. JS adds .is-inview as each element crosses the
   viewport; reveals are one-shot (they do not re-hide on
   scroll-up). Easing matches the pull-quote word reveal above
   (cubic-bezier(0.22, 0.61, 0.36, 1)) so the whole widget shares
   a single motion language.
   ============================================================ */

.pas-wrap.pas-anim .pas-reveal {
    opacity: 0;
    transform: translateY(26px);
    transition:
        opacity   0.85s cubic-bezier(0.22, 0.61, 0.36, 1),
        transform 0.85s cubic-bezier(0.22, 0.61, 0.36, 1);
    transition-delay: calc(var(--pas-reveal-i, 0) * 85ms);
    will-change: opacity, transform;
}

.pas-wrap.pas-anim .pas-reveal.is-inview {
    opacity: 1;
    transform: none;
}

/* Title accent rule — draws itself in from the left instead of
   fading/sliding. Overrides the base translate + fade above. */
.pas-wrap.pas-anim .pas-title-rule.pas-reveal--rule {
    opacity: 1;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
    transition-delay: calc(var(--pas-reveal-i, 0) * 85ms + 120ms);
}

.pas-wrap.pas-anim .pas-title-rule.pas-reveal--rule.is-inview {
    transform: scaleX(1);
}

/* Main feature image — the wrap fades/slides via the base rule
   while the image inside unveils from a gentle scale-up. The
   .pas-main-img-wrap already has overflow:hidden, so the scale
   stays cleanly clipped. The original opacity transition on
   .pas-main-img (used by the mobile random-swap) is preserved. */
.pas-wrap.pas-anim .pas-reveal--img .pas-main-img {
    transform: scale(1.08);
    transition:
        transform 1.15s cubic-bezier(0.22, 0.61, 0.36, 1),
        opacity   0.4s ease;
    transition-delay: calc(var(--pas-reveal-i, 0) * 85ms);
}

.pas-wrap.pas-anim .pas-reveal--img.is-inview .pas-main-img {
    transform: scale(1);
}

/* Safety net 1 — JS disabled entirely: reveal everything. The
   wrap ships with .pas-anim, so without this rule a no-JS visitor
   would never see the content. */
@media (scripting: none) {
    .pas-wrap.pas-anim .pas-reveal,
    .pas-wrap.pas-anim .pas-reveal--rule,
    .pas-wrap.pas-anim .pas-reveal--img .pas-main-img {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
}

/* Safety net 2 — reduced motion: neutralize every reveal. JS also
   strips .pas-anim in this case, but this covers reduced-motion +
   JS-disabled where the class can't be removed. */
@media (prefers-reduced-motion: reduce) {
    .pas-wrap.pas-anim .pas-reveal,
    .pas-wrap.pas-anim .pas-reveal--rule,
    .pas-wrap.pas-anim .pas-reveal--img .pas-main-img {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
}

/* ── Accent gallery thumbs — a gentler, slightly longer reveal than
   the default. The JS holds this until the thumbnail image has
   decoded (revealWhenReady), so the fade plays over the finished
   picture instead of an empty box; the softer ease-out and small
   scale-settle take the remaining snap off it. Duration/easing/
   transform are overridden via longhand (not the transition
   shorthand) so the per-thumb transition-delay stagger from the
   base .pas-reveal rule stays intact. ── */
.pas-wrap.pas-anim .pas-masonry-item.pas-reveal {
    transform: translateY(16px) scale(0.99);
    transition-property: opacity, transform;
    transition-duration: 1.1s;
    transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

.pas-wrap.pas-anim .pas-masonry-item.pas-reveal.is-inview {
    transform: none;
}

/* ============================================================
   ELEMENTOR WRAPPER RESETS
   ============================================================
   Zero out any horizontal padding/margin or width cap Elementor or the
   theme puts on the widget's own wrappers, so the content really does
   reach both edges of the parent container. Vertical spacing is left
   alone so widget margin/padding still works.
   ============================================================ */
.elementor-widget-palmer_about_sections,
.elementor-widget-palmer_about_sections > .elementor-widget-container,
.elementor-widget-palmer_about_sections > .elementor-widget-container > .pas-wrap {
    width: 100% !important;
    max-width: none !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}