/* =========================================================
   Prime Web Media — Public site stylesheet
   Bold creative-agency look. No framework, no external fonts.
   ========================================================= */

:root {
    --bg: #0b0b12;
    --bg-alt: #131320;
    --surface: #191927;
    --surface-2: #21212f;
    --text: #f4f4f8;
    --text-muted: #a3a3b8;
    --border: #2a2a3a;

    --accent-1: #7c3aed;
    --accent-2: #ec4899;
    --accent-gradient: linear-gradient(120deg, var(--accent-1), var(--accent-2));
    --lime: #d4ff3f;

    --radius-sm: 8px;
    --radius: 16px;
    --radius-lg: 28px;

    --shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
    --container: 1180px;

    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
    margin: 0;
    font-family: var(--font);
    background: var(--bg);
    color: var(--text);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

/* Set by main.js while the mobile nav panel is open, so background content
   can't be scrolled behind it. Not gated to a media query on purpose — it
   only ever gets toggled from the hamburger handler, but if a visitor
   resizes past the mobile breakpoint while it's open, the lock should
   release along with the menu rather than sticking around. */
body.nav-open { overflow: hidden; }

img { max-width: 100%; display: block; }

.skip-link {
    position: absolute;
    left: -999px;
    top: 0;
    background: var(--lime);
    color: #0b0b12;
    padding: 10px 16px;
    z-index: 1000;
    font-weight: 700;
}
.skip-link:focus { left: 10px; top: 10px; }

.container {
    max-width: var(--container);
    margin: 0 auto;
    padding: 0 24px;
}

h1, h2, h3, h4 {
    font-weight: 800;
    line-height: 1.15;
    margin: 0 0 0.5em;
    letter-spacing: -0.02em;
}
h1 { font-size: clamp(2.2rem, 5vw, 3.6rem); }
h2 { font-size: clamp(1.8rem, 3.6vw, 2.6rem); }
h3 { font-size: 1.3rem; }
p { color: var(--text-muted); margin: 0 0 1em; }
a { color: inherit; text-decoration: none; }

.accent {
    background: var(--accent-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.section { padding: clamp(60px, 9vw, 110px) 0; }
.section--alt { background: var(--bg-alt); }
.section__head { max-width: 640px; margin: 0 auto 48px; text-align: center; }
.eyebrow {
    display: inline-block;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--lime);
    margin-bottom: 12px;
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 14px 28px;
    border-radius: 999px;
    font-weight: 700;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
    font-size: 0.95rem;
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--shadow); }
.btn--accent {
    background: var(--accent-gradient);
    border: none;
    color: #fff;
}
.btn--lime { background: var(--lime); color: #0b0b12; border: none; }
.btn--outline { background: transparent; }
.btn--small { padding: 10px 20px; font-size: 0.85rem; }
.btn--block { width: 100%; }

/* Header */
/* Transparent over the hero, solid once scrolled past it. main.js toggles
   .is-solid (see the header-state block there) and keeps --header-h in sync
   with the real rendered height. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 500;
    border-bottom: 1px solid transparent;
    transition: border-color 0.35s ease;
}
.site-header.is-solid { border-bottom-color: var(--border); }
/* The frosted-glass tint lives on a pseudo-element rather than directly on
   .site-header on purpose: backdrop-filter (like transform/filter) makes
   the element it's applied to a new containing block for any
   position:fixed descendants — and .main-nav (the mobile menu panel) is
   nested inside .site-header. With the filter directly on .site-header,
   .main-nav's "position:fixed; top:84px; ... bottom:0" was being measured
   against the ~84px-tall header box instead of the real viewport, which is
   why the open mobile menu only ever showed a sliver of its first item.
   Putting the same background+blur on ::before instead gives the identical
   visual result without .site-header itself carrying the filter. */
.site-header::before {
    content: "";
    position: absolute;
    inset: 0;
    /* Near-transparent over the hero so the footage reads through the bar.
       No blur here either — blurring would defeat the point. */
    background: rgba(0, 0, 0, 0.05);
    z-index: -1;
    transition: background-color 0.35s ease, backdrop-filter 0.35s ease;
}
.site-header.is-solid::before {
    background: rgba(11, 11, 18, 0.85);
    backdrop-filter: blur(10px);
}

/* Legibility while transparent. The nav's resting colour (--text-muted) is
   tuned for a flat dark bar and disappears over bright footage, so it lifts to
   near-white with a shadow — same approach as the hero copy. The logo is a PNG,
   so it needs drop-shadow rather than text-shadow. */
.site-header:not(.is-solid) .main-nav > ul > li > a,
.site-header:not(.is-solid) .header-phone,
.site-header:not(.is-solid) .brand__text {
    color: rgba(255, 255, 255, 0.95);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6), 0 2px 14px rgba(0, 0, 0, 0.55);
}
.site-header:not(.is-solid) .brand__logo {
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6));
}
.site-header:not(.is-solid) .hamburger span {
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
}
.site-header__inner {
    display: flex;
    align-items: center;      /* keeps nav/phone/CTA centred against the taller logo */
    justify-content: space-between;
    gap: 24px;
    padding: 14px 24px;
}
.brand { display: flex; align-items: center; }
.brand__logo { height: 38px; width: auto; }
.brand__text { font-weight: 800; font-size: 1.3rem; }

/* Brand mark size, shared by the header and the footer so the two can never
   drift apart. The logo is a wide lockup (867x260, ~3.3:1), so height drives
   width hard — 104px tall would be 347px wide and crowd the header nav inside
   the 1180px container. Hence a fluid clamp: it reaches the full ~2x on wide
   screens and eases down before it can squeeze anything. Nav gaps tighten in
   the same range to buy it room. Redefined at the two breakpoints below. */
