/* ==========================================================================
   KB Home — Elementor wrapper reset
   Homepage content only. Resets Elementor's default 10px vertical padding
   on .e-con-inner for every homepage content section, while preserving
   padding-left / padding-right (gutters). Header (.kb-header) and
   Footer (.kb-footer) widgets do NOT use .e-con-inner, so they are
   untouched. Left/right padding and per-section spacing remain intact.
   ========================================================================== */
body.home .e-con-inner {
    padding-block: 0 !important;
}

/* ==========================================================================
   KB Home Hero — Atlasyn × Khaoula Bouabidi
   Scoped strictly to .kb-home-hero (and its full-bleed ancestors below).
   No border-radius. No heavy shadow. Editorial. Couture.
   All values driven by tokens.css (design-system source of truth).

   Composition (final):
     The full Hero image is an absolute background layer that covers the
     entire section (top, bottom, left, right). The editorial copy
     (eyebrow / title / text / CTAs) is layered over the LEFT side of the
     same canvas via a position:relative layout sitting above a soft
     Bordeaux left-to-right gradient overlay (using the --kb-bordeaux
     brand token, same color as the global Footer). The two CTAs share
     one outline-architecture system (Porcelain primary, Gold secondary)
     so they clearly belong to the same family.

   Elementor contract: the Hero image is still a real <img> selected
   through the existing MEDIA content control. CSS converts it into a
   true background layer (position:absolute, inset:0) — no inline
   style="background-image:..." is ever emitted by the widget.
   ========================================================================== */

.kb-home-hero {
    position: relative;
    width: 100%;
    background-color: var(--kb-porcelain);
    color: var(--kb-ink);
    overflow: hidden;
    /* Definite Hero height. This is the source of truth for the
       "fill the viewport below the header" rule on desktop. The
       absolute media layer and the position:relative layout both
       resolve their own 100% height against this number. */
    min-height: calc(100svh - var(--kb-header-height-desktop));
}

/* Soft Bordeaux left-to-right gradient. Lives between the image
   (z-index 0) and the copy (z-index 2) so the editorial text always
   has a calm brand-aligned readable field on the left while the right
   side of the photograph (the model + gown) stays fully visible.
   Uses color-mix() against the existing --kb-bordeaux token so the
   overlay tint tracks the design system exactly — no hardcoded rgba
   literals, no muddy full-image veil.

   Multi-stop curve (refined): the far-left is softened from a heavy
   78% to 70% Bordeaux so the read does not feel "stuck" on the wall,
   then the curve eases out through 7 stops (vs the previous 5) for a
   more gradual, controlled transition into the unobstructed image.
   Total fade length extended slightly (transparent by 90%) so the
   subject on the right side stays cinematic and free of any tint. */
.kb-home-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(
        to right,
        color-mix(in srgb, var(--kb-bordeaux) 70%, transparent) 0%,
        color-mix(in srgb, var(--kb-bordeaux) 58%, transparent) 16%,
        color-mix(in srgb, var(--kb-bordeaux) 44%, transparent) 32%,
        color-mix(in srgb, var(--kb-bordeaux) 30%, transparent) 48%,
        color-mix(in srgb, var(--kb-bordeaux) 18%, transparent) 62%,
        color-mix(in srgb, var(--kb-bordeaux) 8%, transparent) 76%,
        color-mix(in srgb, var(--kb-bordeaux) 3%, transparent) 86%,
        transparent 90%
    );
}

/* ==========================================================================
   FULL-BLEED ESCAPE — Hero section architecture
   ------------------------------------------------------------
   The KB design system requires ALL page Hero sections to be true
   full-bleed (outer 100% viewport width, inner content aligned to the
   1140px content grid). The Home Hero is a regular Elementor content
   widget, not a Theme Builder template, so it inherits the page's
   .atlasyn-container (parent theme, 1200px max-width + auto margins) and
   the Elementor .e-con (1140px max-width + auto margins) defaults. Both
   visibly center the Hero with large side margins.

   This narrow :has() reset escapes those wrapper constraints ONLY when the
   ancestor actually contains a Hero widget, leaving all unrelated page
   .e-con containers completely untouched.

   REUSABLE CONTRACT — every future page Hero widget (About, Services,
   Créations, Expérience, Contact, service-page Heroes, etc.) MUST add
   the class `kb-hero` to its root element. The CSS below then
   automatically grants it the same full-bleed ancestor override.
   No global reset. No negative-margin hacks. No 100vw math.
   ========================================================================== */

