/*
 * Margaritte per-site exceptions — rules no Bricks layer can express.
 * Loaded by aell-site-settings.php after Bricks's inline CSS, so it wins the cascade.
 *
 * Anything *not* here lives where it belongs in Bricks:
 *   - Element settings   (per-instance)
 *   - Global Class       (custom-class scope)
 *   - Theme Style        (per-site element defaults: body, h1-h6, section, container)
 *   - Style Manager      (variables + colour palette)
 *
 * See WebDev Stack (Bricks) → "Where exceptions go" for the full decision tree.
 */

/* Global reset — html/body aren't Bricks elements */
body, html { margin: 0; padding: 0; }
/* Bricks ships `text-size-adjust: auto`, which lets Chrome/Android font-boost
   text in wide blocks (homepage captions) while constrained blocks (About
   column) stay put — same CSS size, different rendered size. Pin it. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* Home grid span-2 variant + wide-breakpoint overrides.
   `.card--double` is a Bricks Global Class — the rule should ideally live in its
   class settings (Bricks builder) so it's editable from the UI. Until that's
   moved, the rule lives here. */
.home-grid .card--double { grid-column: span 2; }

/* Tablet + mobile column counts — Bricks's element-setting responsive
   variants (_gridTemplateColumns:tablet/:mobile) don't render when set
   programmatically, so we emit the fallback. ID selector matches the
   element CSS specificity (1-0-0); style.css loads after Bricks inline
   so it wins on equal specificity.

   Card heights vary by card class on both breakpoints — regular cards
   (1-col span) get +20% over their grid-baseline, card--double cards
   (2-col span) get +10%. Override the per-instance `height: 100%` via
   the `#brxe-atyozd > .card` selector (1-1-1 specificity beats 1-0-0). */
@media (max-width: 991px) {
    #brxe-atyozd { grid-template-columns: repeat(2, 1fr); grid-auto-rows: auto; }
    #brxe-atyozd > .card                { height: 67vw; } /* baseline 56vw + 20% */
    #brxe-atyozd > .card.card--double   { height: 62vw; } /* baseline 56vw + 10% */
}
@media (max-width: 478px) {
    #brxe-atyozd { grid-template-columns: 1fr; grid-auto-rows: auto; }
    .home-grid .card--double            { grid-column: auto; } /* no 2-col axis to span on 1-col */
    #brxe-atyozd > .card                { height: 108vw; }     /* baseline 90vw + 20% */
    #brxe-atyozd > .card.card--double   { height: 99vw; }      /* baseline 90vw + 10% */
}

@media (min-width: 1600px) {
    .home-grid { grid-template-columns: repeat(5, 1fr); grid-auto-rows: 26vw; }
}
@media (min-width: 2000px) {
    .home-grid { grid-template-columns: repeat(6, 1fr); grid-auto-rows: 22vw; }
}
@media (min-width: 2400px) {
    .home-grid { max-width: 2400px; margin-left: auto; margin-right: auto; grid-auto-rows: 480px; }
}

/* Card hover — linked cards only */
.card.card--linked .card__media { cursor: pointer; }
.card.card--linked .card__image,
.card.card--linked .card__video {
    transition: transform .35s ease, filter .35s ease;
}
.card.card--linked:hover .card__image,
.card.card--linked:hover .card__video {
    transform: scale(1.03);
    filter: brightness(0.95);
}
/* Bricks Video element wraps the <video> tag — fill + crop the inner tag */
.card .card__video video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Hide Bricks's "No file URL provided." placeholder in the builder canvas
   for cards without a video. The Video element's render() returns the
   placeholder div in place of its normal wrapper, so it ends up as a sibling
   of .card__image inside .card__media (not inside .card__video). Bricks
   short-circuits placeholder output on the public frontend (is_frontend=true),
   so this rule only affects the builder canvas. */
.card__media > .bricks-element-placeholder { display: none; }

/* Header — tablet edge padding (instance ID; programmatic _padding:tablet
   never rendered, so set here). Mobile (16px) is in the max-width:767 block. */
@media (max-width: 991px) {
    #brxe-6vk98w { padding: 20px 16px; }
}

/* ── Component layout: NATIVE-FIRST ─────────────────────────────────────
   Base layout (flex containers, column widths 26/48/26 & 50%, paddings, gaps,
   caption rows, name weight) lives in the COMPONENT ELEMENT SETTINGS (Bricks
   native) — those render in both the builder canvas and the frontend.
   style.css carries ONLY variant overrides + genuine exceptions below.

   Specificity note: Bricks element settings emit `.brxe-{id}` rules (0-1-0).
   On the frontend style.css loads after them, but in the BUILDER the element CSS
   can be injected later, so any override here that competes with an element-base
   property uses ≥0-2-0 selectors (e.g. `.psec.psec--max`) to win in BOTH. */

