/* ==========================================================================
   Pixels Productions — client revision round, Sept 2026
   Loaded on every page, after the theme CSS. Nothing here edits vendor files,
   so a Pelicula/Elementor update cannot wipe it.

   Palette is defined once below and is the client's exact brand palette.
   Note that cream also lives in ~336 inline style="color:#E2E0D7" attributes
   in the HTML, so re-tinting cream means sweeping those too, not just this
   file (20_global.py is what writes them).
   ========================================================================== */

:root {
  --px-cream:      #E2E0D7;   /* replaces pure white for all typography      */
  --px-cream-soft: rgba(226, 224, 215, 0.72);
  --px-cream-dim:  rgba(226, 224, 215, 0.45);
  --px-blood:      #9C2016;   /* brand BLOOD — the one red                   */
  --px-red:        var(--px-blood);  /* alias, kept so older rules still read */
  --px-navy:       #151935;   /* Contact hero scrim                          */
  --px-navy-rgb:   21, 25, 53;       /* same value, for rgba() with an alpha  */
  --px-navy-line:  #222855;   /* NAVY at +8.8pts lightness                    */
  --px-electric:   #1A43F3;   /* brand ELECTRIC — unused, kept for the record */
}

/* These are the client's exact brand values, confirmed against the brand book
   (brand assets p2): INK #000000, CREAM #E2E0D7, NAVY #151935,
   ELECTRIC #1A43F3, BLOOD #9C2016. Nothing here is an approximation any more,
   so do not "tune" them.

   The book prints ELECTRIC's hex as #E4E2D9, which is cream — the swatch
   itself measures #1A43F3. The printed value is a typo; ELECTRIC is unused on
   the site so far either way.

   --px-navy-line is the only derived value: it is the hover box's 1px border,
   NAVY lifted 8.8 lightness points, the same lift the previous pair used.

   KNOWN TRADE-OFF: BLOOD is built to be a solid fill on a cream page, and
   this site is black. As a large fill it is strong — the cream knockout on
   top measures 6.03:1 — but as a 1-2px hairline on black it measures 2.63:1,
   under the 3:1 WCAG floor for UI components. The active-page mark and the
   opener lines are those hairlines. This is the client's stated colour, so it
   stands; if those indicators ever need to read harder, thicken them rather
   than inventing a lighter red that is not in the palette. */

/* --------------------------------------------------------------------------
   1. TYPOGRAPHY COLOUR — white -> cream/off-white
   IMPORTANT: the dark pages get their white from inline style="color:#FFFFFF"
   attributes, and those were rewritten to cream in the HTML itself. Do NOT add
   blanket `h1..h6 { color: cream }` rules here: the single-post template
   (post-*.html) is a LIGHT page — white background, near-black headings, grey
   body — and a blanket override makes that text invisible.
   Only genuinely-white-on-dark chrome belongs below.
   -------------------------------------------------------------------------- */

/* The theme flags dark-background pages with body.qodef-header--light and
   forces the nav to #fff !important there. Single posts and archives do NOT
   carry that class — they print #111 nav on a white header — so recolour only
   the light-on-dark case, matching the theme's specificity to win.
   (The 1px menu mark is painted with `currentColor`, so it follows this
   automatically; no separate rule needed.) */
body.qodef-header--light #qodef-page-header #qodef-page-header-inner
  .qodef-header-navigation > ul > li > a {
  color: var(--px-cream) !important;
}

/* theme buttons print white label text on a solid fill */
.qodef-theme-button,
button[type="submit"],
input[type="submit"],
#qodef-page-footer input[type="email"] {
  color: var(--px-cream);
}

/* The card chrome the theme paints #fff from its own stylesheet, so no inline
   style was there to rewrite and these survived the first retint. Audited in
   the browser rather than grepped: 20 nodes were still pure white — project
   and post card titles, every "READ MORE" and "CONTACT US" label, the "share"
   captions, and the struck word inside a post title.

   Scoped to body.qodef-header--light, which is the theme's own flag for a
   dark-background page. It is exact here: index/about/services/ourwork/blog/
   contact and the portfolio pages carry it, while post-*, category-*,
   archive-* and author-* (the LIGHT template, near-black text on white) do
   not — and painting cream there would make them unreadable. That is the same
   trap the note at the top of this section warns about. */
body.qodef-header--light .qodef-m-text,
body.qodef-header--light .qodef-social-title,
body.qodef-header--light .qodef-custom-styles {
  color: var(--px-cream);
}

/* The card titles and their meta needed MORE SPECIFICITY, not another
   selector. The winning declaration was
       .qodef-portfolio-list.qodef-item-layout--info-on-hover .qodef-e-content
   at (0,3,0) — set on the content wrapper, with the title inheriting from it —
   so `body.qodef-header--light .qodef-e-title-link` at (0,2,1) lost and the
   titles stayed white. Going through .qodef-shortcode (always an ancestor of
   these lists) makes it (0,3,1), which wins without resorting to !important.

   The anchors are listed separately because they do NOT inherit: the theme's
   `a, p a { color: #111 }` beats inheritance, so the author and category links
   need naming in their own right. */
