:root {
    /* Global Padding Variables - Editable */
    /* Left and Right Padding All /Sections/Containers*/
    --fluid-side-padding-min: 1.25rem; /* 20px */
    --fluid-side-padding-max: 5rem;   /* 80px */

    /* Top and Bottom Padding All Containers*/
    --section-xxl-padding-min: 9.375rem; /* 150px */
    --section-xxl-padding-max: 10rem; /* 160px */

    --section-xl-padding-min: 6.875rem; /* 110px */
    --section-xl-padding-max: 7.5rem; /* 120px */

    --section-l-padding-min: 5.625rem; /* 90px */
    --section-l-padding-max: 6.25rem; /* 100px */

    --section-m-padding-min: 5rem; /* 80px */
    --section-m-padding-max: 5rem; /* 80px */

    --section-s-padding-min: 3.75rem; /* 60px */
    --section-s-padding-max: 3.75rem; /* 60px */

    --section-xs-padding-min: 2.5rem; /* 40px */
    --section-xs-padding-max: 2.5rem; /* 40px */

    --section-xxs-padding-min: 1.5rem; /* 20px */
    --section-xxs-padding-max: 1.5rem; /* 20px */

    --section-header-padding-min: 1.25rem; /* 20px */
    --section-header-padding-max: 1.25rem; /* 20px */


    /* Hero Sections Height Variable */
    --section-hero-height: 100vh; /* 100% the screen height */

    /* Offset Padding for Overlay Headers */
    --section-offset-header: 80px; /* Adjust to the overlay header's negative margin */

    /* Width For Narrow Sections*/
    --section-narrow: 62.5rem; /* 1000px */
    --section-narrow-xs: 45rem; /* 720px */
  }


/* CSS Template (do not edit below) */


  /* Section/Container Padding - Fluid Variants */
  .section-xxl {
    padding-top: clamp(var(--section-xxl-padding-min), 1.087vw + 9.13rem, var(--section-xxl-padding-max));
    padding-bottom: clamp(var(--section-xxl-padding-min), 1.087vw + 9.13rem, var(--section-xxl-padding-max));
    padding-left: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
    padding-right: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
  }

  .section-xl {
    padding-top: clamp(var(--section-xl-padding-min), 1.087vw + 6.63rem, var(--section-xl-padding-max));
    padding-bottom: clamp(var(--section-xl-padding-min), 1.087vw + 6.63rem, var(--section-xl-padding-max));
    padding-left: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
    padding-right: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
  }

  .section-l {
    padding-top: clamp(var(--section-l-padding-min), 1.087vw + 5.38rem, var(--section-l-padding-max));
    padding-bottom: clamp(var(--section-l-padding-min), 1.087vw + 5.38rem, var(--section-l-padding-max));
    padding-left: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
    padding-right: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
  }

  .section-m {
    padding-top: clamp(var(--section-m-padding-min), 0vw + 5rem, var(--section-m-padding-max));
    padding-bottom: clamp(var(--section-m-padding-min), 0vw + 5rem, var(--section-m-padding-max));
    padding-left: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
    padding-right: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
  }

  .section-s {
    padding-top: clamp(var(--section-s-padding-min), 0vw + 3.75rem, var(--section-s-padding-max));
    padding-bottom: clamp(var(--section-s-padding-min), 0vw + 3.75rem, var(--section-s-padding-max));
    padding-left: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
    padding-right: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
  }

  .section-xs {
    padding-top: clamp(var(--section-xs-padding-min), 0vw + 2.5rem, var(--section-xs-padding-max));
    padding-bottom: clamp(var(--section-xs-padding-min), 0vw + 2.5rem, var(--section-xs-padding-max));
    padding-left: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
    padding-right: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
  }

  .section-xxs {
    padding-top: clamp(var(--section-xxs-padding-min), 0vw + 1.5rem, var(--section-xxs-padding-max));
    padding-bottom: clamp(var(--section-xxs-padding-min), 0vw + 1.5rem, var(--section-xxs-padding-max));
    padding-left: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
    padding-right: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
  }

  .section-header {
    padding-top: clamp(var(--section-header-padding-min), 0vw + 1.25rem, var(--section-header-padding-max));
    padding-bottom: clamp(var(--section-header-padding-min), 0vw + 1.25rem, var(--section-header-padding-max));
    padding-left: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
    padding-right: clamp(var(--fluid-side-padding-min), 6.522vw + -0.217rem, var(--fluid-side-padding-max))!important;
  }

  /* Hero Container/Sections Height */
  .section-hero {
    min-height: var(--section-hero-height)!important;
  }

  .section-hero .e-con-inner {
    justify-content: center!important;
}

  /* Full Width Sections - No Side Padding */

  .section-full div {
    max-width: 100%!important;
  }


  /* Narrow Sections */
  .section-narrow .e-con-inner {
    max-width: var(--section-narrow)!important;
  }

  .section-narrow-xs .e-con-inner {
    max-width: var(--section-narrow-xs)!important;
  }


  /* Offset Padding for Overlay Headers */
  .section-offset {
    padding-top: calc(var(--section-offset-header) + var(--section-xxl-padding-min));
  }