/* Media fills its column, ratio kept */
.psec__media img,
.psec__media video { width: 100%; height: auto; display: block; }

/* Bricks Video element wraps <video> in .brxe-video and puts the chosen
   aspectRatio on that wrapper — so the wrapper needs an explicit width for its
   height to resolve (otherwise it collapses to 0). The <video> fills it; the
   aspectRatio matches the file's real ratio, so cover doesn't crop. */
.psec__media .brxe-video { width: 100%; }
.psec__media .brxe-video video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Variant — Portrait column widths */
.psec--portrait .psec__media { width: 35%; }
.psec--portrait .psec__title,
.psec--portrait .psec__tags  { width: 32.5%; }

/* DESKTOP-FIRST: the Bricks builder canvas does NOT satisfy `min-width` media
   queries (it renders at a logical width media queries don't see as ≥768), so
   the desktop layout must be the UNCONDITIONAL base and mobile goes in the
   max-width:767 block at the end. (Verified via headless login: a min-width:768
   grid rule stayed `display:flex` in the canvas while content was 992px wide.)

   First section hero: full viewport, vertically centred (psecsg flex
   align-items:center). Mobile resets to natural height. */
.psec--hero { min-height: 100vh; }

/* Carousels — constant frame: every slide renders in the same aspect-ratio box
   (3:2 landscape sections, 2:3 portrait sections); object-fit: cover crops
   off-ratio images to fill the frame, so neither height nor visible width
   ever changes between slides. */
.psec__media .swiper-slide img {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
}
.psec--portrait .psec__media .swiper-slide img { aspect-ratio: 2 / 3; }

/* "Fit" carousel — mixed-orientation, no cropping (KUEI = hsec19, per-instance
   exception). Height is the limiting factor (fixed = --media-max-h); each image
   shows fully (contain), so width varies per slide. script.js sets the media
   width to the active image so the side labels reflow to fill the rest.
   Mobile: media is full width, height follows the image, labels below. */
.psec--fitcar .psec__media { width: auto; flex: 0 0 auto; max-width: 100%; }
.psec--fitcar .psec__title,
.psec--fitcar .psec__tags { flex: 1 1 0; min-width: 0; width: auto; }
.psec--fitcar .bricks-swiper-container { height: var(--media-max-h); }
.psec--fitcar .psec__media .swiper-slide { display: flex; align-items: center; justify-content: center; }
.psec--fitcar .psec__media .swiper-slide img {
    height: 100%;
    width: auto;
    max-width: 100%;
    aspect-ratio: auto;
    object-fit: contain;
}
/* Fitcar tablet/mobile behaviour (captions under, full-width, natural height)
   lives in the ≤991 tablet tier below — see "FITCAR". */

/* Carousel navigation — desktop: click left/right half for prev/next, with
   directional arrow cursors. Overlays are inserted by script.js; hidden on
   touch devices where Swiper's native swipe takes over (events bubble through
   the overlays to the Swiper container regardless). */
.psec .bricks-swiper-container { position: relative; }
.psec-car-nav { position: absolute; top: 0; height: 100%; width: 50%; z-index: 5; }
.psec-car-prev {
    left: 0;
    cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="M20 6 L10 16 L20 26" fill="none" stroke="black" stroke-width="2.5"/></svg>') 16 16, w-resize;
}
.psec-car-next {
    right: 0;
    cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><path d="M12 6 L22 16 L12 26" fill="none" stroke="black" stroke-width="2.5"/></svg>') 16 16, e-resize;
}
@media (hover: none) {
    .psec-car-nav { display: none; }
}

/* Viewport fit (desktop base) — no media taller than the screen. Media columns
   get a ratio-derived max-width; plain image/video get a max-height. Mobile
   (max-width:767 block) resets widths to 100% and lifts the height cap. */
.psec {
    --media-max-h: calc(100vh - 200px);
    --media-max-h-sm: calc((100vh - 200px) * 0.75); /* Small double columns */
}
.psec--single .psec__media { max-width: calc(var(--media-max-h) * 1.5); }   /* 3:2 frame */
.psec--portrait .psec__media { max-width: calc(var(--media-max-h) * 0.667); } /* 2:3 frame */
.psec__media > img.brxe-image {
    width: 100%;
    max-height: var(--media-max-h);
    object-fit: cover;
}
/* Video fills its column at natural ratio (no height cap / crop) so vertical
   clips show full vertical height — put vertical videos in a Portrait/Max
   single so the column width keeps them a sensible size. */