body.qodef-header--light .qodef-shortcode .qodef-e-content,
body.qodef-header--light .qodef-shortcode .qodef-e-content a,
body.qodef-header--light .qodef-shortcode .qodef-e-title-link,
body.qodef-header--light .qodef-shortcode .qodef-e-info-author-label,
body.qodef-header--light .qodef-shortcode .qodef-e-info-author-link,
body.qodef-header--light .qodef-shortcode .swiper-button-text,
body.qodef-header--light .qodef-shortcode .swiper-pagination-current-slide,
body.qodef-header--light .qodef-shortcode .swiper-pagination-total-slides {
  color: var(--px-cream);
}

/* The card families needed their own rules because the theme paints them
   through its `skin--light` flag — its name for "this component sits on a dark
   ground, so print it white" — at (0,4,1):
       .qodef-blog.qodef-skin--light article .qodef-e-inner .qodef-e-title
   which outranks anything routed through .qodef-shortcode. Mirroring the
   theme's own selector shape and prefixing `body` takes it to (0,4,2), which
   wins by one element without `!important`.

   Chasing these one at a time is the wrong instinct: `skin--light` is a whole
   family, so the fix is written against the family. Anything new that still
   comes out white will be a component the theme flags the same way — find its
   rule, mirror its shape, add `body`. */
body .qodef-blog.qodef-skin--light article .qodef-e-inner .qodef-e-title,
body .qodef-blog.qodef-skin--light article .qodef-e-inner .qodef-e-title a,
body .qodef-blog.qodef-skin--light article .qodef-e-inner .qodef-e-excerpt,
body .qodef-blog.qodef-skin--light article .qodef-e-inner .qodef-e-info,
body .qodef-blog.qodef-skin--light article .qodef-e-inner .qodef-e-info-item,
body .qodef-blog.qodef-skin--light article .qodef-e-inner .qodef-e-info-item a,
body .qodef-blog.qodef-skin--light article .qodef-e-inner .qodef-e-read-more,
body .qodef-portfolio-list.qodef-item-layout--info-on-hover .qodef-e-content-inner *,
body .qodef-navigation-skin--light .qodef-e-title-link,
body .qodef-shortcode .qodef-navigation .swiper-button-text,
body .qodef-shortcode .swiper-pagination .swiper-pagination-current-slide,
body .qodef-shortcode .swiper-pagination .swiper-pagination-total-slides {
  color: var(--px-cream);
}

/* The blog index is the METRO layout, which paints its own meta white through
   a third family — not `skin--light` at all:
       .qodef-blog.qodef-item-layout--metro article
         .qodef-e-info.qodef-info--bottom .qodef-e-info-item a      (0,5,2)
   Mirrored with a `body` prefix to reach (0,5,3). Both the --top and --bottom
   info rows are covered because the index uses --top while the cards elsewhere
   use --bottom. */
body .qodef-blog.qodef-item-layout--metro article .qodef-e-info,
body .qodef-blog.qodef-item-layout--metro article .qodef-e-info a,
body .qodef-blog.qodef-item-layout--metro article .qodef-e-info .qodef-e-info-item,
body .qodef-blog.qodef-item-layout--metro article .qodef-e-info .qodef-e-info-item a,
body .qodef-blog.qodef-item-layout--metro article .qodef-e-info.qodef-info--top .qodef-e-info-item,
body .qodef-blog.qodef-item-layout--metro article .qodef-e-info.qodef-info--top .qodef-e-info-item a,
body .qodef-blog.qodef-item-layout--metro article .qodef-e-info.qodef-info--bottom .qodef-e-info-item,
body .qodef-blog.qodef-item-layout--metro article .qodef-e-info.qodef-info--bottom .qodef-e-info-item a {
  color: var(--px-cream);
}

/* --------------------------------------------------------------------------
   2. HEADER — menu centred, and it STAYS clear of the logo
   The header is a flex row of logo / nav / opener. The logo (300px) and the
   opener (~39px) are different widths, so the theme's space-between pushes the
   nav ~118px right of true centre.

   An earlier fix pinned the nav with `position:absolute; left:50%`. That
   centred it, but taking it out of flow meant the logo no longer pushed it:
   the nav is 803px wide, so it starts overlapping the logo as soon as
   (viewport - 803) / 2 < 325, i.e. **below ~1453px** — measured at 87px of
   overlap at 1280 and 214px at 1025. Tablet-width desktop windows had the menu
   sitting on top of the logo.

   The fix is to centre it IN FLOW instead: give the logo and the opener equal
   flex space either side, and the nav lands dead centre by construction. It
   can never overlap, because flex shrinks the flanks rather than letting items
   cross. The nav's own padding then tightens between 1025px and 1500px so all
   three still fit at the narrow end.
   -------------------------------------------------------------------------- */