/* (0) Page-level block padding — the parent theme's base.css sets
   `.site-main { padding-block: 2rem; }` (≈ 32px top + 32px bottom).
   That block padding visibly breaks the "Hero immediately under Header"
   rule on any page that uses our full-width Hero architecture. The
   :has() selector scopes the reset to pages whose main loop actually
   contains a Hero widget — all other page templates keep their normal
   vertical rhythm. */
.site-main:has(.kb-hero) {
    padding-block: 0;
}

/* (1) Parent theme content container — .atlasyn-container is the page's
   1200px max-width wrapper from atlasyn-core/utilities.css. */
.atlasyn-container:has(.kb-hero) {
    max-width: 100% !important;
    width: 100% !important;
    margin-inline: 0 !important;
    padding-inline: 0 !important;
}

/* (2) Elementor .e-con default container — defaults to 1140px max-width
   plus auto horizontal margins. Reset all container custom properties
   so this Hero and any future container it sits in stay edge-to-edge. */
.e-con:has(.kb-hero) {
    --container-default-width: 100% !important;
    --container-max-width: 100% !important;
    --container-default-padding: 0px !important;
    --container-default-padding-block: 0px !important;
    --container-default-padding-inline: 0px !important;
    width: 100% !important;
    max-width: 100% !important;
    margin-inline: 0 !important;
    padding-inline: 0 !important;
    padding-block: 0 !important;
}

/* (3) Elementor .e-con-inner — inner counterpart of (2). */
.e-con:has(.kb-hero) > .e-con-inner {
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    --container-default-padding: 0px !important;
    --container-default-padding-block: 0px !important;
    --container-default-padding-inline: 0px !important;
}

/* ---- Single-canvas layout -----------------------------------------------
   The Hero is now a single full-bleed canvas, not a 2-column grid.
   The position:relative + z-index:2 places the copy above the absolute
   image layer (z-index 0) and the soft Bordeaux overlay (z-index 1).
   display:flex + align-items:center vertically centers the copy inside
   the inherited Hero height without needing a grid row. min-height:inherit
   keeps the layout matching the Hero root's definite viewport-minus-header
   value so the flex parent has a real height to center against. */
.kb-home-hero__layout {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    min-height: inherit;
    width: 100%;
}

/* ---- Copy block ---------------------------------------------------------
   padding-inline-start: max(0, (100vw - 1140) / 2) pins the copy's left
   edge to the 1140px content frame on viewports >= 1140px. On narrower
   viewports the max() collapses to 0 so the copy sits at viewport left.
   No right padding: the actual footprint is owned by .kb-home-hero__copy-inner's
   max-width (60% of 1140 ≈ 684px) so the editorial block reads as
   occupying the left ~60% of the Hero and the two CTAs fit comfortably
   on a single row at the locked 54px height. */
.kb-home-hero__copy {
    padding-inline-start: max(0px, calc((100vw - var(--kb-content-width)) / 2));
    min-width: 0;
    flex: 0 0 auto;
}

/* Footprint widened to ~60% of the 1140px content frame so the two
   CTAs sit comfortably on the same row at their locked 54px height
   with the design system gap. The eyebrow / title / text still read
   as a left-side editorial block thanks to text-wrap: balance +
   text-wrap: pretty, and the right ~40% of the canvas stays free
   for the unobstructed photograph. margin-inline-start: 0 keeps the
   block left-aligned inside the padded copy cell. */
.kb-home-hero__copy-inner {
    width: 100%;
    max-width: calc(var(--kb-content-width) * 0.6);
    margin-inline-start: 0;
}

/* ---- Media background layer ---------------------------------------------
   The figure is now a true background layer. position:absolute + inset:0
   makes it cover the entire Hero canvas (top, bottom, left, right). The
   <img> inside fills the figure via width/height 100% + object-fit:cover.
   z-index 0 keeps the image BEHIND both the Bordeaux overlay (::after
   z-index 1) and the editorial copy (layout z-index 2). The fallback
   Bordeaux→Ink gradient is preserved so the canvas is never empty before
   the asset is selected. */