:root {
    --brand-logo-h: clamp(58px, 6.6vw, 100px);
    /* Height alone can't size a logo safely — the admin can upload any aspect
       ratio, and a wide lockup (the current file is 2555x300, ~8.5:1) would run
       to ~800px at the height above and swamp the nav. This caps the other axis.
       Replaced elements re-derive their height when max-width binds, so the
       image shrinks proportionally rather than distorting; whichever axis is
       tighter wins, and both ratios end up sensibly sized with no branching. */
    --brand-logo-maxw: min(300px, 26vw);
}

/* Both axes are maxima with auto sizing, deliberately — NOT height + max-width.
   With an explicit height Chrome caps the width but keeps the height, so a wide
   lockup ends up in a 300x100 box it only fills 300x35 of: no distortion (the
   image letterboxes), but the header reserves 65px of empty space. As two
   maxima the box shrinks to the image, so whichever axis binds, the ratio holds
   and nothing is wasted. Trade-off: a logo smaller than these bounds renders at
   its own size rather than being upscaled — which is the right call anyway,
   upscaling a logo just blurs it. */
.site-header .brand__logo,
.site-footer .brand__logo {
    width: auto;
    height: auto;
    max-width: var(--brand-logo-maxw);
    max-height: var(--brand-logo-h);
    align-self: center;   /* .brand--footer is inline-flex with default stretch */
}
.site-header .brand__text { font-size: clamp(1.75rem, 2.2vw, 2.4rem); }

/* Without this the global img{max-width:100%} lets flex squeeze the lockup
   horizontally as space runs out — it kept its height but lost its width, so
   the logo rendered visibly squashed between roughly 880px and 1050px. */
.site-header .brand { flex-shrink: 0; }

@media (max-width: 1240px) {
    .main-nav ul { gap: 20px; }
    .site-header__actions { gap: 12px; }
}
@media (max-width: 1100px) {
    /* Logo + 7 nav links + phone + CTA genuinely stop fitting on one line here
       (they were already colliding before the logo grew). The phone is the
       least critical of them — it's repeated in the mobile nav panel and in the
       footer — so it goes first rather than letting anything get crushed. */
    .header-phone { display: none; }
}

.main-nav ul { list-style: none; display: flex; gap: 28px; margin: 0; padding: 0; }
.main-nav a { font-weight: 600; font-size: 0.95rem; color: var(--text-muted); transition: color 0.2s; }
.main-nav a:hover, .main-nav a.is-active { color: var(--text); }
/* Phone + CTA duplicated inside the nav panel for mobile only — desktop
   already shows these in .site-header__actions, see the media query below. */
.main-nav__cta { display: none; }

.site-header__actions { display: flex; align-items: center; gap: 16px; }
.header-phone { font-weight: 700; font-size: 0.9rem; white-space: nowrap; }

.hamburger {
    display: none;
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px;
}
.hamburger span { width: 24px; height: 2px; background: var(--text); transition: 0.25s; }
.hamburger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hamburger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Hero */
.hero {
    position: relative;
    padding: clamp(80px, 12vw, 140px) 0 clamp(60px, 8vw, 100px);
    text-align: center;
    overflow: hidden;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}
/* The header is sticky and therefore still in flow, so without this the hero
   would start *below* it and the "transparent header over video" effect would
   have nothing behind it. Pull the hero up by the header's height and give the
   padding back on the inside, so the copy still sits correctly in the area
   that's actually visible. --header-h is measured by main.js; the 84px is only
   the pre-JS fallback. Pages with no .hero (404, legal) are unaffected — their
   header is solid from the start. */
:root { --header-h: 84px; }
.hero {
    margin-top: calc(-1 * var(--header-h));
    padding-top: calc(clamp(80px, 12vw, 140px) + var(--header-h));
}
/* Dark scrim + the original purple glow, layered over an optional admin-
   uploaded background image (site_settings: hero_bg_image). With no image
   set, this sits on top of the plain --bg color and looks identical to the
   original hero — the scrim colors match --bg almost exactly. */
.hero__overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    background:
        linear-gradient(180deg, rgba(11, 11, 18, 0.72) 0%, rgba(11, 11, 18, 0.9) 100%),
        radial-gradient(circle at 50% 0%, rgba(124, 58, 237, 0.35), transparent 60%);
    pointer-events: none;
}
.hero__inner { position: relative; z-index: 2; max-width: 780px; margin: 0 auto; }
.hero p.lead { font-size: 1.15rem; margin-bottom: 2em; }
.hero__actions { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }

/* --- Video-first hero (.hero--video, rendered by includes/hero-video.php) ---
   The still frame is painted as the section's background-image *and* set as
   the <video poster>, so there's never a blank flash: poster -> video fade.
   The video only gets a real src once main.js decides playback is wanted. */
.hero--video {
    /* + --header-h so the visible area below the header keeps its full height. */
    min-height: calc(clamp(460px, 70vh, 720px) + var(--header-h));
    display: flex;
    align-items: center;
}
.hero--video .hero__inner { width: 100%; }
/* --- Homepage hero (.hero--home) --------------------------------------------
   Same untinted treatment as .hero--compact: no wash over the footage, with
   legibility handled by a dark pool sized to the copy plus a text-shadow.
   Scoped to its own modifier so the eight .hero--compact templates are
   unaffected. */
.hero--home .hero__overlay--brand {
    background: none;
}
/* Radii of exactly 50% mean the gradient reaches full transparency at the
   element's mid-edges, so the pool dissolves rather than hard-cutting into a
   visible rectangle. .hero__inner is max-width 780px, so the video stays fully
   visible either side of the copy. */
.hero--home .hero__inner::before {
    content: '';
    position: absolute;
    inset: -80px -150px;
    z-index: -1;
    pointer-events: none;
}
/* Carries the load past the pool's edge — notably the outer stat columns.
   Scaled by the same admin setting as the pool but with its own higher floor;
   see hero_text_shadow(). The fallback is the 82%-default value. */