/* Client asked the logo to sit closer to the screen edge, not just closer
   than the nav (Oct 2026). The equal-flex-flank fix above already puts the
   logo flush against the START of its own flex item -- which starts right
   after the header's own edge padding -- so "closer to the edge" means
   shrinking that padding, not touching the flex logic. Left-only: the right
   edge holds the hamburger opener, which was not part of this request, and
   tightening it was never a problem the client raised.
   Covers all three header states: the static header (#qodef-page-header-inner,
   theme default 25px), the sticky header that appears on scroll
   (.qodef-header-sticky-inner, a DIFFERENT element from pelicula-core with its
   own 40px default) and the mobile header (#qodef-page-mobile-header-inner,
   also 40px default). A first pass took this to 16px, which the client read
   as "didn't move"; a second went to 6px.

   HARD LEFT (client, Oct 2026): 6px went to 0, so the wordmark's own ink
   started at the viewport edge with nothing in front of it -- then the client
   asked for it back a few pixels, so it now sits at --px-logo-inset below.

   THAT ONE VALUE IS THE KNOB. Everything that depends on the logo's distance
   from the edge is expressed in terms of it, including the nav's centring
   compensation further down, so nudging the logo is a one-number edit and
   nothing else has to be recomputed by hand.

   `env(safe-area-inset-left)` is added on top, and only the notched phones that
   report a non-zero inset get anything from it -- it falls back to 0 everywhere
   else, so a desktop window gets exactly the inset asked for while a landscape
   iPhone still keeps the logo clear of the notch. That was the whole reason the
   earlier 6px was never taken to 0 on its own.

   Covers all three header states: the static header (#qodef-page-header-inner,
   theme default 25px), the sticky header that appears on scroll
   (.qodef-header-sticky-inner, a DIFFERENT element from pelicula-core with its
   own 40px default) and the mobile header (#qodef-page-mobile-header-inner,
   also 40px default).

   Padding is NOT sufficient on its own -- see the two theme rules undone
   below, which were between the logo and the edge the whole time. */
#qodef-page-header-inner,
.qodef-header-sticky-inner,
#qodef-page-mobile-header-inner {
  --px-logo-inset: 35px;     /* how far the LOGO sits off the edge */
  --px-header-inset: 25px;   /* what the OPENER side still keeps; see below */
  padding-left: 12px;        /* fallback for no var() support */
  padding-left: calc(var(--px-logo-inset) + env(safe-area-inset-left, 0px));
}

@media only screen and (min-width: 1025px) {
  /* equal flanks => the nav is centred without leaving the flow */
  #qodef-page-header-inner > .qodef-header-logo-link,
  #qodef-page-header-inner > .qodef-widget-holder {
    flex: 1 1 0;
    min-width: 0;
  }

  #qodef-page-header-inner > .qodef-widget-holder {
    display: flex;
    justify-content: flex-end;
    /* the theme puts margin-left:24px here; with equal flanks that asymmetry
       lands the nav exactly half of it (12px) left of centre */
    margin-left: 0;
  }

  #qodef-page-header-inner > .qodef-header-navigation {
    flex: 0 1 auto;
    min-width: 0;
  }

  /* Equal flanks centre the nav on the CONTENT box, which is only the viewport
     centre while the two edge paddings match. They do not: the logo side is
     --px-logo-inset and the opener side keeps the theme's 25px, so the content
     box — and the nav with it — sits half the difference left of true centre.

     An asymmetric chrome cannot centre on the viewport by flex alone, so the
     difference is given back explicitly. A margin-left of (right inset - left
     inset) moves the nav by HALF of it — free space shrinks by the margin and
     the flanks then split the remainder — which is exactly what is owed. It is
     written as that subtraction rather than as a number so the logo inset can
     be nudged without anyone having to recompute this; at the hard-left 0 it
     was the full 25px, and it tracks on its own from here.

     The env() is subtracted too because it is part of the left padding. It is
     0 on every desktop, and this whole block is >=1025px, so in practice it
     only keeps the arithmetic honest rather than changing any real layout.

     TWO ids again: the body carries `qodef-header-standard--center`, and
     pelicula-core's `.qodef-header-standard--center #qodef-page-header-inner
     .qodef-header-navigation{margin-left:auto;margin-right:auto}` is (1,2,0),
     so a single-id rule here computed to 0px and moved nothing. The auto
     margins it sets resolve to 0 anyway once the flanks have grown, which is
     why nothing looked wrong — it just silently ignored the compensation.
     margin-right is pinned too so the pair is stated, not half-inherited. */
  #qodef-page-header #qodef-page-header-inner > .qodef-header-navigation {
    margin-left: calc(var(--px-header-inset) - var(--px-logo-inset)
                      - env(safe-area-inset-left, 0px));
    margin-right: 0;
  }

  /* the theme pins the logo at flex-shrink:0 and a fixed width; let it scale
     down rather than force an overflow */
  #qodef-page-header .qodef-header-logo-link img {
    max-width: 100%;
    object-fit: contain;
  }
}