.psec__media video {
    width: 100%;
    height: auto;
    display: block;
}

/* Max layout (desktop): the big image keeps its size (media-max-h × 1.5 == the
   old grid's 2×0.75 columns, capped 90%) and the captions move into the side
   strips that already flank it — `flex:1 1 0` fills each side, exactly like the
   fit-carousel. Base psecsg flex row (justify/align center) centres the image.
   Drops under at ≤1400 with the rest of the singles. */
.psec.psec--max { display: flex; }
.psec--max .psec__media {
    flex: 0 0 auto;
    width: calc(var(--media-max-h) * 1.5);
    max-width: 90%;
}
/* No `padding:0` here — keep the element's 30px inner padding (pstitl right /
   pstags left) so the side captions sit the same distance off the image as
   every other single layout, instead of touching it. */
.psec--max .psec__title,
.psec--max .psec__tags { flex: 1 1 0; min-width: 0; width: auto; }

/* Double — per-column sizing (component "Item N — Sizing" class property).
   Each item is a 50% flex column; the image AND its caption share one width
   cap (--item-cap) and are centered, so the caption edges always meet the
   image edges regardless of the image's aspect ratio. Sizing variants just
   change the cap. Item width stays 50% (the cap, not the column, sets the
   visible size). align-items:center also lives in the component element
   settings so the builder canvas matches. */
.psec--double .psec__item {
    align-items: center;
    --item-cap: 30vw;            /* Standard */
}
.psec--double .psec__item.psec__item--small { --item-cap: 24vw; }
.psec--double .psec__item.psec__item--full  { --item-cap: 50vw; }
.psec--double .psec__item > img.brxe-image,
.psec--double .psec__item .swiper-slide img { width: 100%; height: auto; }
.psec--double .psec__item > img.brxe-image,
.psec--double .psec__item .brxe-carousel,
.psec--double .psec__caption { width: 100%; max-width: var(--item-cap); }

/* Tags wrap right-ragged wherever they sit on the right edge */
.psec__caption > .brxe-text-basic:last-child { text-align: right; }
.psec--max .psec__tags { text-align: right; }

/* Per-side caption hide on desktop (component Left/Right "(desktop)" props →
   class pshd-d). Base hides; mobile block restores. */
.pshd-d { display: none !important; }

/* Merged double captions (psecdb "Merge matching captions" → .psec--merged):
   left column shows only the name, right column only the tags (pushed right),
   so the caption reads as one line across the pair. Mobile block un-merges. */
.psec--double.psec--merged .psec__item:nth-child(1) .psec__caption > .brxe-text-basic { display: none; }
.psec--double.psec--merged .psec__item:nth-child(2) .psec__caption > .psec__ctitle { display: none; }
.psec--double.psec--merged .psec__item:nth-child(2) .psec__caption { justify-content: flex-end; }

/* Tall double (psecdb "Layout (desktop)" → .psec--tall) — reads as ONE
   AMBER-sized image: the pair fills the same 3:2 frame a Max single does
   (combined width = --media-max-h × 1.5 ≤ 90vw), split into two 3:4 halves that
   cover-crop and touch at the centre. The merged caption is split into the side
   strips like a Max single: each item becomes a flex ROW so its caption sits
   beside the image (name → left strip, tags → right strip), the inner edges of
   the two images meeting in the middle. Reverts to the equalised two-column
   (captions below) at ≤1200; section 5 is the only Tall. */
.psec--double.psec--tall .psec__item { flex: 1 1 0; min-width: 0; align-items: center; }
.psec--double.psec--tall .psec__item > img.brxe-image {
    flex: 0 0 auto;
    width: calc(var(--media-max-h) * 0.75);   /* half of the Max single's width */
    max-width: 45vw;                            /* mirrors Max's 90% cap, halved */
    aspect-ratio: 3 / 4;                        /* two of these = one 3:2 frame */
    height: auto;
    object-fit: cover;
}
.psec--double.psec--tall.psec--merged .psec__item:nth-child(1) { flex-direction: row-reverse; }
.psec--double.psec--tall.psec--merged .psec__item:nth-child(2) { flex-direction: row; }
.psec--double.psec--tall.psec--merged .psec__item .psec__caption { flex: 1 1 0; min-width: 0; max-width: none; }
.psec--double.psec--tall.psec--merged .psec__item:nth-child(1) .psec__caption { justify-content: flex-end; padding-right: 30px; }
.psec--double.psec--tall.psec--merged .psec__item:nth-child(2) .psec__caption { justify-content: flex-start; padding-left: 30px; }