.hero--home .hero__inner h1,
.hero--home .hero__inner p,
.hero--home .hero__inner .stat__num,
.hero--home .hero__inner .stat__label {
    text-shadow: var(--hero-text-shadow,
        0 2px 12px rgba(0, 0, 0, 0.85), 0 0 30px rgba(0, 0, 0, 0.65));
}
/* Hero body copy needs more contrast than the site-wide muted grey. Both the
   subtext (global `p { color: var(--text-muted) }`) and the stat labels inherit
   #a3a3b8, which is tuned for a flat dark background and washes out over
   footage — worst at the bottom of .hero__inner where the pool has already
   faded, and worst again at low backing settings, where a stress render showed
   the subtext dropping out entirely on near-white frames. No drop-shadow
   rescues grey text on a light background; the colour itself has to lift.
   Scoped to the two hero variants, so body copy elsewhere keeps its grey.

   Both colours come from PHP (hero_text_colors()) so the admin's Hero Text
   Transparency setting can scale them; the fallbacks are the 100% values, which
   are exactly what these elements rendered before that setting existed. */
.hero--home .hero__inner h1,
.hero--home .hero__inner .stat__num,
.hero--compact .hero__inner h1 {
    color: var(--hero-text-color, #f4f4f8);
}
.hero--home .hero__inner p.lead,
.hero--home .hero__inner .stat__label,
.hero--compact .hero__inner p.lead {
    color: var(--hero-text-soft-color, rgba(255, 255, 255, 0.88));
}
@media (max-width: 640px) {
    .hero--home .hero__inner::before { inset: -52px -60px; }
}

/* Inner pages: identical footprint to the homepage hero. min-height mirrors
   .hero--video above exactly, and there's deliberately no padding override so
   .hero's own padding applies — same box, same rhythm, on every page. Keep the
   two clamps in sync if either ever changes. */
.hero--compact {
    /* + --header-h so the visible area below the header keeps its full height. */
    min-height: calc(clamp(460px, 70vh, 720px) + var(--header-h));
    display: flex;
    align-items: center;
}
.hero--compact .hero__inner { width: 100%; }
.hero--compact h1 { font-size: clamp(2rem, 5vw, 3.1rem); }
.hero--compact p.lead { margin-bottom: 0; }
/* .lead's bottom margin is zeroed above, so the CTA row (service pages) needs
   its own breathing room. */
.hero--compact .hero__actions { margin-top: 28px; }

/* Jump target for the Contact hero's CTA. html{scroll-behavior:smooth} already
   animates the jump; this keeps the sticky ~84px .site-header from covering the
   first field on arrival. */
#contact-form { scroll-margin-top: 104px; }

/* Inner-page heroes show the footage completely untinted — no wash, no scrim,
   true colour edge to edge. Legibility is handled entirely at the text block
   instead: a soft dark pool sized to the copy, plus a heavy text-shadow.
   (The homepage keeps its full brand overlay — different job, and it carries
   the CTA stack.) This rule out-specifies the base .hero__overlay background,
   so the element stays in the DOM but paints nothing. A compact hero with *no*
   media never gets --brand at all, so it keeps the plain dark scrim. */
.hero--compact .hero__overlay--brand {
    background: none;
}

/* The local backing. Scoped to .hero__inner (max-width 780px, centred), so it
   covers the copy and nothing else — the media stays fully visible across the
   rest of the hero. Sits at z-index -1 inside .hero__inner's own stacking
   context, which puts it behind the text but still above the video (z 0). */
.hero--compact .hero__inner::before {
    content: '';
    position: absolute;
    /* Generous inset + radii of exactly 50% means the gradient reaches full
       transparency right at the element's mid-edges (and earlier at the
       corners), so the pool dissolves instead of hard-cutting into a
       visible rectangle. .hero has overflow:hidden, so the negative
       horizontal inset can't produce a scrollbar. */
    inset: -72px -150px;
    z-index: -1;
    pointer-events: none;
}

/* The pool itself, shared by both hero variants (only their insets differ).
   The stops arrive as complete rgba() strings from includes/header.php
   (hero_pool_stops()), scaled from the single admin setting — no calc() inside
   an alpha channel, which is valid CSS but historically flaky across engines and
   fails silently when it does misbehave. Fallbacks match the seeded 82% so the
   stylesheet still renders correctly on its own. */
.hero--home .hero__inner::before,
.hero--compact .hero__inner::before {
    background: radial-gradient(ellipse 50% 50% at 50% 50%,
        var(--hero-pool-1, rgba(0, 0, 0, 0.82)) 0%,
        var(--hero-pool-2, rgba(0, 0, 0, 0.74)) 38%,
        var(--hero-pool-3, rgba(0, 0, 0, 0.52)) 62%,
        var(--hero-pool-4, rgba(0, 0, 0, 0.22)) 82%,
        rgba(0, 0, 0, 0) 100%);
}
@media (max-width: 640px) {
    .hero--compact .hero__inner::before { inset: -48px -60px; }
}

/* Carries the load wherever the backing has faded out — the descenders and
   outer letters that sit past the pool's edge. Same admin-scaled value as the
   homepage hero; see hero_text_shadow(). */
.hero--compact .hero__inner h1,
.hero--compact .hero__inner p {
    text-shadow: var(--hero-text-shadow,
        0 2px 12px rgba(0, 0, 0, 0.85), 0 0 30px rgba(0, 0, 0, 0.65));
}
.hero-bg-video {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    z-index: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.7s ease;
}
.hero--video.is-video-playing .hero-bg-video { opacity: 1; }
/* Lighter than the no-video scrim above — the dark version buries the footage.
   Brand gradient first, then a bottom-weighted dark wash so the CTA row stays
   readable over bright clips. */
.hero__overlay--brand {
    background:
        linear-gradient(135deg, rgba(139, 92, 246, 0.55), rgba(236, 72, 153, 0.45)),
        linear-gradient(180deg, rgba(11, 11, 18, 0.30) 0%, rgba(11, 11, 18, 0.70) 100%);
}
/* Belt-and-braces: main.js already skips the download in both these cases,
   but if JS never runs the element must not paint a black box over the poster. */
@media (prefers-reduced-motion: reduce) {
    .hero-bg-video { display: none; }
}
@media (max-width: 767px) {
    .hero-bg-video { display: none; }
}

/* Stats */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; margin-top: 64px; }
.stat { text-align: center; }
.stat__num { font-size: clamp(2rem, 4vw, 2.8rem); font-weight: 800; }
.stat__label { color: var(--text-muted); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; }