.kb-home-hero__media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    z-index: 0;
    overflow: hidden;

    /* Subtle theme-controlled fallback surface for when no Hero image
       has been approved yet. A soft Bordeaux → Ink diagonal wash keeps
       the canvas from rendering as an empty void while waiting for a
       real photograph. Sits BEHIND the image (which is then on top of
       it via object-fit:cover) and is never visible once the asset is
       in place. */
    background:
        linear-gradient(135deg, var(--kb-bordeaux) 0%, var(--kb-ink) 100%);
}

.kb-home-hero__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Centered focal point. The source photograph is composed so the
       model + gown sit roughly on the right side; with object-fit:cover
       filling a viewport-wide canvas, "center center" keeps the subject
       visible on the right while letting the immersive composition
       breathe. Tune horizontally in CSS only — never exposed to Elementor. */
    object-position: center center;
}

/* ---- Eyebrow ------------------------------------------------------------
   Gold caps, restrained tracking. Reuses the Header eyebrow vocabulary
   so the Hero reads as part of the same editorial family. */
.kb-home-hero__eyebrow {
    margin: 0 0 var(--kb-space-m) 0;
    font-family: var(--kb-font-body);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--kb-gold);
}

/* ---- Hero title ---------------------------------------------------------
   Single H1 on the page. Raleway display, hairline weight, line-height 1,
   text-wrap: balance so the line break is editorial (not a "first line
   short, second line overflowing" SaaS look). Desktop title size 60px
   (the Hero is the ONLY section allowed to use the 60px title spec;
   all other home sections use 44px). */
.kb-home-hero__title {
    margin: 0 0 var(--kb-space-m) 0;
    font-family: var(--kb-font-display);
    font-size: 60px;
    font-weight: 300;
    line-height: 1;
    letter-spacing: -0.01em;
    /* Porcelain on the Bordeaux left overlay for AA-grade contrast
       against the brand-tinted gradient. */
    color: var(--kb-porcelain);
    text-wrap: balance;
}

/* ---- Supporting text ----------------------------------------------------
   Body face, generous line-height, capped at ~48ch so the line length
   stays editorial. text-wrap: pretty prevents orphan/widow lines.
   Desktop 17px (the Hero is the ONLY section allowed to use the
   17px body spec; all other home sections use 15px). */
.kb-home-hero__text {
    margin: 0 0 var(--kb-space-l) 0;
    font-family: var(--kb-font-body);
    font-size: 17px;
    font-weight: 400;
    line-height: 1.7;
    /* Porcelain on the Bordeaux left overlay for consistent
       readability with the H1 above. */
    color: var(--kb-porcelain);
    max-width: 48ch;
    text-wrap: pretty;
}

/* ---- CTA group ----------------------------------------------------------
   Both Hero CTAs share the same outline-architecture: transparent
   ground, 1px frame, square corners (--kb-radius: 0), same 54px height,
   same 13px Montserrat label, same 0.12em tracking, same smooth
   --kb-transition-button on background-color / color / border-color.

   The only difference between the two is the accent color (Porcelain
   for the primary, Gold for the secondary) and its hover inversion.
   The locked .kb-button system in base.css is never modified — the
   .kb-home-hero__cta--* modifiers below only override the visible
   color tokens on top of the existing primitive.

   State cascade (fixed): the previous version used `:focus` together
   with `:hover` for the fill inversion, which made a clicked button
   (mouse focus) get stuck in the filled hover state until the user
   moved the pointer away. The cascade is now split:

     :visited  → forced back to NORMAL (anchors can drift otherwise)
     :hover    → mouse pointer over the button → fill inversion
     :active   → button physically pressed → same fill as hover
     :focus-visible → only keyboard focus → NORMAL appearance +
                     restrained Gold focus ring (not the hover fill)

   :hover, :active, :focus-visible are independent so a click releases
   the fill immediately, focus-visible never paints the hover state,
   and visited never alters the brand colors. */
.kb-home-hero__ctas {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--kb-space-s);
    margin-top: var(--kb-space-m);
}

.kb-home-hero__ctas .kb-button {
    width: auto;
    flex: 0 0 auto;
}

.kb-home-hero__cta {
    flex: 0 0 auto;
    /* Hero-scoped motion refinement. Promotes the base 300ms transition
       to the --kb-transition-button token (500ms easeOutQuint) for a
       calmer, more premium hover. background-color, color and
       border-color only — no transition: all, no transform, no scale. */
    transition:
        background-color var(--kb-transition-button),
        color var(--kb-transition-button),
        border-color var(--kb-transition-button);
}