/* Added by Nova, 2026-08-17: Elementor's sticky-header script inserts a
   placeholder div (.elementor-sticky__spacer) at runtime to hold the header's
   space once it goes fixed. That placeholder is `visibility: hidden`, which
   means it can NEVER paint a background color no matter what we set here —
   so this rule alone did nothing (confirmed via a real DevTools inspection,
   not guessed). The actual source of the white sliver is the plain white
   <body> showing through wherever nothing else paints over it — most
   visibly in the space the spacer reserves at the very top of the page.
   Fixing it at the source instead: give <body> itself a navy base so any
   such gap reads as navy, regardless of which layered element is or isn't
   painting correctly above it. */
body {
  background-color: #031233;
}
.elementor-sticky__spacer {
  background-color: #031233 !important;
}

/* Added by Nova, 2026-08-17: the theme's auto-generated .entry-title (plain
   page/post title, separate from each page's real styled heading) is meant
   to stay invisible everywhere via .entry-title{display:var(--page-title-display)}
   — but that variable is undefined, and it was showing through as visible
   text above the featured image on the blog posts. Hiding it outright
   instead of relying on an undefined CSS variable to do it. */
.entry-title {
  display: none !important;
}

/* Added by Nova, 2026-08-17: the Services/Work nav dropdowns rely entirely on
   Elementor's JS to show/hide the submenu (there's no CSS :hover rule doing
   it) — so any JS init issue takes the whole dropdown down site-wide with
   no fallback. Making the desktop submenu open on pure CSS :hover/:focus
   instead removes that JS dependency entirely. Scoped narrowly (both
   .sub-menu AND .elementor-nav-menu--dropdown, direct child of a hovered
   .menu-item-has-children) so it does not touch the separate mobile burger
   flyout, which uses the .elementor-nav-menu--dropdown class differently. */
li.menu-item-has-children:hover > ul.sub-menu.elementor-nav-menu--dropdown,
li.menu-item-has-children:focus-within > ul.sub-menu.elementor-nav-menu--dropdown {
  display: block !important;
}

/* Added by Nova, 2026-08-17: the dropdown box itself has no width rule
   anywhere in Elementor's own CSS (position:absolute with no width/left/right),
   so longer items like "Graphic & Brand Design Portfolio" were overrunning
   the white box instead of it sizing to fit. Sizing it to its own content
   fixes that regardless of how the underlying constraint was happening. */