/* --------------------------------------------------------------------------
   LOGO HARD LEFT — the two theme rules that actually held it off the edge

   Shrinking the header's padding (above) moves the logo's BOX. It did not move
   the logo, because on desktop the artwork was sitting 106px inside that box,
   for two separate reasons that stack. Measured at 1440: the link starts at
   x=6 and the ink started at x=112.

   1. THE VISIBLE IMG IS NOT THE ONE IN FLOW. The theme ships three copies of
      the logo — .qodef--main, .qodef--dark, .qodef--light — and cross-fades
      between them with opacity. Only --main is in flow; the other two are
      `position:absolute; left:0`, and under `body.qodef-header--light` (which
      is the skin this site uses on the dark pages) pelicula-core re-pins them
      to `left:50%; translateX(-50%)` — CENTRED in the link. Normally harmless,
      because the theme's link is only as wide as the logo. Here the header
      centring fix above gives the link `flex:1 1 0`, so it is ~357px wide at
      1440, and centring the 178px image inside it threw the visible copy 89px
      right. The copy sitting correctly at the edge was --main, at opacity 0.

      So this is invisible to a spot check: inspect the element, read x=6,
      screenshot it, and the logo is 112px in. The element you measured is not
      the element you can see.

   2. OBJECT-FIT WAS LETTERBOXING THE REST. `.qodef-height--not-set img` is
      `width:50%` in the theme — again sized against that now-huge link, giving
      a 178px box for artwork that is only 144px wide at a 48px cap height.
      `object-fit:contain` (ours, just above) then centred the art in the extra
      34px, for another 17px of gap. Setting the box back to `width:auto` makes
      it hug the art, after which contain has nothing left to centre.

   Both are scoped to the desktop header: the mobile and sticky headers set
   their own logo height, so `qodef-height--not-set` never applies there and
   their --main copy was already flush.
   -------------------------------------------------------------------------- */
@media only screen and (min-width: 1025px) {
  /* TWO ids, deliberately. pelicula-core's rule is
       .qodef-header--light #qodef-page-header .qodef-header-logo-link img:not(.qodef--main):not(.qodef--sticky)
     which is (1,4,1) — four classes, counting both :not() arguments. A single-id
     copy of the same selector with `body` in front is (1,3,2) and LOSES, which
     is how the first attempt at this silently did nothing. Adding
     #qodef-page-header-inner takes it to (2,3,2) and id count settles it.

     That second id also scopes this to the static header on purpose: the sticky
     header is a sibling inner with its own logo link, which the equal-flex-flank
     rule above never widened, so its copies centre inside a box that already
     hugs the artwork and are flush as they are. */
  #qodef-page-header #qodef-page-header-inner .qodef-header-logo-link img:not(.qodef--main):not(.qodef--sticky) {
    left: 0;
    transform: translateY(-50%);
  }

  #qodef-page-header #qodef-page-header-inner .qodef-header-logo-link.qodef-height--not-set img {
    width: auto;
  }
}

/* Between 1025 and 1500 the three items cannot all sit at full size — at
   1025px the nav alone is 803px against a 300px logo. Tighten the nav's item
   padding across that range so everything fits without the logo shrinking.

   Client asked for the menu to read more compact generally (Oct 2026), so the
   same tightened padding is now applied at EVERY desktop width, not just this
   narrow range — the theme's own default is a flat 31px/side regardless of
   viewport, which is what made the menu feel loose on wide screens too. The
   ceiling is lowered from 31px to 22px; the narrow end of the clamp (9px) is
   unchanged since that was already the tightest it can go before labels
   touch. */
@media only screen and (min-width: 1025px) {
  .qodef-header-navigation > ul > li {
    padding: 0 clamp(9px, 1.3vw, 22px);
  }
}

/* The theme renders the logo at a FIXED 100px tall (~300px wide) at every
   desktop width, 1025px up to 4K alike — there is no breakpoint of its own.
   Two prior passes (100 -> 60-85 -> 42-62) were both still "too big" by eye,
   so this one is anchored to a real measurement instead of another guess:
   the nav links render at 17px Bebas Neue, a 12px CAP height (ascent 16,
   descent 6, cap 12 -- the same figure already measured for the active-page
   mark's strike position elsewhere in this file). Inside the logo's own
   300x100 artwork "PIXELS" occupies the top 72% of the canvas and
   "PRODUCTION" the bottom 19% (measured for the preloader write-on), so at
   any rendered height H the wordmark itself is ~0.72*H tall. The previous
   62px ceiling put PIXELS at ~45px -- 3.7x the nav's cap height, which reads
   as oversized next to single-line nav text. 48px puts PIXELS at ~35px,
   closer to 2.8x -- still clearly the dominant mark (it's the logo), but no
   longer fighting the nav for visual weight. PRODUCTION shrinks along with
   it, to ~9px -- smaller than the nav text but still legible as a tagline,
   not the thing anyone is meant to read first. */