/* PRIMARY / PORCELAIN CTA — outline architecture, Porcelain frame. */
.kb-home-hero__cta--primary,
.kb-home-hero__cta--primary:visited {
    background-color: transparent;
    color: var(--kb-porcelain);
    border-color: var(--kb-porcelain);
}
/* Hover fill must ONLY run on devices that actually support hover
   with a fine pointer. Touch browsers (iOS Safari, Android Chrome,
   etc.) emulate and can stick :hover after a tap, which would leave
   the CTA visually frozen in its filled state. By gating the hover
   rule behind (hover: hover) and (pointer: fine), coarse-pointer
   devices never receive the fill — the button returns to its normal
   outline palette immediately on release.

   :active is intentionally kept outside the media query so the brief
   "press" feedback still works on touch (finger down → filled,
   finger up → back to normal). :focus-visible is also kept outside
   the media query so keyboard focus is independent of pointer type. */
.kb-home-hero__cta--primary:active {
    background-color: var(--kb-porcelain);
    color: var(--kb-ink);
    border-color: var(--kb-porcelain);
}
.kb-home-hero__cta--primary:focus-visible {
    /* Normal Porcelain appearance (no hover fill) + restrained Gold
       focus ring so the keyboard focus state is visible on the
       Bordeaux overlay but does NOT visually become the hover state. */
    background-color: transparent;
    color: var(--kb-porcelain);
    border-color: var(--kb-porcelain);
    outline: 2px solid var(--kb-gold);
    outline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) {
    .kb-home-hero__cta--primary:hover {
        background-color: var(--kb-porcelain);
        color: var(--kb-ink);
        border-color: var(--kb-porcelain);
    }
}

/* SECONDARY / GOLD CTA — outline architecture, Gold frame. */
.kb-home-hero__cta--secondary,
.kb-home-hero__cta--secondary:visited {
    background-color: transparent;
    color: var(--kb-gold);
    border-color: var(--kb-gold);
}
/* Hover fill must ONLY run on devices that actually support hover
   with a fine pointer (mouse / trackpad). On coarse-pointer touch
   devices, :hover is emulated and can stick after a tap, which
   would leave the Gold CTA visually frozen in its filled state.
   The hover rule is therefore gated behind (hover: hover) and
   (pointer: fine) so touch devices never receive the fill.

   :active stays outside the media query so the brief press feedback
   (filled Gold ground + Ink label) still works on touch and clears
   immediately on release. :focus-visible stays outside so keyboard
   focus is independent of pointer type. */
.kb-home-hero__cta--secondary:active {
    background-color: var(--kb-gold);
    color: var(--kb-ink);
    border-color: var(--kb-gold);
}
.kb-home-hero__cta--secondary:focus-visible {
    /* Normal Gold appearance (no hover fill) + restrained Gold focus
       ring offset 3px outside the border so it reads on the
       Bordeaux overlay without dissolving into the button. */
    background-color: transparent;
    color: var(--kb-gold);
    border-color: var(--kb-gold);
    outline: 2px solid var(--kb-gold);
    outline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) {
    .kb-home-hero__cta--secondary:hover {
        background-color: var(--kb-gold);
        color: var(--kb-ink);
        border-color: var(--kb-gold);
    }
}

/* ==========================================================================
   Tablet (≤ 1199px)
   - Same full-background principle as desktop: image covers the whole
     canvas, copy sits over the left side.
   - Min-height accounts for the tablet header (80px).
   - Title scales to 60px. Body 17px.
   ========================================================================== */
@media (max-width: 1199px) {
    /* Tablet header is 80px — promote the new definite height to the
       Hero root so the absolute media layer and the layout both fill
       the new viewport-minus-header size. */
    .kb-home-hero {
        min-height: calc(100svh - var(--kb-header-height-tablet));
    }

    .kb-home-hero__title {
        font-size: 60px;
    }

    .kb-home-hero__text {
        font-size: 17px;
        max-width: 40ch;
    }
}

/* ==========================================================================
   Tablet (768px – 1024px) — typography refinement
   ------------------------------------------------------------
   The wider tablet band (≤ 1199px) above keeps the title at the
   desktop 60px so 1025–1199px stays in lockstep with desktop. This
   narrower 768–1024px band refines the Hero typography to the
   visual middle point between the already-correct desktop and
   mobile specs:

     - title       53px  (between 60px desktop / 46px mobile)
     - descriptive 17px  (same as desktop / mobile)
     - eyebrow     11.5px (between 12px desktop / 11px mobile)

   Desktop and mobile are intentionally untouched.
   ========================================================================== */