ul.sub-menu.elementor-nav-menu--dropdown {
  width: max-content;
  max-width: 320px;
  margin-top: 0 !important;
  z-index: 999999 !important;
}
/* Added by Nova, 2026-08-17: footer screenshot (footer-menu.jpg) showed the
   other footer links (Work, Process, About, Insights) painting on top of
   the open dropdown instead of behind it — a stacking-order problem, not a
   visibility one. Giving the trigger <li> its own explicit stacking context
   only while its dropdown is open guarantees it (and its dropdown child)
   wins over sibling links regardless of whatever implicit stacking those
   siblings have. */
li.menu-item-has-children {
  position: relative;
}
li.menu-item-has-children:hover,
li.menu-item-has-children:focus-within {
  z-index: 999999;
}

/* Added by Nova, 2026-08-17: same "menu disappears" bug reported again, this
   time in the footer's nav-menu widget (id 9c92a6d — a separate widget
   instance from the header's, so the header-only margin-top fix above never
   reached it). Its dropdown has no widget-specific margin-top rule at all,
   which most likely means it was falling through to the browser's own
   default <ul> margin — an unpredictable, unstyled gap, same dead-zone
   problem either way. The generic rule just above now zeroes it universally
   for any .sub-menu.elementor-nav-menu--dropdown, header, footer, or
   anywhere else this pattern is used, rather than patching one widget ID at
   a time as each one gets reported. */

/* Added by Nova, 2026-08-17: Elementor's own CSS puts a 22px margin-top
   (!important, so it needs matching specificity to beat) between the nav
   link and the dropdown box. That gap is a dead zone for :hover — moving
   the cursor straight down from the link to the dropdown crosses space that
   belongs to neither element, so hover breaks and the menu closes before
   the cursor arrives. Closing the gap removes the dead zone entirely. */
.elementor-element-30a8d57 .elementor-nav-menu--main > .elementor-nav-menu > li.menu-item-has-children > ul.sub-menu.elementor-nav-menu--dropdown {
  margin-top: 0 !important;
}

/* Added by Nova, 2026-08-17: replaces Elementor's JS-driven "fadeIn on load"
   entrance animation with a pure-CSS one. Elements marked .elementor-invisible
   (the header on every page, FAQ accordions on 5 pages — 31 instances total,
   audited directly) previously stayed permanently `visibility:hidden` unless
   a JS module ran to reveal them: a single point of failure with zero
   fallback if that script ever didn't execute for a visitor. A CSS
   @keyframes animation runs the instant the element paints, handled by the
   browser's rendering engine directly — nothing to fail to load. Same fade
   effect, no JS dependency. Respects prefers-reduced-motion. */
@keyframes pt-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.elementor-invisible {
  visibility: visible !important;
  opacity: 0;
  animation: pt-fade-in 0.6s ease-out forwards;
}
@media (prefers-reduced-motion: reduce) {
  .elementor-invisible {
    animation: none;
    opacity: 1;
  }
}

/* Added by Nova, 2026-08-17: pure-CSS autoplay review carousel, replacing
   the broken Trustindex widget. Shows 3 cards, slides right-to-left one
   card at a time, loops seamlessly (the track holds the 10 real reviews
   plus an exact duplicate set — sliding to position 10 shows the same 3
   cards as position 0, so the loop restart is invisible). No JS: the
   @keyframes animation runs on paint, pauses on hover so it can be read,
   and freezes on prefers-reduced-motion. */
:root {
  --pt-card-w: 270px;
}
/* Added by Nova, 2026-08-17: right-aligned wrapper holding the "leave a
   review" badge image on the left and the carousel on the right. Row on
   desktop, pushed to the right edge of its section; stacks and centers on
   narrow screens where side-by-side no longer fits. */