/* Cards / grids */
.grid { display: grid; gap: 28px; }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 32px;
    transition: transform 0.25s ease, border-color 0.25s ease;
}
.card:hover { transform: translateY(-6px); border-color: var(--accent-1); }
.card__icon {
    width: 52px; height: 52px;
    border-radius: 14px;
    background: var(--accent-gradient);
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 20px;
    overflow: hidden;
}
.card__icon img { width: 34px; height: 34px; object-fit: contain; }
.card a.card__link { color: var(--accent-2); font-weight: 700; font-size: 0.9rem; }

/* --- Alternating service grid (includes/service-cards.php) ------------------
   Two cards per row, text and media treatments alternating so the sides flip
   each row. Shared by the homepage section and /services. */
.service-cards {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 28px;
    align-items: stretch;   /* paired cards match height */
}
/* A trailing odd card (homepage can drop to 5 if a service is unfeatured)
   spans the row rather than leaving a half-width hole. */
.service-card--wide { grid-column: 1 / -1; }

.service-card {
    position: relative;
    border-radius: var(--radius);
    overflow: hidden;
    min-height: 340px;
}

/* Text treatment */
.service-card--text {
    background: var(--surface);
    border: 1px solid var(--border);
    padding: 40px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    transition: transform 0.25s ease, border-color 0.25s ease;
}
.service-card--text:hover { transform: translateY(-6px); border-color: var(--accent-1); }
/* ~3x the old 52px tile / 34px glyph. Sources are 1360x1360 so there's no
   upscaling at this size. */
.service-card__icon {
    width: clamp(112px, 11vw, 150px);
    height: clamp(112px, 11vw, 150px);
    border-radius: 26px;
    background: var(--accent-gradient);
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 28px;
    overflow: hidden;
    flex-shrink: 0;
}
.service-card__icon img { width: 66%; height: 66%; object-fit: contain; }
.service-card--text h3 { font-size: 1.45rem; margin-bottom: 12px; }
.service-card--text p { margin-bottom: 20px; }
.service-card--text .card__link { margin-top: auto; color: var(--accent-2); font-weight: 700; font-size: 0.9rem; }

/* Media treatment — same scrim/overlay language as the portfolio grid */
.service-card--media { background: var(--surface-2); }
.service-card__poster,
.service-card__preview {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
}
.service-card__poster { transition: transform 0.4s ease; }
.service-card--media:hover .service-card__poster { transform: scale(1.06); }
.service-card__preview {
    z-index: 1;
    opacity: 0;
    transition: opacity 0.35s ease;
    pointer-events: none;
}
.service-card.is-previewing .service-card__preview { opacity: 1; }

/* Stand-in until per-service hero media is uploaded. Branded panel rather than
   an empty box, matching .portfolio-item__placeholder. */
.service-card__placeholder {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    padding: 32px;
    text-align: center;
    background:
        linear-gradient(135deg, rgba(139, 92, 246, 0.30), rgba(236, 72, 153, 0.22)),
        var(--surface-2);
}
/* The tile itself comes from .service-card__icon (shared with the text cards).
   Only the spacing differs here: nudge it up so it stays optically centred in
   the visible panel rather than drifting behind the caption scrim. */
.service-card__placeholder .service-card__icon { margin-bottom: 44px; }

.service-card__overlay {
    position: absolute;
    inset: 0;
    z-index: 2;
    background: linear-gradient(0deg, rgba(0, 0, 0, 0.85), transparent 55%);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 28px;
    pointer-events: none;
}
.service-card__overlay .cat {
    color: var(--lime);
    font-size: 0.75rem;
    text-transform: uppercase;
    font-weight: 700;
    letter-spacing: 0.06em;
}
.service-card__overlay h3 { margin: 6px 0 0; font-size: 1.35rem; }
/* Full-card click target, above the overlay. */
.service-card__link { position: absolute; inset: 0; z-index: 3; }

/* Single column well before the two columns get cramped. */
@media (max-width: 900px) {
    .service-cards { grid-template-columns: 1fr; gap: 22px; }
    .service-card--wide { grid-column: auto; }
    .service-card { min-height: 300px; }
    .service-card--text { padding: 32px; }
}

.reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.is-visible { opacity: 1; transform: none; }