@media only screen and (min-width: 1025px) {
  #qodef-page-header .qodef-header-logo-link {
    height: clamp(32px, 4vw, 48px);
  }
}

/* --------------------------------------------------------------------------
   3. NAVIGATION — red mark on the active page
   An earlier round painted a navy box behind the hovered item; the client has
   since asked for it to go, so HOVER IS THE THEME'S OWN again: a 1px rule in
   currentColor that sweeps across the label
   (`> a:hover > span:before { transform: scaleX(1) }`). Because it is
   currentColor it stays legible on both templates — cream on the dark pages,
   #111 on the light single-post header.

   Three rules went with the box and must NOT come back on their own:
     * position:relative on the <li>, which only existed to be the box's
       containing block (the theme leaves the <li> static, and this nav has no
       dropdowns that would need it),
     * position/z-index on the <a>, to lift the label above the box — the theme
       already sets position:relative on both the <a> and its <span>, and the
       <span> is what the mark is measured against,
     * a forced cream hover label, which only existed so #111 text would not
       vanish against the navy. Without the box that rule would paint cream on
       the white header and make the hovered item invisible.
   -------------------------------------------------------------------------- */

/* ACTIVE PAGE: the mark turns cream (the label keeps its own colour).
   Two ids to outrank the theme's own `.qodef-header--light ... !important`. */
body #qodef-page-header #qodef-page-header-inner
  .qodef-header-navigation > ul > li.current-menu-item > a > span:before,
body #qodef-page-header #qodef-page-header-inner
  .qodef-header-navigation > ul > li.current_page_item > a > span:before,
body #qodef-page-header #qodef-page-header-inner
  .qodef-header-navigation > ul > li.px-current > a > span:before {
  background-color: var(--px-cream) !important;
  transform: scaleX(1) !important;
  height: 2px;            /* theme draws it at 1px */

  /* Strike through the OPTICAL middle of the caps, not the middle of the line
     box. Those are not the same place and the gap is visible.

     Measured on the live nav at 17px Bebas Neue: ascent 16, descent 6, cap
     height 12, line-height 26. So half-leading is (26-22)/2 = 2, the baseline
     sits 18 down, the caps run 6..18, and their centre is 12 — while the line
     box centre is 13. Bebas is uppercase-only, so the descent is space the
     text never uses, and `top: 50%` drops the rule below the glyphs.

     The correction is (ascent - descent - capHeight) / 2, which cancels
     line-height entirely and so holds at every breakpoint:
       (16 - 6 - 12) / 2 = -1px at 17px = -0.059em.
     The extra -1px is half the rule's own 2px height, to centre the bar
     itself rather than hang it from its top edge. */
  top: calc(50% - 0.059em - 1px);
}

/* mobile menu gets the same active colour */
.qodef-mobile-header-navigation li.current-menu-item > a,
.qodef-mobile-header-navigation li.px-current > a {
  color: var(--px-red);
}

/* --------------------------------------------------------------------------
   3b. SIDE-AREA MENU — the slide-out panel's link list
   #menu-main-menu-pj-5 is the nav widget inside #qodef-side-area. The theme
   gives its items no vertical rhythm at all, so the links sit almost on top of
   each other.
   -------------------------------------------------------------------------- */

/* Measured with the panel actually open at 1600x900: six items, each <li>
   33px of text (22px/1.5) plus 9px top and bottom, so a 51px pitch and only
   18px of air between links. The whole list spanned 327->633, which is 306px
   of a 900px panel — 327px empty above it and 267px below. There is plenty of
   room, so the spacing is roughly doubled.

   Still expressed as a vh clamp rather than a fixed value, because this panel
   is full-height and the list has to survive a short viewport (a landscape
   phone, a 13" laptop with browser chrome). At the 2.6vh rate the list is
   ~479px tall at 900px, ~416px at 700px and ~354px at 500px — comfortable at
   every one. The 26px ceiling stops it sprawling on a tall desktop display. */
#qodef-side-area .widget_nav_menu ul.menu > li,
#qodef-side-area-inner ul.menu > li {
  margin: 0;
  padding: clamp(12px, 2.6vh, 26px) 0;
}

#qodef-side-area .widget_nav_menu ul.menu > li > a,
#qodef-side-area-inner ul.menu > li > a {
  display: inline-block;
  line-height: 1.5;
}

/* Safety net: if the panel ever does run out of height — more menu items, a
   very short viewport — let it scroll rather than clip the last link. */
#qodef-side-area-inner {
  max-height: 100%;
  overflow-y: auto;
}