.pt-reviews-wrap {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 24px;
  width: 100%;
}
.pt-reviews-badge {
  flex: 0 0 auto;
  display: block;
  width: 220px;
  max-width: 40vw;
  height: auto;
  border-radius: 12px;
}
@media (max-width: 700px) {
  .pt-reviews-wrap {
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
  .pt-reviews-badge {
    width: 200px;
    max-width: 70vw;
  }
}
.pt-reviews-viewport {
  overflow-x: auto;
  overflow-y: hidden;
  width: calc(var(--pt-card-w) * 3 + 16px * 2);
  max-width: 100%;
  cursor: grab;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Added by Nova, 2026-08-18: fixes "massive space to the right" — a real
     sitewide horizontal-scroll bug on all 5 pages carrying this carousel,
     confirmed live via a real browser (Playwright), not guessed from CSS.
     The 2026-08-17 min-width:0 fix (on this element and on .e-con/.e-con-inner)
     was real but incomplete: even with min-width:0 correctly shrinking this
     element's own rendered box to 842px (confirmed via getComputedStyle/
     getBoundingClientRect) and overflow-x:auto correctly containing the
     24-card, 6848px-wide track internally, the browser's *scrollable-overflow*
     calculation for ancestors (document.documentElement.scrollWidth) still
     counted the full unclipped track width, not the item's visible box —
     bisection-confirmed by toggling this exact element and nothing else
     (before: 7175px on a 1920px viewport; after removing it: 1905px).
     Neither overflow:hidden nor justify-content changes on the parent
     .pt-reviews-wrap stopped it. `contain: layout` is the correct, targeted
     fix: it makes this element's internal layout fully opaque to ancestors
     for scrollable-overflow purposes without changing anything about how it
     renders or scrolls (verified visually unchanged, live). */
  contain: layout;
}
.pt-reviews-viewport::-webkit-scrollbar {
  display: none;
}
.pt-reviews-viewport.pt-dragging {
  cursor: grabbing;
}
.pt-reviews-viewport.pt-dragging .pt-reviews-track {
  user-select: none;
}
@media (max-width: 900px) {
  :root { --pt-card-w: 240px; }
  .pt-reviews-viewport {
    width: calc(var(--pt-card-w) * 2 + 16px);
  }
}
@media (max-width: 600px) {
  :root { --pt-card-w: 86vw; }
}
.pt-reviews-track {
  display: flex;
  gap: 16px;
  width: max-content;
}
.pt-review-card {
  flex: 0 0 auto;
  width: var(--pt-card-w);
}
/* Added by Nova, 2026-08-17: "Read more" for long review text, pure CSS
   (checkbox-toggle technique) — no JS. The checkbox sits before the text
   and label in the DOM so :checked can reach both via the general sibling
   combinator. Clamps to 4 lines by default; toggling reveals the rest and
   swaps the label text via ::before content. */