/* Portfolio */
.filter-bar { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-bottom: 40px; }
.filter-btn {
    padding: 9px 20px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    font-weight: 600;
    cursor: pointer;
    font-size: 0.85rem;
}
.filter-btn.is-active { background: var(--accent-gradient); color: #fff; border-color: transparent; }

/* Video Ads / Image Ads tabs */
.portfolio-tabs {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-bottom: 32px;
    flex-wrap: wrap;
}
.portfolio-tab {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 13px 28px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    font-weight: 700;
    font-size: 0.95rem;
    cursor: pointer;
    transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.portfolio-tab:hover { color: var(--text); border-color: var(--accent-1); }
.portfolio-tab.is-active { background: var(--accent-gradient); color: #fff; border-color: transparent; }
.portfolio-tab__count {
    font-size: 0.75rem;
    font-weight: 700;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.14);
}
.portfolio-tab:not(.is-active) .portfolio-tab__count { background: var(--surface-2); }
.portfolio-panel[hidden] { display: none; }

.portfolio-item {
    position: relative;
    display: block;
    border-radius: var(--radius);
    overflow: hidden;
    aspect-ratio: 4 / 5;
    cursor: pointer;
    background: var(--surface);
}
.portfolio-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
.portfolio-item:hover img { transform: scale(1.06); }

/* Stand-in when an item has no artwork yet — a branded panel reads as
   deliberate, where the old flat grey rectangle read as a broken image. */
.portfolio-item__placeholder {
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
    padding: 24px;
    text-align: center;
    background:
        linear-gradient(135deg, rgba(139, 92, 246, 0.30), rgba(236, 72, 153, 0.22)),
        var(--surface-2);
}
.portfolio-item__placeholder span {
    font-weight: 700;
    font-size: 0.95rem;
    color: rgba(255, 255, 255, 0.75);
}

/* Muted preview loop, stacked over the poster. src is hydrated by main.js on
   hover (desktop) or on scroll-into-view (touch) — never on page load. */
.portfolio-item__preview {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    z-index: 1;
    opacity: 0;
    transition: opacity 0.35s ease;
    pointer-events: none;
}
.portfolio-item.is-previewing .portfolio-item__preview { opacity: 1; }

/* Full-card click target for image cards (video cards use the play button). */
.portfolio-item__open {
    position: absolute;
    inset: 0;
    z-index: 3;
    border: 0;
    background: transparent;
    cursor: pointer;
}
.portfolio-item--image::after {
    content: '';
    position: absolute;
    top: 16px; right: 16px;
    width: 30px; height: 30px;
    z-index: 2;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.9)
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%230b0b12'%3E%3Cpath d='M15 3h6v6h-2V6.41l-3.29 3.3-1.42-1.42L17.59 5H15V3zM3 15h2v2.59l3.29-3.3 1.42 1.42L6.41 19H9v2H3v-6z'/%3E%3C/svg%3E")
        center / 17px no-repeat;
    opacity: 0;
    transition: opacity 0.25s ease;
}
.portfolio-item--image:hover::after, .portfolio-item--image:focus-within::after { opacity: 1; }
.portfolio-item__overlay {
    position: absolute; inset: 0;
    z-index: 2; /* above .portfolio-item__preview (1), below the click targets (3) */
    background: linear-gradient(0deg, rgba(0,0,0,0.85), transparent 55%);
    display: flex; flex-direction: column; justify-content: flex-end;
    padding: 20px;
    pointer-events: none;
}
/* The homepage tiles are anchors — don't let link styling leak into the caption. */
a.portfolio-item { color: inherit; text-decoration: none; }
.portfolio-item__overlay .cat { color: var(--lime); font-size: 0.75rem; text-transform: uppercase; font-weight: 700; letter-spacing: 0.06em; }
.portfolio-item__play {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 56px; height: 56px; border-radius: 50%;
    background: rgba(255,255,255,0.9);
    display: flex; align-items: center; justify-content: center;
    z-index: 3;
    border: 0;
    padding: 0;
    cursor: pointer;
    transition: transform 0.25s ease, background 0.25s ease;
}
.portfolio-item__play:hover { transform: translate(-50%, -50%) scale(1.1); background: #fff; }
.portfolio-item[data-hidden="true"] { display: none; }

/* --- Sub-offerings on /services/{slug} --------------------------------------
   Informational grid of the specific things sold under a service. Sits inside
   the 820px content column, between the description and the FAQs. */
.suboffering-block { margin-top: 48px; }
.suboffering-block h2 { font-size: clamp(1.5rem, 3vw, 2rem); margin-bottom: 24px; }
.suboffering-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 18px;
}
.suboffering {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 26px;
    transition: border-color 0.25s ease, transform 0.25s ease;
}
.suboffering:hover { border-color: var(--accent-1); transform: translateY(-4px); }
/* Same tile language as the service cards, at a smaller scale — these sit
   alongside body copy, not as a page-level feature. */
.suboffering__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px; height: 56px;
    border-radius: 14px;
    background: var(--accent-gradient);
    overflow: hidden;
    margin-bottom: 16px;
}
.suboffering__icon img { width: 64%; height: 64%; object-fit: contain; }
.suboffering h3 { font-size: 1.08rem; margin-bottom: 8px; }
.suboffering p { margin: 0; font-size: 0.92rem; }

@media (max-width: 640px) {
    .suboffering-grid { grid-template-columns: 1fr; }
    .suboffering { padding: 22px; }
}

/* --- FAQ accordion (includes/faq-section.php) -------------------------------
   Native <details>/<summary>, so it works with no JS, is keyboard operable, and
   browsers can expand it for in-page find. */
.faq-list { max-width: 820px; margin: 0 auto; }
.faq-item {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    margin-bottom: 14px;
    overflow: hidden;
    transition: border-color 0.25s ease;
}
.faq-item[open] { border-color: var(--accent-1); }
.faq-item__q {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 22px 26px;
    cursor: pointer;
    font-weight: 700;
    font-size: 1.05rem;
    list-style: none;          /* kill the default triangle */
    transition: color 0.2s ease;
}
.faq-item__q::-webkit-details-marker { display: none; }
.faq-item__q:hover { color: var(--accent-2); }
.faq-item__q:focus-visible { outline: 2px solid var(--accent-1); outline-offset: -2px; }

/* Custom +/- marker, rotated on open. */
.faq-item__marker {
    position: relative;
    flex: 0 0 auto;
    width: 20px; height: 20px;
}
.faq-item__marker::before,
.faq-item__marker::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 15px; height: 2px;
    background: var(--accent-2);
    transform: translate(-50%, -50%);
    transition: transform 0.3s ease, opacity 0.3s ease;
}
.faq-item__marker::after { transform: translate(-50%, -50%) rotate(90deg); }
.faq-item[open] .faq-item__marker::after { transform: translate(-50%, -50%) rotate(0deg); opacity: 0; }

.faq-item__a {
    padding: 0 26px 24px;
    color: var(--text-muted);
    font-size: 0.98rem;
}
.faq-item__a > :first-child { margin-top: 0; }
.faq-item__a > :last-child { margin-bottom: 0; }
.faq-item__a a { color: var(--accent-2); font-weight: 600; }
.faq-item__a a:hover { text-decoration: underline; }

/* Service pages already sit inside an 820px content column, so the list there
   needs no extra centring — just spacing above the CTA band. */