/* ── The "small-screen" regime comes in over staged breakpoints, widest first:
     ≤1400  ALL singles — captions drop from the side strips to UNDER the image,
                          media goes full-width to the 16px header line
     ≤1200  doubles     — the vw-capped small column equalises into two columns
     ≤767   mobile      — doubles stack, spacing tightens
   Each tier is self-contained (its own 16px padding). Desktop (>1400) keeps the
   side-caption / viewport-fit layout for every single column section. */

/* ── ALL SINGLES: captions side → UNDER at ≤1400 ───────────────────────────
   Unifies every single column section to section 14's behaviour: on desktop
   (>1400) landscape / portrait / max / fitcar all carry captions in the side
   strips beside the image; at ≤1400 the media goes full-width to the 16px header
   line and the captions stack 50/50 underneath (height cap + crop lifted, fitcar
   JS width-sync also bails ≤1400). */
@media (max-width: 1400px) {
    .psec--single.psec { padding-left: 16px; padding-right: 16px; }
    .psec--hero { min-height: auto; }
    .psec--single .psec__media { width: 100%; max-width: none; flex: 0 1 auto; order: -1; }
    .psec--single .psec__title { width: 50%; flex: 0 1 auto; min-width: 0; padding: 0; justify-content: flex-start; }
    .psec--single .psec__tags  { width: 50%; flex: 0 1 auto; min-width: 0; padding: 0; justify-content: flex-end; }
    .psec--portrait .psec__media { max-width: none; }
    .psec__media > img.brxe-image { max-height: none; object-fit: contain; }
    .psec__media video { max-height: none; }
    .pshd-d { display: flex !important; }   /* show desktop-hidden side captions */
    /* fitcar carousel: natural height (its slides aren't the plain `> img`) */
    .psec--fitcar .bricks-swiper-container { height: auto; }
    .psec--fitcar .psec__media .swiper-slide img { height: auto; width: 100%; }
}

/* ── TALL double tracks the Max single it mimics (≤1400) ───────────────────
   Above 1400 it's the AMBER-sized side-caption frame (base rules). At ≤1400 it
   follows AMBER exactly: the pair goes full-width to the 16px line with the
   merged caption UNDER it. Each half keeps its 3:4 crop (base aspect-ratio), so
   the pair stays one full-width 3:2 frame, same as the Max single. */
@media (max-width: 1400px) {
    .psec--double.psec--tall.psec { padding-left: 16px; padding-right: 16px; }
    .psec--double.psec--tall.psec--merged .psec__item:nth-child(1),
    .psec--double.psec--tall.psec--merged .psec__item:nth-child(2) { flex-direction: column; }
    .psec--double.psec--tall .psec__item > img.brxe-image { width: 100%; max-width: none; }
    .psec--double.psec--tall.psec--merged .psec__item .psec__caption { width: 100%; flex: initial; padding: 0; }
    /* padding:0 needs nth-child specificity to beat the desktop side-strip 30px gap (base) */
    .psec--double.psec--tall.psec--merged .psec__item:nth-child(1) .psec__caption { justify-content: space-between; padding: 0; }
    .psec--double.psec--tall.psec--merged .psec__item:nth-child(2) .psec__caption { justify-content: flex-end; padding: 0; }
}

/* ── DOUBLES equalise into two columns early (≤1200) ───────────────────────
   The vw-based --item-cap sizing makes the smaller side tiny on laptops, so at
   ≤1200 both columns equalise out to the 16px header edges (16px gutter; the
   Tall edges-touch pair gets none). Doubles still STACK at ≤767. */
@media (max-width: 1200px) {
    .psec--double.psec { padding-left: 16px; padding-right: 16px; column-gap: 16px; }
    .psec--double .psec__item,
    .psec--double .psec__item.psec__item--small,
    .psec--double .psec__item.psec__item--full {
        flex: 1 1 0; width: auto; max-width: none; align-items: center; --item-cap: 100%;
    }
    .psec--double .psec__item > img.brxe-image,
    .psec--double .psec__item .brxe-carousel,
    .psec--double .psec__caption { width: 100%; max-width: 100%; }
    .psec--double.psec--tall { column-gap: 0; }
    .psec--double.psec--tall .psec__item { flex: 1 1 0; width: auto; max-width: none; }
}