.pt-rm-toggle {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.pt-review-text {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pt-rm-toggle:checked ~ .pt-review-text {
  -webkit-line-clamp: unset;
  overflow: visible;
}
.pt-read-more {
  display: inline-block;
  cursor: pointer;
  color: #3366FF;
  font-family: 'DM Sans', Sans-serif;
  font-weight: 600;
  font-size: 12px;
  margin-top: -4px;
}
.pt-read-more::before {
  content: "Read more";
}
.pt-rm-toggle:checked ~ .pt-read-more::before {
  content: "Read less";
}
@media (max-width: 600px) {
  .pt-reviews-viewport {
    width: var(--pt-card-w);
    margin: 0 auto;
  }
}

/* Added by Nova, 2026-08-17: on the Services page, "View Website Projects"
   and "View Brand & Graphic Design Work" were solid sand-filled buttons,
   inconsistent with the "ghost" style (transparent, 1px Deep Navy border)
   used everywhere else on the same page for this kind of secondary action —
   confirmed against 4 other buttons already using the correct style.
   Overriding these two to match exactly, including the same hover state. */
.elementor-element-d12adb9 .elementor-button,
.elementor-element-899e661 .elementor-button {
  background-color: transparent !important;
  border-style: solid !important;
  border-width: 1px !important;
  border-color: #031233 !important;
  color: #031233 !important;
}
.elementor-element-d12adb9 .elementor-button:hover,
.elementor-element-899e661 .elementor-button:hover,
.elementor-element-d12adb9 .elementor-button:focus,
.elementor-element-899e661 .elementor-button:focus {
  background-color: #FFFFFE !important;
  border-color: #FFFFFE !important;
  color: #344054 !important;
}

/* Added by Nova, 2026-08-17: sitewide Legacy Blue → Royal Blue migration.
   Per the Brand Kit (2026-08-16): Legacy Blue (#466FE3) is retired,
   Royal Blue (#3366FF) is the brand blue everywhere going forward.
   Legacy Blue was still live as the Elementor kit's global accent color
   variable, referenced by ~29 elements just on the Services page alone
   (headings, icon accents, labels, buttons) — every page uses the same
   variable. Redefining it once here fixes every instance sitewide in one
   consistent change instead of patching individual elements. */
body.elementor-kit-5 {
  --e-global-color-e6155aa: #3366FF !important;
}

/* Added by Nova, 2026-08-17: unifying H1 sizing sitewide to the same clamp
   structure used on 13 of the 21 pages ("primary" typography preset). Two
   hand-built pages (Privacy Policy, Sitemap) had no H1 size rule at all —
   just the bare browser default — because they were never wired into either
   Elementor typography preset when built. This is a low-specificity fallback
   (bare h1.elementor-heading-title, no !important) so it only reaches those
   two pages; every other page already has a more specific per-widget rule
   that wins the cascade unchanged. Font-size only, deliberately: primary and
   secondary presets differ in text color too (near-white for hero sections
   vs. Deep Navy for content pages), and swapping color here would make text
   on light-background pages unreadable. The 6 blog-post pages that were
   using the "secondary" clamp got their own targeted font-size-only fix
   directly in each page's compiled CSS, same reasoning. */
h1.elementor-heading-title {
  font-size: var(--e-global-typography-primary-font-size);
}

/* Added by Nova, 2026-08-17: fixes sitewide horizontal scroll (visible at
   every screen width, not just mobile). Root cause: .pt-reviews-viewport is
   a flex child of .pt-reviews-wrap, and flex items default to
   `min-width: auto` — meaning the browser lets a flex item grow to fit its
   content's full intrinsic width even when an explicit `width` is set,
   which defeats `overflow-x: auto` entirely. The viewport's child,
   .pt-reviews-track, is deliberately much wider than the viewport (it holds
   two full sets of review cards for the seamless drag-loop), so without
   this override the whole track's width was leaking out through the
   viewport into .pt-reviews-wrap and from there into the page itself —
   pushing the document wider than the actual viewport on every page that
   carries the reviews carousel (About, Home, Brand & Graphic Design,
   Social Media Management, Website Design). `min-width: 0` is the standard,
   safe fix for this well-known flexbox behavior — it doesn't change any
   visible sizing, it just lets the explicit `width` and `overflow-x: auto`
   actually take effect the way they were meant to. */
.pt-reviews-viewport {
  min-width: 0;
}

/* Added by Nova, 2026-08-17: the min-width:0 fix above was real but
   incomplete — confirmed via a live DevTools scrollWidth check on the
   actual page (not guessed) that the SAME flex-growth problem exists at
   multiple levels of Elementor's own container system, independent of the
   reviews carousel. Elementor's ".e-con"/".e-con-inner" flex containers
   (used to build every section on every page) default to `min-width: auto`
   like any flex item, so any nested content wider than intended — the
   reviews carousel, but also, found in the same check, two unrelated
   Elementor "swiper" widgets on the homepage — can force its way back up
   through every ancestor container to <body> itself, which is exactly what
   was measured (body stretched to 6698px against a real ~1900px window).
   Fixing it at the root, on Elementor's own shared container classes,
   rather than patching each wide-content widget individually as it's
   found. */
.e-con,
.e-con-inner {
  min-width: 0;
}