@media (min-width: 768px) and (max-width: 1024px) {
    .kb-home-hero__title {
        font-size: 53px;
    }

    .kb-home-hero__text {
        font-size: 17px;
    }

    .kb-home-hero__eyebrow {
        font-size: 11.5px;
    }
}

/* ==========================================================================
   Mobile (≤ 767px) — Hero architecture stays the same as desktop
   (full-section background image + content layered over it + Bordeaux
   atmosphere). This block is MOBILE ONLY — desktop and tablet are
   untouched.

   Layout intent:
   - Hero fills the visible screen below the 72px mobile Header.
   - Content sits in the lower portion of the Hero (not floating at
     the top under the Header) with comfortable breathing room.
   - Image focal point is right-biased so the subject (woman + gown)
     stays visible after the aggressive mobile crop.
   - Bordeaux overlay is a layered horizontal + vertical fade so the
     readable field is concentrated in the lower-left where the copy
     lives, while the upper-right stays clear for the photograph.
   - CTAs stack vertically, full-width, inside the 20px mobile gutter.
   - No serif. No radius. No shadow. No SaaS card treatment.
   - Header / Footer / desktop / tablet / tokens / Elementor JSON
     are NOT touched by this block.
   ========================================================================== */
@media (max-width: 767px) {
    .kb-home-hero {
        min-height: calc(100svh - var(--kb-header-height-mobile));
    }

    /* Mobile Bordeaux atmosphere: layered horizontal + vertical fade.
       The horizontal layer (listed second, sits behind) provides the
       brand-tint anchor on the left; the vertical layer (listed
       first, on top) adds a subtle bottom darken so the copy sits in
       a controlled readable pocket without flattening the photo. The
       upper-right of the canvas stays clear so the subject remains
       visible. No solid Bordeaux screen, no Porcelain wash. */
    .kb-home-hero::after {
        background:
            linear-gradient(
                to bottom,
                transparent 15%,
                color-mix(in srgb, var(--kb-bordeaux) 22%, transparent) 100%
            ),
            linear-gradient(
                to right,
                color-mix(in srgb, var(--kb-bordeaux) 72%, transparent) 0%,
                color-mix(in srgb, var(--kb-bordeaux) 48%, transparent) 32%,
                color-mix(in srgb, var(--kb-bordeaux) 22%, transparent) 58%,
                transparent 80%
            );
    }

    /* Editorial rhythm — eyebrow spacing is owned by the canonical
       .kb-section-eyebrow primitive (base.css). No per-section override
       needed on mobile. */

    /* Layout: vertically center the copy block in the Hero on
       mobile. The desktop / tablet layout already centers with
       `align-items: center`; this is a single-property mobile
       refinement to keep the editorial block on the visual
       vertical axis of the canvas instead of anchoring it to
       the top or the bottom edge. */
    .kb-home-hero__layout {
        align-items: center;
    }

    /* Copy cell: full width, 20px gutter on both sides, comfortable
       breathing room from the bottom edge (and a smaller breathing
       room from the top so the content never collides with the
       Header on very short screens). The desktop padding-inline-end
       reserve is removed — mobile content uses the full canvas width. */
    .kb-home-hero__copy {
        width: 100%;
        padding-inline-start: var(--kb-gutter-mobile);
        padding-inline-end: var(--kb-gutter-mobile);
        padding-top: var(--kb-space-l);
        padding-bottom: var(--kb-space-xl);
    }

    .kb-home-hero__copy-inner {
        max-width: none;
        width: 100%;
    }

    /* Image: right-biased focal point so the subject (woman on the
       right side of the source composition) stays visible after the
       aggressive mobile crop. Not exposed to Elementor — tuned in
       CSS only. 360px → 390px viewports all keep the woman + gown
       inside the visible frame. */
    .kb-home-hero__media img {
        object-position: 68% center;
    }

    .kb-home-hero__eyebrow {
        font-size: 11px;
        margin-bottom: 20px;
    }

    .kb-home-hero__title {
        font-size: 46px;
        line-height: 1;
    }

    .kb-home-hero__text {
        font-size: 17px;
        line-height: 1.7;
        max-width: none;
    }

    /* CTA group: stacked vertically, full-width buttons. This is
       Hero-mobile-specific only — the global .kb-button architecture
       (54px height, 28px padding, Montserrat 13px / 0.12em / 500 /
       uppercase / radius 0) is untouched. The recently fixed
       normal / hover / active / focus-visible / visited state
       cascade is also untouched. */
    .kb-home-hero__ctas {
        flex-direction: column;
        align-items: stretch;
        gap: var(--kb-space-s);
        width: 100%;
        margin-top: var(--kb-space-m);
    }

    .kb-home-hero__ctas .kb-button {
        width: 100%;
        flex: 0 0 auto;
    }
}