/* --------------------------------------------------------------------------
   3c. LINKEDIN — removed site-wide (client request, Oct 2026)
   Two real "follow us" instances: the home-hero icon stack (Slider Revolution
   content) and the Contact page's social row. #SR7_13_1-34-7 is that hero
   icon's own layer-wrapper id — stable because it is derived from the
   slide/layer ids baked into the SR7 JSON config, which is NOT touched here
   (see README's warning about hand-editing that escaped JSON blob; one bad
   substitution there can silently kill the whole slider). Hiding the layer
   leaves a slightly larger gap in the vertical icon stack (Instagram to
   Clutch becomes one ~80px step instead of two ~40px ones) rather than risk
   repositioning inside SR7's own absolute-position system.

   The per-post "share this to LinkedIn" dropdown buttons on blog templates
   are deliberately NOT touched — different feature (sharing a post vs.
   following the company), different URL shape
   (…/sharing/share-offsite?url=…, not …/company/pixelsjo), and already
   called out in README as a correct leftover. */
#SR7_13_1-34-7,
a[href="https://www.linkedin.com/company/pixelsjo"] {
  display: none !important;
}

/* Repositioning Clutch in the hero icon stack (client follow-up, Oct 2026:
   Clutch should read BEFORE Instagram, i.e. above it in the stack, and the
   gap LinkedIn left behind needs to close). Each icon's REAL positioned
   element is not the id'd <sr7-txt> itself (that one is position:relative
   with no offset) -- it's the <sr7-mask> parent SR7 wraps it in, which
   carries the actual `position:absolute` box as an INLINE style written
   straight from the slider's JSON config. That wrapper has no id or class of
   its own, so it has to be reached relative to the id it DOES carry a child
   of, via :has() -- already used elsewhere on this site (html:has(.px-pre)
   above). !important is required because an inline style otherwise always
   wins; it is safe here because SR7 sets these inline values as plain
   (non-!important) strings, so this rule keeps winning even if the slider
   re-asserts them on resize.

   bottom, not top. All four icons were originally authored bottom-anchored
   (pos.v:"bottom" in the JSON) stepping 40/80/120/160px up from the bottom
   edge -- YouTube/Instagram/LinkedIn/Clutch in that order -- which is what
   keeps their spacing correct at ANY viewport height, since <sr7-content>'s
   own height is resized by SR7's JS to match the actual viewport. A first
   attempt here overrode `top` with a HARD-CODED pixel value (866px):
   measured correct at the one viewport height it was tested against, but
   wrong at every other height, since top is measured from the opposite,
   fixed edge -- exactly the kind of bug that looks fine in one screenshot
   and broken for a real visitor. bottom is the right property to drive.

   Why not just set `bottom` alone, the way a first-first attempt did: that
   left the inline `top` from SR7 ALSO present, and with both top and bottom
   set and height:auto, the box STRETCHES to fill the space between them
   instead of moving -- and because the mask is `rotate(-90deg)`, that
   stretched height renders as extra WIDTH after rotation, which shoved the
   icon to the wrong edge of its own oversized box. `top: auto` cancels the
   old inline value so bottom is the only thing driving the box, exactly like
   the other untouched icons.

   120px reuses LinkedIn's own original slot -- the step directly above
   Instagram's 80px -- so Clutch lands exactly one 40px rhythm above it
   (reads "before" Instagram top-to-bottom) with no leftover gap, and holds
   at every viewport height because it is the same bottom-anchoring the
   other three icons already use. */
sr7-mask:has(> #SR7_13_1-34-8) {
  top: auto !important;
  bottom: 120px !important;
}

/* --------------------------------------------------------------------------
   4. SIDE INDICATORS — the two opener lines, white -> red -> cream
   -------------------------------------------------------------------------- */

.qodef-opener-icon .qodef-m-line,
.qodef-side-area-opener .qodef-m-line,
#qodef-side-area-close .qodef-m-line {
  background-color: var(--px-cream) !important;
}

/* the mobile header draws the same two-line opener as an inline SVG with a
   hardcoded fill, so it needs its own rule */
.qodef-mobile-header-opener svg path,
.qodef-mobile-header-opener svg polygon {
  fill: var(--px-cream) !important;
}

/* the sticky back-to-top arrow on the right edge */
.qodef-sticky-right .qodef-icon-elegant-icons,
#qodef-back-to-top .qodef-icon-elegant-icons,
.qodef-back-to-top .qodef-icon-elegant-icons {
  color: var(--px-cream) !important;
}

/* --------------------------------------------------------------------------
   5. CLIENT LOGO CAROUSEL — no prev/next, no counter
   The markup is injected by Qode's swiper init at runtime, so these are
   belt-and-braces alongside the JS removal in pixels-edits.js.
   -------------------------------------------------------------------------- */

.elementor-widget-pelicula_core_clients_list .qodef-navigation,
.elementor-widget-pelicula_core_clients_list .swiper-button-next,
.elementor-widget-pelicula_core_clients_list .swiper-button-prev,
.elementor-widget-pelicula_core_clients_list .swiper-pagination,
.elementor-widget-pelicula_core_clients_list .swiper-pagination-current-slide,
.elementor-widget-pelicula_core_clients_list .swiper-pagination-total-slides,
.px-clients-holder .qodef-navigation,
.px-clients-holder .swiper-button-next,
.px-clients-holder .swiper-button-prev,
.px-clients-holder .swiper-pagination {
  display: none !important;
}