/* 40px breathing room between every section (on top of each section's own
   vertical padding). Footer included. */
#brx-content > section + section,
#brx-content > .brxe-section + .brxe-section { margin-top: 40px; }

/* Footer — small, gray, centered */
.site-footer .brxe-text-basic { margin: 0; }
.site-footer a { color: var(--secondary); text-decoration: underline; }
.site-footer a:hover { text-decoration: none; }

@media (max-width: 767px) {
    /* Tighter mobile rhythm: 12px vertical (overrides the element-setting padding
       the singles tier kept) + 16px sides. Structural changes (media full-width,
       captions under, height-cap lifted, fitcar under) are inherited from the
       ≤1400 singles tier above. */
    .psec--single.psec, .psec--double.psec { padding: 12px 16px; row-gap: 12px; }

    /* Carousels: reserve the tallest image's height so a mixed-orientation
       carousel keeps a constant height (and the page doesn't jump) as it
       autoplays / is swiped. Each slide becomes a box at the tallest image's
       aspect-ratio (`--fitcar-ar`, set per-carousel by script.js — 2/3 fallback)
       with the image contained inside (no crop; landscape slides letterbox). */
    .psec--fitcar .psec__media .swiper-slide img {
        aspect-ratio: var(--fitcar-ar, 2 / 3);
        width: 100%;
        height: auto;
        object-fit: contain;
    }

    /* Doubles STACK now — reset the tablet two-column flex to full-line items.
       64px between stacked items matches the gap between sections
       (12px pad + 40px section margin + 12px pad). */
    .psec--double { flex-wrap: wrap; }
    .psec--double.psec { column-gap: 0; row-gap: 64px; }
    .psec--double .psec__item,
    .psec--double .psec__item.psec__item--small,
    .psec--double .psec__item.psec__item--full,
    .psec--double.psec--tall .psec__item {
        flex: 0 0 100%; width: 100%; max-width: none; padding: 0; --item-cap: 100%; row-gap: 12px;
    }
    .psec--double .psec__item > img.brxe-image,
    .psec--double.psec--tall .psec__item > img.brxe-image { width: 100%; height: auto; max-width: none; aspect-ratio: auto; }

    /* Flip the stacking order (psecdb "Flip on mobile" → .psec--flip): swap which
       photo sits on top. `order` reorders the stacked items; nth-child still
       targets DOM order so the merged-caption logic is unaffected. */
    .psec--double.psec--flip .psec__item:nth-child(1) { order: 2; }
    .psec--double.psec--flip .psec__item:nth-child(2) { order: 1; }

    /* Un-merge merged captions when stacked (each photo carries its own line). */
    .psec--double.psec--merged .psec__item:nth-child(1) .psec__caption > .brxe-text-basic,
    .psec--double.psec--merged .psec__item:nth-child(2) .psec__caption > .psec__ctitle { display: flex; }
    .psec--double.psec--merged .psec__item:nth-child(2) .psec__caption { justify-content: space-between; }
    /* tall uses higher-specificity caption rules above — match them here so it un-merges too */
    .psec--double.psec--tall.psec--merged .psec__item:nth-child(2) .psec__caption { justify-content: space-between; }

    /* Fixed transparent header overlay — first section clears it (mobile padding
       12px < header height). */
    #brx-content > .psec:first-child { padding-top: 66px; }
    #brxe-6vk98w { padding: 16px; }
    #brxe-metabk { padding-top: 66px; }
}

/* Body-class scoped — body isn't a Bricks element */
body.single-portfolio { overflow-x: hidden; }

/* About page section — responsive padding (programmatic _padding:tablet/:mobile
   didn't render as @media on the page either; same quirk as bricks_template).
   Values mirror the v1 Elementor About layout *including* Elementor's default
   10px .e-con inner-container padding (so +10 on every side vs the raw values). */
@media (max-width: 991px) {
    #brxe-2b4596 { padding: 190px 70px 210px 70px; }
}
@media (max-width: 767px) {
    #brxe-2b4596 { padding: 130px 30px; }
}

/* Fallbacks for Bricks programmatic-rendering quirks */
/* _objectFit only renders when paired with _aspectRatio */
.card__image { object-fit: cover; }
/* widthMax on Div doesn't render programmatically */
#brxe-835555 { max-width: 720px; }
/* _flex shorthand on Block doesn't render programmatically */
.card__media { flex: 1 1 0; min-height: 0; }