.faq-inline { margin-top: 48px; }
.faq-inline h2 { font-size: clamp(1.5rem, 3vw, 2rem); margin-bottom: 24px; }
.faq-inline .faq-list { max-width: none; }

@media (max-width: 640px) {
    .faq-item__q { padding: 18px 20px; font-size: 1rem; }
    .faq-item__a { padding: 0 20px 20px; }
}

/* --- Featured Example block on /services/{slug} -----------------------------
   The large media block in the content column, below the intro copy. Not the
   page hero — that sits behind the title above. */
.service-example {
    position: relative;
    border-radius: var(--radius);
    overflow: hidden;
    margin: 0 0 32px;
    background: var(--surface-2);
}
/* Video gets a fixed 16/9 frame so the play affordance has a predictable box. */
.service-example--video { aspect-ratio: 16 / 9; }
.service-example__video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* An uploaded still is shown at its own ratio — cropping someone's ad creative
   to 16/9 would cut the message out of it. */
.service-example--image { background: none; }
.service-example--image img { width: 100%; height: auto; display: block; border-radius: var(--radius); }

/* No example uploaded yet: a contained branded panel, NOT the icon stretched to
   the full column width (which is what this block used to do). */
.service-example--icon {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 56px 24px;
    background:
        linear-gradient(135deg, rgba(139, 92, 246, 0.22), rgba(236, 72, 153, 0.16)),
        var(--surface-2);
    border: 1px solid var(--border);
}

.service-example__play {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    border: 0;
    background: rgba(11, 11, 18, 0.34);
    color: #fff;
    font: inherit;
    cursor: pointer;
    transition: background 0.25s ease;
}
.service-example__play:hover { background: rgba(11, 11, 18, 0.16); }
.service-example__play[hidden] { display: none; }
.service-example__play-icon {
    width: 76px; height: 76px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-gradient);
    box-shadow: 0 10px 34px rgba(0, 0, 0, 0.45);
    transition: transform 0.25s ease;
}
.service-example__play:hover .service-example__play-icon { transform: scale(1.08); }
.service-example__play-label {
    font-weight: 700;
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.7);
}

/* --- Client logo marquee (includes/client-strip.php) ------------------------
   Pure-CSS infinite loop: the track holds the sequence twice and slides to
   -50%, so the wrap point is pixel-identical to the start. */
.section--clients { padding: clamp(44px, 6vw, 72px) 0; }
.section__head--tight { margin-bottom: 28px; }

.client-strip {
    position: relative;
    overflow: hidden;
    /* Feather both ends so logos enter and leave rather than being chopped. */
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.client-strip__track {
    display: flex;
    align-items: center;
    width: max-content;
    animation: client-marquee var(--marquee-duration, 40s) linear infinite;
}
@keyframes client-marquee {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}
/* Let a visitor stop the strip to actually look at a logo. */
.client-strip:hover .client-strip__track { animation-play-state: paused; }

.client-logo {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 clamp(24px, 3.5vw, 52px);
    height: 84px;
}
/* Two maxima with auto sizing: any aspect ratio is normalised to a consistent
   visual weight, and nothing is ever distorted or upscaled. Same approach as
   the header/footer brand mark. */
.client-logo img {
    width: auto;
    height: auto;
    max-height: 52px;
    max-width: 150px;
    object-fit: contain;
    filter: grayscale(1);
    opacity: 0.55;
    transition: filter 0.3s ease, opacity 0.3s ease;
}
.client-logo:hover img,
.client-logo:focus-visible img { filter: none; opacity: 1; }

@media (max-width: 640px) {
    .client-logo { padding: 0 22px; height: 68px; }
    .client-logo img { max-height: 40px; max-width: 116px; }
}

/* Reduced motion: no marquee. The strip becomes a normal touch/trackpad
   scroller so the logos are still all reachable. */
@media (prefers-reduced-motion: reduce) {
    .client-strip { overflow-x: auto; }
    .client-strip__track { animation: none; }
    .client-logo img { filter: none; opacity: 0.8; }
}

/* Testimonials */
.testimonial {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 32px;
}
.testimonial__stars { color: var(--lime); margin-bottom: 12px; letter-spacing: 2px; }
.testimonial__author { display: flex; align-items: center; gap: 12px; margin-top: 20px; }
.testimonial__author img { width: 46px; height: 46px; border-radius: 50%; object-fit: cover; }

/* Team */
.team-card { text-align: center; }
.team-card img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius); margin-bottom: 16px; }
.team-card .role { color: var(--accent-2); font-weight: 600; font-size: 0.9rem; margin-bottom: 10px; }
.team-card .socials { display: flex; gap: 10px; justify-content: center; }

/* Pricing */
.pricing-group { margin-bottom: 72px; }
.pricing-group:last-child { margin-bottom: 0; }
.pricing-group__title {
    text-align: center;
    font-size: clamp(1.3rem, 2.4vw, 1.6rem);
    margin-bottom: 36px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border);
}
.pricing-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 36px 30px;
    display: flex; flex-direction: column;
    position: relative;
}
.pricing-card.is-popular { border-color: var(--accent-2); box-shadow: 0 0 0 1px var(--accent-2); }
.pricing-card__badge {
    position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
    background: var(--accent-gradient); color: #fff; font-size: 0.75rem;
    font-weight: 700; padding: 6px 16px; border-radius: 999px;
}
.pricing-card__price { font-size: 2.4rem; font-weight: 800; margin: 12px 0; }
.pricing-card ul { list-style: none; padding: 0; margin: 24px 0; flex: 1; }
.pricing-card li { padding: 8px 0; border-top: 1px solid var(--border); color: var(--text-muted); }
.pricing-card li:first-child { border-top: none; }

/* Blog */
.blog-card__link { display: block; }
.blog-card img { width: 100%; aspect-ratio: 16/10; object-fit: cover; border-radius: var(--radius); margin-bottom: 18px; }
.blog-card .meta { color: var(--text-muted); font-size: 0.8rem; margin-bottom: 8px; }
.blog-card__excerpt { font-size: 0.88rem; margin: 6px 0 0; }