/* reclaim the space the counter column used to occupy */
.elementor-widget-pelicula_core_clients_list .qodef-grid-inner {
  width: 100%;
}

/* --------------------------------------------------------------------------
   6. HIGHLIGHTED WORDS — the brand's mark
   The brand does NOT emphasise by turning a word red. It knocks the word out
   of a solid BLOOD block and slants it — "WHO /WE ARE./" on company profile
   p3 — and uses the slant on its own where a block would be too heavy
   ("WORK /PROCESS./", p15). So the mark here is: Blood block, cream knockout,
   italic.

   Geometry started from that lockup, where the block is 1.22x the cap height
   and starts 0.12 cap-heights above the cap line. Bebas Neue metrics: cap
   0.711em, ascent 0.956em, so the cap line sits 0.245em below the content-box
   top and the baseline 0.956em below it.

   These ARE the measured reference values — the block was opened up over two
   rounds and then brought back here at the client's request:
       above cap      0.086em  =>  top    = 0.245 - 0.086 = 0.159em
       below baseline 0.070em  =>  height = (0.956 + 0.070) - 0.159
                                          = 0.867em  (1.22x cap)
       sides          0.08em left / 0.10em right
   Keep all four moving together or the word stops looking optically centred
   in the block.
   Do NOT "correct" these back to the 1.22x reference — the looseness is
   deliberate.

   To resize: pick the padding you want above the cap and below the baseline,
   then re-derive top and height with the two formulas above. Changing
   background-size alone just stretches the block off-centre. Nothing clips it
   — every ancestor is overflow:visible — so it is free to grow.

   Painted as a background-image, not a pseudo-element: the theme wraps each
   animated word in an overflow:hidden span, which would clip an absolutely
   positioned block. box-decoration-break keeps the block whole if the mark
   ever wraps across two lines.
   -------------------------------------------------------------------------- */

.px-accent,
.px-mark {
  --px-mark-fill: var(--px-blood);
  background-image: linear-gradient(var(--px-mark-fill), var(--px-mark-fill));
  background-repeat: no-repeat;
  background-size: 100% 0.867em;
  background-position: 0 0.159em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  padding: 0 0.1em 0 0.08em;   /* a touch more on the right: the synthesised
                                  oblique leans the last glyph outward */
  color: var(--px-cream) !important;
  font-style: italic;
}

/* Bebas Neue ships no italic, so the browser synthesises the oblique. That is
   fine for a geometric condensed face, but it does not re-space the glyphs —
   hence the asymmetric padding above rather than a symmetric box. */

/* The theme's JS re-splits every .qodef-m-title into per-word spans for its
   reveal animation, throwing away any markup nested inside the heading. The
   static .px-accent span therefore cannot survive inside a heading, so
   pixels-edits.js re-wraps the target word as .px-mark after each split.
   .px-accent above still covers the headings the theme does not touch
   (Contact, Our Work), where the span is left alone. */

/* NAVY variant of the mark — same block, different fill.
   Used on "visuals" in the Showreel heading on the home page.

   HEADS UP: that heading sits on a near-black ground (~#0C0C0A), and NAVY
   against it is 1.14:1, so the block itself is all but invisible — the word
   reads, because cream on NAVY is 12.99:1, but the highlight does not announce
   itself the way the BLOOD one does. This is what was asked for. If it needs
   to actually show, --px-mark-fill is the single knob:
       var(--px-navy-line)  #222855  1.40:1   (still very quiet)
       var(--px-electric)   #1A43F3  2.93:1   (reads, and is brand)
   BLOOD is 2.45:1 on the same ground for reference. */
.px-accent-navy,
.px-mark--navy {
  --px-mark-fill: var(--px-navy);
}

/* STRIKETHROUGH. The theme emphasises a word by wrapping it in
   .qodef-custom-styles, which pelicula-core styles as
   `text-decoration: line-through` — that is where the rule through "visuals"
   comes from. The title-split throws that span away along with everything else
   nested in the heading, and the .px-mark the JS builds in its place does not
   inherit it, so the strike has to be re-applied here.
   Driven by data-px-mark-strike on the heading, so it lands only on words that
   had it — TRUSTED, 2019, "to make" and "films" are not struck through. */
.px-mark--strike {
  text-decoration: line-through;
}

/* --------------------------------------------------------------------------
   6b. CLUTCH ICON
   Clutch isn't in Elegant Icons / Ionicons / FontAwesome, so it ships as an
   inline SVG. Sized in em so it matches the icon-font glyphs beside it
   whatever font-size the slider layer sets.
   -------------------------------------------------------------------------- */

.px-icon-clutch {
  display: inline-block;
  line-height: 1;
  vertical-align: middle;
}

.px-icon-clutch .px-clutch-svg {
  width: 1.05em;
  height: 1.05em;
  display: block;
  color: inherit;
  transition: color 0.25s ease;
}