/* ==========================================================================
   HERO EDITORIAL ENTRANCE (page-load CSS keyframes)
   ------------------------------------------------------------
   The Hero is above the fold and present at first render. It
   uses its OWN dedicated CSS @keyframes (NOT the generic
   [data-kb-reveal] / IntersectionObserver system used by
   Section 02 and below-the-fold sections). CSS animations are
   deterministic for above-the-fold load — no first-paint class
   sequencing race, no IntersectionObserver dependency, no
   forced reflow.

   Two keyframe groups, applied directly to the Hero elements
   via the `animation` shorthand:

     kb-home-hero-media-enter  → the background image fades in
                                 while softly resolving from
                                 scale 1.025 → 1.
     kb-home-hero-copy-enter   → the entire copy block (eyebrow,
                                 title, paragraph, BOTH CTAs)
                                 rises 26px → 0 while fading
                                 0 → 1. The buttons are NOT
                                 animated independently — they
                                 ride the parent wrapper.

   Stagger:
     0ms     — image begins (1200ms, scale 1.025 → 1)
     180ms   — copy joins   (1100ms, translateY 26px → 0)
   After ~1.28s, every transform is `none` and every opacity
   is 1 — the existing canonical button hover / focus / touch
   / state system is fully untouched (the keyframe composes
   `transform` on the parent wrapper only).

   Reduced motion:
     The third keyframe `none` override below resets the Hero
     to its final visible state immediately for users with
     prefers-reduced-motion: reduce.
   ========================================================================== */

@keyframes kb-home-hero-media-enter {
    from {
        opacity: 0;
        transform: scale(1.025);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

@keyframes kb-home-hero-copy-enter {
    from {
        opacity: 0;
        transform: translate3d(0, 26px, 0);
    }
    to {
        opacity: 1;
        transform: translate3d(0, 0, 0);
    }
}

/* Background image — desktop. */
.kb-home-hero__media {
    animation-name: kb-home-hero-media-enter;
    animation-duration: 1200ms;
    animation-timing-function: var(--kb-reveal-easing);
    animation-delay: 0ms;
    animation-fill-mode: both;
    animation-iteration-count: 1;
}

/* Copy group (eyebrow / title / paragraph / both CTAs) — desktop.
   The wrapper itself is animated; every child rides the parent
   transform/opacity automatically. No child-level animation. */
.kb-home-hero__copy {
    animation-name: kb-home-hero-copy-enter;
    animation-duration: 1100ms;
    animation-timing-function: var(--kb-reveal-easing);
    animation-delay: 180ms;
    animation-fill-mode: both;
    animation-iteration-count: 1;
}

/* Reduced motion — the Hero is final-state immediately. */
@media (prefers-reduced-motion: reduce) {
    .kb-home-hero__media,
    .kb-home-hero__copy {
        animation: none;
        opacity: 1;
        transform: none;
    }
}

/* Mobile: slightly faster, shorter rise. Same easing. */
@media (max-width: 767px) {
    .kb-home-hero__media {
        animation-duration: 1000ms; /* spec: 1000ms */
    }

    .kb-home-hero__copy {
        animation-name: kb-home-hero-copy-enter-mobile;
        animation-duration: 950ms; /* spec: 950ms */
        animation-delay: 140ms; /* spec: 140ms */
    }
}

/* Mobile copy keyframe — shorter 18px rise for a calm, restrained
   entrance that does not feel like a "card lift" on small screens. */
@keyframes kb-home-hero-copy-enter-mobile {
    from {
        opacity: 0;
        transform: translate3d(0, 18px, 0);
    }
    to {
        opacity: 1;
        transform: translate3d(0, 0, 0);
    }
}