/* Tags */
.tag-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.tag-chip {
    display: inline-block; padding: 4px 12px; border-radius: 999px;
    background: var(--surface-2); border: 1px solid var(--border);
    color: var(--text-muted); font-size: 0.75rem; font-weight: 600;
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.tag-chip:hover { background: var(--accent-gradient); color: #fff; border-color: transparent; }

/* Admin post preview */
.preview-banner {
    background: var(--lime); color: #0b0b12; text-align: center;
    font-weight: 700; font-size: 0.9rem; padding: 12px 20px;
}
.blog-post { max-width: 760px; margin: 0 auto; }
.blog-post img.featured { width: 100%; border-radius: var(--radius); margin-bottom: 32px; }
.blog-post__content { font-size: 1.05rem; }
.blog-post__content img { border-radius: var(--radius); margin: 24px 0; }

.pagination { display: flex; gap: 10px; justify-content: center; margin-top: 48px; }
.pagination a, .pagination span {
    padding: 10px 16px; border-radius: 8px; border: 1px solid var(--border); color: var(--text-muted);
}
.pagination a:hover { color: var(--text); }
.pagination .is-active { background: var(--accent-gradient); color: #fff; border-color: transparent; }

/* Breadcrumbs */
.breadcrumbs { padding: 20px 0; }
.breadcrumbs ol { list-style: none; display: flex; gap: 8px; padding: 0; margin: 0; flex-wrap: wrap; font-size: 0.85rem; color: var(--text-muted); }
.breadcrumbs li:not(:last-child)::after { content: "/"; margin-left: 8px; }
.breadcrumbs a { color: var(--text-muted); }
.breadcrumbs a:hover { color: var(--text); }

/* Forms */
.form-field { margin-bottom: 20px; }
.form-field label { display: block; font-weight: 600; margin-bottom: 8px; font-size: 0.9rem; }
.form-field input, .form-field select, .form-field textarea {
    width: 100%;
    padding: 13px 16px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    font-size: 0.95rem;
}
.form-field textarea { resize: vertical; min-height: 130px; }
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
    outline: none; border-color: var(--accent-1);
}
.honeypot { position: absolute; left: -9999px; opacity: 0; }

.alert { padding: 16px 20px; border-radius: var(--radius-sm); margin-bottom: 24px; font-size: 0.9rem; }
.alert--success { background: rgba(212, 255, 63, 0.12); border: 1px solid var(--lime); color: var(--lime); }
.alert--error { background: rgba(236, 72, 153, 0.12); border: 1px solid var(--accent-2); color: var(--accent-2); }

/* CTA band */
.cta-band {
    background: var(--accent-gradient);
    border-radius: var(--radius-lg);
    padding: clamp(40px, 6vw, 70px);
    text-align: center;
    color: #fff;
}
.cta-band p { color: rgba(255,255,255,0.85); }
.cta-band .btn { background: #fff; color: #0b0b12; border: none; }

/* Map */
.map-embed { border-radius: var(--radius); overflow: hidden; border: 1px solid var(--border); }
.map-embed iframe { width: 100%; height: 380px; border: 0; display: block; }

/* Footer */
.site-footer { background: var(--bg-alt); border-top: 1px solid var(--border); padding: 70px 0 0; margin-top: 60px; }
.footer__grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1.3fr; gap: 40px; padding-bottom: 50px; }
.footer__col h3 { font-size: 1rem; margin-bottom: 18px; }
.footer__links, .footer__contact { list-style: none; padding: 0; margin: 0; }
.footer__links li, .footer__contact li { margin-bottom: 10px; color: var(--text-muted); font-size: 0.9rem; }
.footer__links a { color: var(--text-muted); }
.footer__links a:hover { color: var(--text); }
.footer__tagline { font-size: 0.9rem; margin: 16px 0; }
.brand--footer { margin-bottom: 16px; display: inline-flex; max-width: 100%; }
/* Footer mark is sized by the same shared rule as the header (see
   --brand-logo-h / --brand-logo-maxw), so the two stay matched at every
   breakpoint and both are capped on width as well as height. The brand column
   is 2fr of 2fr/1fr/1fr/1.3fr — ~382px at full container width — so the 300px
   cap clears it comfortably. */
.site-footer .brand__text { font-size: clamp(1.75rem, 2.2vw, 2.4rem); }
.social-icons { display: flex; gap: 10px; list-style: none; padding: 0; margin: 18px 0 0; }
.social-icons a {
    width: 36px; height: 36px; border-radius: 50%;
    border: 1px solid var(--border);
    display: flex; align-items: center; justify-content: center;
    transition: background 0.2s, border-color 0.2s;
}
.social-icons a:hover { background: var(--accent-gradient); border-color: transparent; }
.footer__bottom { border-top: 1px solid var(--border); padding: 22px 0; text-align: center; color: var(--text-muted); font-size: 0.85rem; }
.footer__bottom-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 28px; }
.footer__bottom-inner p { margin: 0; }
.footer__legal { list-style: none; display: flex; flex-wrap: wrap; gap: 20px; margin: 0; padding: 0; }
.footer__legal a { color: var(--text-muted); }
.footer__legal a:hover { color: var(--text); }

/* WhatsApp float */
.whatsapp-float {
    position: fixed;
    /* --cookie-banner-h is set/cleared by cookie-consent.js so this button
       shifts up out of the way while the cookie banner is visible, instead
       of sitting underneath it. Defaults to 0px (normal position). */
    bottom: calc(24px + var(--cookie-banner-h, 0px));
    right: 24px;
    width: 60px; height: 60px;
    border-radius: 50%;
    background: #25d366;
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 10px 30px rgba(37, 211, 102, 0.5);
    z-index: 900;
    animation: wa-pulse 2.4s infinite;
    transition: bottom 0.3s ease;
}
@keyframes wa-pulse {
    0% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.5); }
    70% { box-shadow: 0 0 0 16px rgba(37, 211, 102, 0); }
    100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0); }
}