.px-icon-clutch:hover .px-clutch-svg {
  color: var(--px-red);
}

/* --------------------------------------------------------------------------
   6c. EDITORIAL POST BODY (the five new blog articles)
   Measured column + real subheads, so a long read stays readable instead of
   running the full content width like the imported lorem posts did.
   -------------------------------------------------------------------------- */

/* NOTE: single posts render on the LIGHT template (white page, #111 headings,
   #7a7a7a body). These colours deliberately match that template, not the cream
   used on the dark pages. */

.px-post-body {
  max-width: 44em;
}

.px-post-body p {
  color: #7a7a7a;
  margin: 0 0 1.5em;
  line-height: 1.85;
}

/* standfirst: the opening paragraph carries a little more weight */
.px-post-body p:first-child {
  color: #4a4a4a;
  font-size: 1.12em;
  line-height: 1.7;
}

.px-post-h3 {
  color: #111111;
  margin: 2.4em 0 0.75em;
  letter-spacing: 0.02em;
}

.px-post-h3:first-child {
  margin-top: 0;
}

/* --------------------------------------------------------------------------
   7. CONSISTENCY PASS
   -------------------------------------------------------------------------- */

/* selection + focus in brand colours rather than browser blue */
::selection { background: var(--px-red); color: var(--px-cream); }
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--px-red);
  outline-offset: 3px;
}

/* the theme leaves a hairline of pure white on footer/section dividers */
#qodef-page-footer-bottom-area {
  border-top-color: rgba(226, 224, 215, 0.12) !important;
}

/* consistent page-title block spacing across all templates */
.qodef-page-title .qodef-m-content {
  padding-top: 0;
}

/* --------------------------------------------------------------------------
   8. CTA BUTTONS — hover fills with BLOOD
   See _build-scripts/48_cta_hover.py for the half of this that is NOT CSS.
   Short version: the label and border colours on hover are written as INLINE
   styles by qi-addons' JS from the element's data-hover-* attributes, so they
   are set there, not here. What belongs here is the fill and a fallback.
   -------------------------------------------------------------------------- */

/* The fill is a panel parked below the button that slides up on hover. The
   theme paints it #fff for the outlined skin; this is the one declaration that
   actually changes what the hover looks like. */
.qodef-button.qodef-layout--with-bg-holder.qodef-layout--outlined .qodef-btn-bg-holder,
.qodef-button.qodef-layout--with-bg-holder.qodef-layout--outlined.qodef-skin--light .qodef-btn-bg-holder {
  background-color: var(--px-blood);
}

/* Fallback for the label/border if the addon JS never runs — without it a
   no-JS hover would leave black-on-blood from the theme's own rule. Cream on
   blood measures 6.1:1. */
.qodef-button.qodef-layout--outlined:hover,
.qodef-button.qodef-layout--outlined:hover.qodef-skin--light {
  color: var(--px-cream);
  border-color: var(--px-blood);
}

/* The textual CTAs ("Read More", "Contact Us") had NO hover state at all —
   measured, colour and border were identical at rest and on hover. They are
   links that look like buttons, so they get the same blood cue rather than a
   fill they have no box for. */
.qodef-button.qodef-layout--textual:hover,
.qodef-button.qodef-layout--textual:hover .qodef-m-text,
body.qodef-header--light .qodef-button.qodef-layout--textual:hover .qodef-m-text {
  color: var(--px-blood);
}

/* the theme draws a rule under the textual label; move it with the text */
.qodef-button.qodef-layout--textual:hover .qodef-m-text:after,
.qodef-button.qodef-layout--textual:hover .qodef-m-text:before {
  background-color: var(--px-blood);
}

/* --------------------------------------------------------------------------
   9. ULTRA-WIDE SCREENS (2560px and up)
   46_responsive.py only ever walked 320-1440px, so nothing above that had
   been checked. Audited at 1600/1920/2560/3440/3840 with headless Chrome:
   every page is clean (0 boxes crossing the viewport edge) at all five except
   one real bug, below. Everything else on the site is full-bleed video or a
   flex/grid layout that already scales, so it needed no further constraint.
   -------------------------------------------------------------------------- */

/* home, "What Our Clients Say / Showreel": the section's background-image
   (port23o.jpg, wired up in 51_abs_urls.py) was only ever given a URL in the
   Elementor-generated CSS -- background-size and background-repeat were left
   at their CSS defaults (auto / repeat). That is invisible as long as the
   section is narrower than the image itself, which it always was at every
   width this site had been tested at (<=1440, and still only a sliver would
   peek through up to ~1920). At 2560 the section is wider than the image, so
   the default repeat tiles it -- two full copies side by side, three at 3840.
   Cover + no-repeat is the fix at every width, including the ones already
   verified clean. Scoped to the one Elementor element id (home-page only) so
   nothing else with a legitimately tiled background is touched. */
.elementor-element.elementor-element-4e029f6 {
  background-size: cover !important;
  background-repeat: no-repeat !important;
  background-position: center center !important;
}