/* Cookie consent banner */
.cookie-banner {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 960;
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.35);
    padding: 18px 24px;
    transform: translateY(110%);
    transition: transform 0.35s ease;
}
.cookie-banner.is-visible { transform: translateY(0); }
.cookie-banner__inner {
    max-width: var(--container);
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px 28px;
    flex-wrap: wrap;
}
.cookie-banner__text { margin: 0; font-size: 0.88rem; color: var(--text-muted); flex: 1; min-width: 240px; }
.cookie-banner__text a { color: var(--accent-2); font-weight: 600; }
.cookie-banner__text a:hover { text-decoration: underline; }
.cookie-banner__actions { display: flex; gap: 10px; flex-shrink: 0; }

/* Lightbox */
.lightbox {
    position: fixed; inset: 0; background: rgba(0,0,0,0.9);
    display: none; align-items: center; justify-content: center;
    z-index: 1000; padding: 24px;
}
.lightbox.is-open { display: flex; }
.lightbox__inner { max-width: 900px; width: 100%; }
/* Images size to their own aspect ratio rather than being forced to 16/9. */
.lightbox__inner img { display: block; width: auto; max-width: 100%; max-height: 82vh; margin: 0 auto; border-radius: var(--radius); }
.lightbox__caption { margin: 14px 0 0; text-align: center; color: var(--text-muted); font-size: 0.9rem; }
.lightbox__nav {
    flex: 0 0 auto;
    width: 48px; height: 48px;
    margin: 0 8px;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,0.25);
    background: rgba(0,0,0,0.5);
    color: #fff;
    font-size: 2rem;
    line-height: 1;
    cursor: pointer;
}
.lightbox__nav:hover { background: rgba(255,255,255,0.15); }
.lightbox__nav[hidden] { display: none; }
.lightbox__inner video, .lightbox__inner iframe { width: 100%; aspect-ratio: 16/9; border-radius: var(--radius); border: 0; }
.lightbox__close {
    position: absolute; top: 20px; right: 24px;
    background: none; border: none; color: #fff; font-size: 2rem; cursor: pointer;
}

/* 404 page */
.error-404__code {
    font-size: clamp(6rem, 20vw, 11rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.03em;
    margin-bottom: 0.1em;
}
.error-404__links {
    margin: 24px auto 0;
    padding-top: 40px;
    border-top: 1px solid var(--border);
    max-width: 480px;
}
.error-404__link-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.error-404__link-row a {
    padding: 10px 22px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    font-weight: 600;
    font-size: 0.9rem;
    transition: color 0.2s ease, border-color 0.2s ease;
}
.error-404__link-row a:hover { color: var(--text); border-color: var(--accent-1); }

/* Responsive */

/* Header/nav collapses well above the grid breakpoints below — with the
   brand mark's enlarged size, 7 nav links + phone + CTA button no longer
   fit inline at common tablet widths like 768px, so the hamburger needs to
   take over earlier than the content grids do. */
@media (max-width: 880px) {
    .main-nav {
        position: fixed; top: var(--header-h); left: 0; right: 0; bottom: 0;
        background: var(--bg);
        transform: translateX(100%);
        transition: transform 0.3s ease;
        overflow-y: auto;
        padding: 30px 24px;
        /* Above the WhatsApp float (z-index: 900) so the open mobile menu
           fully covers it instead of the button poking through on top. */
        z-index: 950;
    }
    .main-nav.is-open { transform: translateX(0); }
    .main-nav ul { flex-direction: column; gap: 4px; }
    .main-nav a { display: block; padding: 14px 0; border-bottom: 1px solid var(--border); font-size: 1.05rem; }
    .main-nav__cta {
        display: block;
        margin-top: 24px;
        padding-top: 24px;
        border-top: 1px solid var(--border);
    }
    .main-nav__phone {
        display: block;
        font-weight: 700;
        font-size: 1.1rem;
        margin-bottom: 16px;
        color: var(--text);
    }
    .hamburger { display: flex; padding: 12px; }
    .header-phone, .site-header__actions .btn { display: none; }
    /* Only the logo and the hamburger live in the header here, so the mark gets
       a fixed, generous size instead of the viewport-width clamp — capped so it
       can't crowd the hamburger on a narrow phone. The footer picks this up too,
       via --brand-logo-h. */
    :root { --brand-logo-h: 66px; --brand-logo-maxw: min(240px, 56vw); }
}
@media (max-width: 980px) {
    .grid--4 { grid-template-columns: repeat(2, 1fr); }
    .grid--3 { grid-template-columns: repeat(2, 1fr); }
    .footer__grid { grid-template-columns: 1fr 1fr; }
    .stats { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
    .grid--4, .grid--3, .grid--2 { grid-template-columns: 1fr; }
    .footer__grid { grid-template-columns: 1fr; }
    .stats { grid-template-columns: repeat(2, 1fr); gap: 32px; }

    /* Touch targets: bump up interactive elements that are comfortably
       sized with a mouse but too small to tap reliably on a phone. */
    .filter-btn { padding: 13px 20px; min-height: 44px; }
    .pagination a, .pagination span {
        min-height: 44px; min-width: 44px;
        display: inline-flex; align-items: center; justify-content: center;
    }
    .social-icons a { width: 44px; height: 44px; }
    .lightbox__close { padding: 10px; }
    .btn--small { min-height: 44px; }
}

/* Safety net for very narrow phones (~320-360px): the enlarged header
   brand text + the hamburger's larger tap target can get tight together,
   so trim the brand text a bit rather than risk overlap. */
@media (max-width: 380px) {
    .site-header .brand__text { font-size: 1.4rem; }
    :root { --brand-logo-h: 54px; --brand-logo-maxw: min(190px, 58vw); }
    .site-header__inner { padding: 12px 16px; gap: 12px; }
}
