/* Vaakrasa overrides.
   Loads after vaakrasa-design.css. Three jobs:
     1. beat OceanWP's defaults that leak onto theme-rendered pages
     2. cap the display type, which read as oversized in practice
     3. bring LifterLMS's light-theme templates onto the dark design
   Sizes here are deliberately easy to tune: change the max in each clamp. */

/* ---------- 0. Global type scale ----------
   The whole site uses three weights of Syne and nothing else:
     bold   700
     normal 500
     slim   400
   800 and 900 read as too heavy, and 600 is redundant next to 500 and 700.
   Only 400/500/700 are loaded as @font-face now, so anything asking for another
   weight would be faked by the browser. These rules make sure nothing asks.

   Change a weight in one place here and it changes everywhere. */
:root {
  --font-body: "Syne", sans-serif;
  --fw-bold: 700;
  --fw-normal: 500;
  --fw-slim: 400;
}

/* Everything renders in Syne. */
body, button, input, select, textarea,
.elementor-widget-html, .llms-content-wrapper {
  font-family: var(--font-body);
}

/* BOLD (700): headings, emphasis, buttons, big numbers.
   !important is required because every element carries its weight inline. */
h1, h2, h3, h4, h5, h6,
strong, b,
.vk-btn,
.vk-card h3,
.llms-loop-title,
[data-count],
[style*="font-weight: 800"], [style*="font-weight:800"],
[style*="font-weight: 900"], [style*="font-weight:900"],
[style*="font-weight: 700"], [style*="font-weight:700"] {
  font-weight: var(--fw-bold) !important;
}

/* NORMAL (500): the italic accent phrases, labels, secondary emphasis.
   Listed after bold so a 500 span nested inside a heading keeps its lighter
   weight, which is what creates the contrast in the display headlines. */
[style*="font-weight: 600"], [style*="font-weight:600"],
[style*="font-weight: 500"], [style*="font-weight:500"] {
  font-weight: var(--fw-normal) !important;
}

/* SLIM (400): body copy and anything that did not ask for a weight. */
body, p, li, td, th, figcaption, blockquote, .vk-prose,
[style*="font-weight: 300"], [style*="font-weight:300"],
[style*="font-weight: 400"], [style*="font-weight:400"] {
  font-weight: var(--fw-slim);
}

/* Never let the browser fake a heavier cut than we ship. */
body, body * { font-synthesis-weight: none; }

/* OceanWP still renders its own header markup (collapsed to zero height while
   the Elementor header template supplies the real nav) plus a few utility
   links. Left alone they fall back to Montserrat 800, which is neither the
   right family nor a weight we load. Icon fonts are deliberately untouched. */
#site-header, #site-header *,
#site-navigation, #site-navigation *,
#footer, #footer *,
#mobile-fullscreen, #mobile-fullscreen *,
#mobile-nav, #mobile-nav *,
#mobile-menu-search, #mobile-menu-search *,
.sidr, .sidr *, [class*="sidr-class-"],
.skip-link, .site-breadcrumbs, .screen-reader-text {
  font-family: var(--font-body) !important;
}
/* Elementor's header template renders INSIDE OceanWP's #site-header, so this
   rule was flattening our own nav to 500 as well, logo included. Exclude it. */
#site-header *:not([data-nav]):not([data-nav] *):not(.vk-nav-mobile):not(.vk-nav-mobile *),
#site-navigation *, #footer *,
#mobile-fullscreen *, #mobile-nav *,
.sidr *, [class*="sidr-class-"] {
  font-weight: var(--fw-normal) !important;
}

/* The wordmark carries the most weight in the header. */
[data-nav] > a:first-child { font-weight: var(--fw-bold) !important; }
/* but never restyle icon glyphs, they depend on their own family */
.dashicons, .dashicons-before::before,
[class^="eicon-"], [class*=" eicon-"],
[class^="fa-"], [class*=" fa-"], .fa, .fas, .far, .fab,
.gt_switcher img {
  font-family: inherit;
}
.dashicons, .dashicons-before::before { font-family: dashicons !important; }
[class^="eicon-"], [class*=" eicon-"] { font-family: eicons !important; }

/* ---------- 0b. Navigation: desktop row, hamburger below 1024px ----------
   The link row wrapped onto two lines once the viewport got tight, which is
   what the breakpoint is for. 1024px is where tablets land and where the six
   links plus the language switcher plus the button stop fitting on one line. */
.vk-nav-toggle {
  display: none;
  flex: none;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: border-color var(--duration-fast) var(--ease-out-expo);
}
.vk-nav-toggle:hover { border-color: var(--accent); }
.vk-nav-toggle span {
  display: block;
  width: 20px;
  height: 2px;
  background: #fff;
  border-radius: 2px;
  transition: transform .35s var(--ease-out-expo), opacity .2s linear;
}
/* the three lines become an X while open */
.vk-nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.vk-nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.vk-nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.vk-nav-mobile {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 89;
  flex-direction: column;
  gap: 4px;
  padding: 96px clamp(20px, 5vw, 72px) 32px;
  background: rgba(13, 13, 13, .98);
  border-bottom: 1px solid var(--border-subtle);
  transform: translateY(-100%);
  opacity: 0;
  pointer-events: none;
  transition: transform .45s var(--ease-out-expo), opacity .3s linear;
  max-height: 100dvh;
  overflow-y: auto;
}
.vk-nav-mobile.is-open { transform: translateY(0); opacity: 1; pointer-events: auto; }
.vk-nav-mobile a:not(.vk-btn) {
  display: block;
  padding: 14px 0;
  font-size: 1.25rem;
  font-weight: var(--fw-normal);
  letter-spacing: -.015em;
  color: #fff;
  border-bottom: 1px solid var(--border-faint);
}
.vk-nav-mobile a:not(.vk-btn):hover { color: var(--accent); }

@media (max-width: 1024px) {
  .vk-nav-desktop { display: none !important; }
  .vk-nav-toggle { display: flex; }
  .vk-nav-mobile { display: flex; }
  /* the panel is open, so the page behind it must not scroll */
  body.vk-menu-open { overflow: hidden; }
}

/* ---------- 0b-ii. Header alignment ----------
   The <header> is fixed and full-bleed so its background band spans the
   viewport, but its contents have to line up with the page body. Every section
   holds its content in a 1440px column centred inside the same 72px gutter, so
   past 1584px viewport the sections start indenting and a header padded only by
   the gutter kept drifting left of them. This inner element reproduces that
   column; the header keeps its own padding and background. */
.vk-nav-inner {
  flex: 1 1 auto;
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}
/* Above 1024px both children of the bar group are hidden, but the group itself
   is not, leaving a zero-width third flex item pinned to the column's right
   edge. space-between then centred the nav instead of sitting it flush right.
   !important because the element carries an inline display:flex. */
.vk-nav-bar-actions { display: none !important; }
@media (max-width: 1024px) {
  .vk-nav-bar-actions { display: flex !important; }
}


/* ---------- 0d. Horizontal project rail alignment ----------
   Two problems stacked here. The rail carries left padding so its first card
   lines up with the section heading, but `scroll-snap-type: x mandatory` snaps
   that first card to the scrollport edge, scrolling the padding away (the rail
   loaded at scrollLeft equal to its own padding). And on viewports wider than
   the 1440px container, a fixed 72px padding no longer matches the centred
   content edge. Both fixed below. */
/* Every other section applies the gutter to the SECTION and then centres a
   1440px box inside it, so its content edge is:
       gutter + (available - 2*gutter - 1440) / 2
   The work section has no section padding (the rail must bleed right), and its
   header instead centres a 1440px box AND adds the gutter, which double-counts
   and pushed it 72px further right than everything else. This reproduces the
   real content edge for both the header and the rail. */
:root {
  --vk-gutter: clamp(20px, 5vw, 72px);
  --vk-edge: calc(var(--vk-gutter) + max(0px, (100% - 2 * var(--vk-gutter) - 1440px) / 2));
}

#work > div:first-of-type {
  max-width: none !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  padding-left: var(--vk-edge) !important;
  padding-right: var(--vk-edge) !important;
}

[data-rail] {
  scroll-snap-type: x proximity !important;
  padding-left: var(--vk-edge) !important;
  padding-right: var(--vk-gutter) !important;   /* the rail bleeds off the right */
  scroll-padding-left: var(--vk-edge);
  /* overflow-x:auto alone makes the UA compute overflow-y as auto too (CSS
     Overflow spec), so any sub-pixel height mismatch opens a sliver of
     vertical scroll inside the rail that traps wheel input under the cursor. */
  overflow-y: hidden !important;
}

/* ---------- 0e. Custom cursor ----------
   A green dot that replaces the pointer, plus a large soft glow trailing behind
   it. Only on devices that actually have a fine pointer: touch devices have no
   hover state and would be left with no cursor at all and a stuck glow.
   Also disabled for anyone who asked for reduced motion. */
.vk-cursor-dot,
.vk-cursor-glow {
  position: fixed;
  top: 0;
  left: 0;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
  transform: translate3d(-100px, -100px, 0);
}

.vk-cursor-dot {
  z-index: 10000;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;          /* centre on the pointer */
  border-radius: 50%;
  background: var(--accent);
  border: 1px solid transparent;
  transition: width .22s var(--ease-out-expo),
              height .22s var(--ease-out-expo),
              margin .22s var(--ease-out-expo),
              background-color .22s linear,
              border-color .22s linear,
              opacity .2s linear;
}

/* Over anything interactive: bigger, half transparent, accent ring. */
.vk-cursor-dot.is-hover {
  width: 44px;
  height: 44px;
  margin: -22px 0 0 -22px;
  background: rgba(79, 205, 97, .45);
  border-color: var(--accent);
}

/* Pressed. */
.vk-cursor-dot.is-down { width: 14px; height: 14px; margin: -7px 0 0 -7px; }

.vk-cursor-glow {
  z-index: 9999;
  width: 420px;
  height: 420px;
  margin: -210px 0 0 -210px;
  border-radius: 50%;
  /* Dimmed: the original .20/.08 read as a spotlight and pulled the eye away
     from the content. Roughly a third of that now. */
  background: radial-gradient(circle, rgba(79, 205, 97, .07) 0%, rgba(79, 205, 97, .03) 38%, rgba(79, 205, 97, 0) 70%);
  filter: blur(34px);
  transition: opacity .35s linear, width .4s var(--ease-out-expo), height .4s var(--ease-out-expo), margin .4s var(--ease-out-expo);
}
.vk-cursor-glow.is-hover {
  width: 520px;
  height: 520px;
  margin: -260px 0 0 -260px;
}

.vk-cursor-dot.is-visible,
.vk-cursor-glow.is-visible { opacity: 1; }

@media (hover: hover) and (pointer: fine) {
  html.vk-has-cursor,
  html.vk-has-cursor body,
  html.vk-has-cursor a,
  html.vk-has-cursor button,
  html.vk-has-cursor .vk-btn,
  html.vk-has-cursor [role="button"],
  html.vk-has-cursor select,
  html.vk-has-cursor label,
  html.vk-has-cursor summary { cursor: none; }

  /* Text fields keep a real caret. Losing the I-beam while typing is a
     usability cost the effect is not worth. */
  html.vk-has-cursor input[type="text"],
  html.vk-has-cursor input[type="email"],
  html.vk-has-cursor input[type="password"],
  html.vk-has-cursor input[type="search"],
  html.vk-has-cursor input[type="tel"],
  html.vk-has-cursor input[type="number"],
  html.vk-has-cursor textarea { cursor: text; }
}

/* No pointer, or reduced motion: native cursor, no dot, no glow. */
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  .vk-cursor-dot, .vk-cursor-glow { display: none !important; }
  html.vk-has-cursor, html.vk-has-cursor body, html.vk-has-cursor a, html.vk-has-cursor button { cursor: auto; }
}

/* ---------- 0f. Elementor background lazy-load fix ----------
   Elementor lazy-loads container backgrounds with:
     .e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded):not(.e-no-lazyload),
     .e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded):not(.e-no-lazyload) *
     { background-image: none !important }
   Note the trailing `*`: it blanks every DESCENDANT too, so our section
   gradients disappear until its JS marks the container loaded. These are CSS
   gradients, not images, so there is nothing to defer. Elementor's own
   e-no-lazyload opt-out does not survive into the rendered class list here, so
   these rules simply outrank it (five class-level selectors plus html body). */
html body .e-con.e-parent.e-con-full.e-flex section[style*="--gradient-hero-steep"] {
  background-image: var(--gradient-hero-steep) !important;
}
html body .e-con.e-parent.e-con-full.e-flex section[style*="--gradient-hero"]:not([style*="steep"]) {
  background-image: var(--gradient-hero) !important;
}
html body .e-con.e-parent.e-con-full.e-flex [style*="--gradient-card-radial"] {
  background-image: var(--gradient-card-radial) !important;
}
html body .e-con.e-parent.e-con-full.e-flex [style*="--gradient-placeholder"] {
  background-image: var(--gradient-placeholder-b) !important;
}

/* ---------- 1. No dark gray text, anywhere ---------- */
/* OceanWP sets h1..h6{color:#333}. Plain headings lose to it on the blog,
   the case-study archive and every LifterLMS page. */
h1, h2, h3, h4, h5, h6 { color: var(--text-on-dark); }

/* Same for its body and link defaults on those pages. */
#main, .entry-content, .content-area, .llms-content-wrapper { color: var(--text-on-dark); }

/* ---------- 2. Type scale cap ----------
   Every heading carries its font-size inline, so these need !important.
   Adjust the third value in each clamp to taste. */
h1 {
  font-size: clamp(2.1rem, calc(1.5rem + 2.4vw), 4.4rem) !important;
  line-height: 1.03 !important;
}
.elementor-widget-html h2 {
  font-size: clamp(1.7rem, calc(1.25rem + 1.7vw), 3.2rem) !important;
  line-height: 1.08 !important;
}
/* Big stat counters were sized against the old scale. */
.elementor-widget-html [data-count] {
  font-size: clamp(1.9rem, calc(1.5rem + 1.4vw), 2.9rem) !important;
}
/* Long-form article headings keep a smaller scale of their own. */
.vk-prose h2 { font-size: clamp(1.45rem, calc(1.2rem + .9vw), 2rem) !important; }
.vk-prose h3 { font-size: clamp(1.15rem, calc(1.05rem + .45vw), 1.4rem) !important; }

/* ---------- 3. Hero height ----------
   The heroes were full-viewport and read as mostly empty space. Cap them so
   the content below starts sooner. Tune the clamp middle/max values. */
section#top,
section[data-screen-label$="Hero"] {
  min-height: clamp(360px, 56vh, 620px) !important;
  padding-top: clamp(104px, 13vh, 140px) !important;
  padding-bottom: clamp(36px, 6vh, 64px) !important;
}

/* The case-study hero has no min-height of its own, just deep padding. */
section[data-screen-label="Case Hero"] {
  padding-top: clamp(104px, 13vh, 140px) !important;
  padding-bottom: clamp(32px, 5vh, 56px) !important;
}


/* ---------- 5. Course catalog cards ----------
   Default LifterLMS cards are flat and their meta text is mid gray. */
.llms-loop-item {
  background: rgba(255, 255, 255, .02) !important;
  border: 1px solid var(--border-subtle) !important;
  border-radius: 10px !important;
  overflow: hidden !important;
  transition: transform .5s var(--ease-out-expo), border-color .5s var(--ease-out-expo) !important;
}
.llms-loop-item:hover {
  transform: translateY(-4px);
  border-color: rgba(79, 205, 97, .45) !important;
}
.llms-loop-item .llms-loop-item-content { padding: 24px !important; }
.llms-loop-item .llms-featured-image,
.llms-loop-item img { width: 100% !important; display: block !important; }

/* Every scrap of text on a card is white or near-white. Never gray. */
.llms-loop-item,
.llms-loop-item a,
.llms-loop-item h1, .llms-loop-item h2, .llms-loop-item h3, .llms-loop-item h4,
.llms-loop-item .llms-loop-title,
.llms-loop-item .llms-author,
.llms-loop-item .llms-meta,
.llms-loop-item .llms-meta-info,
.llms-loop-item p,
.llms-loop-item span { color: var(--text-on-dark) !important; }

.llms-loop-item .llms-loop-title {
  font-size: 1.375rem !important;
  font-weight: 700 !important;
  letter-spacing: -.015em !important;
  margin: 0 0 10px !important;
}
.llms-loop-item:hover .llms-loop-title { color: var(--accent) !important; }

/* Secondary lines stay readable rather than washed out. */
.llms-loop-item .llms-meta,
.llms-loop-item .llms-author,
.llms-loop-item .llms-meta-info {
  color: rgba(255, 255, 255, .55) !important;
  font-size: 11px !important;
  letter-spacing: .18em !important;
  text-transform: uppercase !important;
}
.llms-loop-item .llms-excerpt,
.llms-loop-item .llms-loop-item-content p {
  color: rgba(255, 255, 255, .6) !important;
  font-size: 1rem !important;
  line-height: 1.6 !important;
}

/* Progress and price chips on the card. */
.llms-loop-item .llms-price-wrapper,
.llms-loop-item .llms-access-plan-price { color: var(--accent) !important; font-weight: 700 !important; }

/* The catalog grid itself. */
.llms-loop-list { gap: 24px !important; }

/* ---------- 6. LifterLMS ---------- */
.llms-content-wrapper,
.llms-loop-item-content,
.llms-syllabus-wrapper,
.llms-lesson-preview,
.llms-person-form-wrapper,
.llms-checkout-wrapper,
.llms-widget,
.llms-sd-widget,
.llms-sd-section {
  background: transparent !important;
  color: var(--text-on-dark) !important;
}

.llms-loop-item,
.llms-lesson-preview,
.llms-access-plan,
.llms-widget,
.llms-sd-widget,
.llms-notice {
  border: 1px solid var(--border-subtle) !important;
  border-radius: 8px !important;
  background: rgba(255, 255, 255, .02) !important;
  overflow: hidden;
}

.llms-loop-item-content { padding: 22px !important; }

.llms-loop-title,
.llms-lesson-title,
.llms-access-plan-title,
.llms-sd-title {
  color: var(--text-on-dark) !important;
  font-weight: 700 !important;
  letter-spacing: -.015em !important;
}

.llms-loop-item a,
.llms-lesson-preview a,
.llms-sd-widget a { color: var(--text-on-dark) !important; }
.llms-loop-item a:hover,
.llms-lesson-preview a:hover { color: var(--accent) !important; }

/* Buttons: match the site's pill button. */
.llms-button-action,
.llms-button-primary,
.llms-button-secondary,
.llms-field-button button,
.llms-person-form-wrapper button[type="submit"],
.llms-checkout-wrapper button[type="submit"] {
  background: var(--accent) !important;
  color: var(--accent-text-on) !important;
  border: 1px solid transparent !important;
  border-radius: var(--radius-pill) !important;
  padding: 14px 28px !important;
  font-family: var(--font-body) !important;
  font-weight: 600 !important;
  font-size: 14px !important;
  letter-spacing: var(--tracking-wide) !important;
  text-transform: uppercase !important;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out-expo) !important;
}
.llms-button-action:hover,
.llms-button-primary:hover,
.llms-button-secondary:hover { background: var(--accent-hover) !important; }

.llms-button-secondary {
  background: transparent !important;
  color: var(--text-on-dark) !important;
  border-color: var(--border-subtle) !important;
}
.llms-button-secondary:hover {
  color: var(--accent) !important;
  border-color: var(--accent) !important;
  background: transparent !important;
}

/* Form fields. */
.llms-form-field input[type="text"],
.llms-form-field input[type="email"],
.llms-form-field input[type="password"],
.llms-form-field input[type="tel"],
.llms-form-field select,
.llms-form-field textarea {
  background: rgba(0, 0, 0, .4) !important;
  border: 1px solid var(--border-subtle) !important;
  border-radius: 6px !important;
  color: #fff !important;
  font-family: var(--font-body) !important;
  padding: 12px 14px !important;
}
.llms-form-field input:focus,
.llms-form-field select:focus,
.llms-form-field textarea:focus {
  border-color: var(--accent) !important;
  outline: none !important;
}
.llms-form-field label,
.llms-form-heading { color: rgba(255, 255, 255, .6) !important; }

/* Progress + syllabus. */
.llms-progress .progress-bar-complete { background: var(--accent) !important; }
.llms-progress .llms-progress-bar { background: rgba(255, 255, 255, .1) !important; }
.llms-syllabus-wrapper .section-title { color: var(--text-on-dark) !important; }

/* Notices. */
.llms-notice { color: var(--text-on-dark) !important; }
.llms-notice.llms-success { border-color: rgba(79, 205, 97, .5) !important; }
.llms-notice.llms-error { border-color: rgba(255, 120, 100, .5) !important; }

/* Pricing. */
.llms-price-currency-symbol, .llms-price { color: var(--accent) !important; }
.llms-access-plan-pricing, .llms-access-plan-footer { background: transparent !important; }
.llms-access-plan-title { background: rgba(255, 255, 255, .04) !important; padding: 14px 18px !important; }

/* The tables LifterLMS uses on the student dashboard. */
.llms-table { border-color: var(--border-subtle) !important; }
.llms-table th, .llms-table td {
  border-color: var(--border-subtle) !important;
  color: var(--text-on-dark) !important;
  background: transparent !important;
}
.llms-table thead th { background: rgba(255, 255, 255, .04) !important; }

/* vk-btn fallback sizing: a .vk-btn carrying no recognised size class would
   otherwise render with no padding at all. */
.vk-btn:not(.vk-btn--sm):not(.vk-btn--md):not(.vk-btn--lg){padding:14px 26px;font-size:14px}


/* ---------- Loading screen ----------
   Full-viewport cover shown from DOMContentLoaded until window.load.
   Reuses the homepage's wordmark-pulse and top progress-line language.
   Markup and lifecycle live in vaakrasa-design.js. */
html.vk-loading, html.vk-preview-open { overflow: hidden; }
html.vk-preview-open [data-marquee] { animation-play-state: paused !important; }
#vk-loader {
  position: fixed;
  inset: 0;
  z-index: 999;
  background: var(--color-dark-blue);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity .5s var(--ease-out-expo);
}
#vk-loader[data-vk-done] { opacity: 0; pointer-events: none; }
#vk-loader .vk-loader__track {
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--color-white-08);
}
#vk-loader .vk-loader__fill {
  height: 100%; width: 0%;
  background: var(--accent);
  transition: width .35s var(--ease-out-expo);
}
#vk-loader .vk-loader__mark {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: clamp(2rem, 5vw, 3rem);
  letter-spacing: -0.03em;
  color: var(--color-white);
  display: flex; align-items: center; gap: 2px;
}
#vk-loader .vk-loader__mark .dot {
  color: var(--accent);
  animation: vk-loader-pulse 1.4s ease-in-out infinite;
}
@keyframes vk-loader-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .35; transform: scale(.7); }
}
#vk-loader .vk-loader__status {
  position: absolute; bottom: clamp(20px, 4vh, 34px); left: clamp(20px, 5vw, 40px);
  font-family: var(--font-body);
  font-size: 11px; letter-spacing: var(--tracking-wide); text-transform: uppercase;
  color: var(--color-white-40);
}
#vk-loader .vk-loader__pct {
  position: absolute; bottom: clamp(20px, 4vh, 34px); right: clamp(20px, 5vw, 40px);
  font-family: var(--font-body);
  font-size: 11px; letter-spacing: var(--tracking-wide); text-transform: uppercase; font-weight: 700;
  color: var(--color-white);
  font-variant-numeric: tabular-nums;
}
#vk-loader .vk-loader__pct span { color: var(--color-white-40); font-weight: 400; margin-left: 1px; }
@media (prefers-reduced-motion: reduce) {
  #vk-loader { transition: none; }
  #vk-loader .vk-loader__mark .dot { animation: none; }
}

/* ---------- Live-site preview overlay ----------
   Full-screen viewer for the "Open the live site" links on project pages.
   The iframe src is set only when opened and cleared on close, so the
   (often heavy, animated) client site never loads until asked for.
   Markup and lifecycle live in vaakrasa-design.js. */
#vk-preview {
  position: fixed;
  inset: 0;
  z-index: 998;
  background: rgba(5, 6, 8, .94);
  display: none;
  flex-direction: column;
  opacity: 0;
  transition: opacity .3s var(--ease-out-expo);
  /* Sizing budget for the device. The screen is a fixed 16:9 box, so its width
     has to be solved against BOTH the free width and the free height, else it
     falls back to its intrinsic (tiny) content size. --vk-bar is a deliberate
     slight over-estimate of the toolbar so the device can never overflow. */
  --vk-pad: clamp(6px, 1vw, 16px);
  --vk-bar: 68px;
  --vk-bez: clamp(6px, 0.8vw, 12px);
  --vk-base: 14px;
  --vk-overhang: clamp(8px, 1.2vw, 20px);
}
#vk-preview[data-vk-open] { display: flex; opacity: 1; }
#vk-preview .vk-preview__bar {
  flex: none;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  padding: 14px clamp(16px, 3vw, 28px);
  background: var(--color-black);
  border-bottom: 1px solid var(--border-subtle);
}
#vk-preview .vk-preview__spacer { min-width: 0; }
#vk-preview .vk-preview__actions {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
#vk-preview .vk-preview__viewport {
  justify-self: center;
  flex: none;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: rgba(255,255,255,.05);
  border: 1px solid var(--border-subtle);
}
#vk-preview .vk-preview__viewport button {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-white-40);
  background: transparent;
  border: none;
  border-radius: 999px;
  padding: 7px 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: color var(--duration-fast) var(--ease-out-expo), background var(--duration-fast) var(--ease-out-expo);
}
#vk-preview .vk-preview__viewport button svg { width: 13px; height: 13px; flex: none; }
#vk-preview .vk-preview__viewport button:hover { color: var(--color-white); }
#vk-preview .vk-preview__viewport button[aria-pressed="true"] {
  background: var(--accent);
  color: var(--accent-text-on);
}
#vk-preview .vk-preview__frame-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
}
#vk-preview .vk-preview__link {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-white-60);
  white-space: nowrap;
  transition: color var(--duration-fast) var(--ease-out-expo);
}
#vk-preview .vk-preview__link:hover { color: var(--accent); }
#vk-preview .vk-preview__close {
  flex: none;
  width: 34px; height: 34px;
  border-radius: 999px;
  border: 1px solid var(--border-subtle);
  background: transparent;
  color: var(--color-white);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: border-color var(--duration-fast) var(--ease-out-expo), color var(--duration-fast) var(--ease-out-expo);
}
#vk-preview .vk-preview__close:hover { border-color: var(--accent); color: var(--accent); }
#vk-preview .vk-preview__frame-wrap {
  flex: 1 1 auto;
  min-height: 0;
  padding: var(--vk-pad);
}
#vk-preview iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--color-white);
}
@media (max-width: 640px) {
  #vk-preview .vk-preview__bar { gap: 8px; padding: 10px 12px; }
  #vk-preview .vk-preview__view-label { display: none; }
  #vk-preview .vk-preview__viewport button { padding: 8px; }
  #vk-preview .vk-preview__link { display: none; }
  #vk-preview { --vk-bar: 58px; }
  /* A desktop-width preview on a phone is unreadable, so the option goes away
     entirely and the laptop chrome with it. */
  #vk-preview [data-vk-view-btn="desktop"] { display: none; }
  #vk-preview .vk-preview__screen { border: none; padding: 0; }
  #vk-preview .vk-preview__base { display: none; }
}
/* Mobile view mode on any screen: phone-width, no laptop around it. The shot
   needs an explicit height here: with aspect-ratio off and no definite parent
   height, a percentage height would resolve against its own content and
   collapse. */
#vk-preview[data-vk-view="mobile"] .vk-preview__shot {
  aspect-ratio: auto;
  /* flex:none and an explicit width at every level: the device is a column
     flex container, so a stretched screen would otherwise let the shot fill
     the full desktop width instead of staying phone-sized. */
  flex: none;
  width: min(420px, 100%);
  height: calc(100vh - var(--vk-bar) - 2 * var(--vk-pad));
  height: calc(100dvh - var(--vk-bar) - 2 * var(--vk-pad));
}
#vk-preview[data-vk-view="mobile"] .vk-preview__device,
#vk-preview[data-vk-view="mobile"] .vk-preview__screen {
  flex: none;
  width: min(420px, 100%);
}
#vk-preview[data-vk-view="mobile"] .vk-preview__screen { border: none; padding: 0; }
#vk-preview[data-vk-view="mobile"] .vk-preview__base { display: none; }

/* ---------- Preview flight: button -> close, screenshot -> frame ----------
   One-off ghosts, not part of the normal cascade for #vk-preview itself, so
   plain top/left/width/height transitions are fine here (a single measured
   element animating for ~0.5s, not a per-frame layout in a hot loop). */
body.vk-preview-open { cursor: default; }
.vk-fly {
  position: fixed;
  z-index: 1000;
  margin: 0;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 clamp(16px, 3.4vw, 34px);
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-text-on);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  pointer-events: none;
  transition:
    top .5s var(--ease-out-expo), left .5s var(--ease-out-expo),
    width .5s var(--ease-out-expo), height .5s var(--ease-out-expo),
    padding .5s var(--ease-out-expo), background .35s ease, color .25s ease;
}
.vk-fly::after {
  content: '\2715';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  text-transform: none;
  letter-spacing: 0;
  color: var(--color-white);
  opacity: 0;
  transition: opacity .25s ease .18s;
}
.vk-fly--done {
  padding: 0;
  background: transparent;
  color: transparent;
  border: 1px solid var(--border-subtle);
}
.vk-fly--done::after { opacity: 1; }
.vk-fly-frame {
  position: fixed;
  z-index: 999;
  background-size: cover;
  background-position: center;
  border-radius: 6px;
  pointer-events: none;
  transition:
    top .5s var(--ease-out-expo), left .5s var(--ease-out-expo),
    width .5s var(--ease-out-expo), height .5s var(--ease-out-expo),
    border-radius .5s var(--ease-out-expo), opacity .3s ease .22s;
}
@media (prefers-reduced-motion: reduce) {
  .vk-fly, .vk-fly-frame { transition: none; }
}

/* ---------- Device chrome ----------
   One 1px light-grey outline defines both the resting laptop mockup on a
   project page and the laptop framing the opened preview overlay, so opening
   the preview reads as zooming into the same object. Outline only: a filled
   light chassis overpowered the black section ground. */
:root { --vk-device-line: rgba(255,255,255,.34); }

.vk-laptop {
  display: block;
  max-width: 980px;
  margin: 0 auto;
  cursor: pointer;
  color: inherit;
  text-decoration: none;
}
/* Inner wrapper so hover scales screen and base together. The anchor itself
   carries data-reveal, whose observer writes an inline `transform: none` that
   would beat any hover transform declared here. */
.vk-laptop__body {
  transition: transform .55s var(--ease-out-expo);
}
.vk-laptop:hover .vk-laptop__body,
.vk-laptop:focus-visible .vk-laptop__body { transform: scale(1.025); }
.vk-laptop:focus-visible { outline: none; }
.vk-laptop:focus-visible .vk-laptop__screen { border-color: var(--accent); }

.vk-laptop__screen {
  position: relative;
  border: 1px solid var(--vk-device-line);
  border-radius: 14px 14px 3px 3px;
  padding: 14px 14px 20px;
  transition: border-color var(--duration-fast) var(--ease-out-expo);
}
.vk-laptop__cam {
  position: absolute;
  top: 6px; left: 50%;
  transform: translateX(-50%);
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--vk-device-line);
}
.vk-laptop__shot {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 3px;
  overflow: hidden;
  background: var(--color-black);
}
/* Base reads wider than the lid, the way a laptop looks from the front. */
.vk-laptop__base {
  position: relative;
  height: 14px;
  margin: 0 -30px;
  border: 1px solid var(--vk-device-line);
  border-top: none;
  border-radius: 0 0 12px 12px;
}
.vk-laptop__notch {
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 100px; height: 5px;
  background: var(--vk-device-line);
  border-radius: 0 0 6px 6px;
}
@media (max-width: 640px) {
  .vk-laptop__screen { padding: 9px 9px 14px; border-radius: 10px 10px 3px 3px; }
  .vk-laptop__base { margin: 0 -16px; height: 11px; }
  .vk-laptop__notch { width: 60px; height: 4px; }
}
@media (prefers-reduced-motion: reduce) {
  .vk-laptop__body { transition: none; }
  .vk-laptop:hover .vk-laptop__body { transform: none; }
}

/* ---------- Overlay device ----------
   Same silhouette around the live iframe, so the opened preview looks like the
   mockup zoomed in. Hidden in mobile view and on phones, where a laptop frame
   around a phone-width site would be nonsense. */
#vk-preview .vk-preview__device {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 100%;
  max-height: 100%;
  min-height: 0;
}
#vk-preview .vk-preview__screen {
  position: relative;
  display: flex;
  border: 1px solid var(--vk-device-line);
  border-radius: 14px 14px 3px 3px;
  padding: var(--vk-bez);
}
#vk-preview .vk-preview__shot {
  position: relative;
  aspect-ratio: 16 / 9;
  height: auto;
  /* Solve the 16:9 width against whichever axis binds first. */
  width: min(
    calc(100vw - 2 * var(--vk-pad) - 2 * var(--vk-bez) - 2 * var(--vk-overhang) - 2px),
    calc((100vh - var(--vk-bar) - 2 * var(--vk-pad) - 2 * var(--vk-bez) - var(--vk-base) - 2px) * 16 / 9)
  );
  width: min(
    calc(100vw - 2 * var(--vk-pad) - 2 * var(--vk-bez) - 2 * var(--vk-overhang) - 2px),
    calc((100dvh - var(--vk-bar) - 2 * var(--vk-pad) - 2 * var(--vk-bez) - var(--vk-base) - 2px) * 16 / 9)
  );
  max-width: 100%;
  overflow: hidden;
  border-radius: 3px;
  background: var(--color-white);
  transition: width .35s var(--ease-out-expo);
}
/* The overhang is subtracted from the solved width above, so it widens the
   base without reintroducing horizontal overflow. align-self:stretch is needed
   because the device is a column flex container with align-items:center — an
   empty base would otherwise size to its own (zero) content. */
#vk-preview .vk-preview__base {
  position: relative;
  flex: none;
  align-self: stretch;
  height: var(--vk-base);
  margin: 0 calc(-1 * var(--vk-overhang));
  border: 1px solid var(--vk-device-line);
  border-top: none;
  border-radius: 0 0 12px 12px;
}
#vk-preview .vk-preview__notch {
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 100px; height: 5px;
  background: var(--vk-device-line);
  border-radius: 0 0 6px 6px;
}

/* ---------- Language switcher (GTranslate) ----------
   widget_look is dropdown_with_flags, so the plugin builds a custom .gt_switcher
   tree in JS rather than a native <select> (a select cannot show flag images).
   Everything below targets generated nodes and needs !important to outrank the
   plugin's own stylesheet. Kept as one block at the very end of this file so no
   rule above can quietly win on source order: the styling used to be split
   across two sections that silently overrode each other's padding, tracking and
   border-radius.

   Two instances share it: .vk-lang in the desktop nav, and .vk-lang--bar beside
   the hamburger. Only one is ever visible — they swap at the 1024px breakpoint.
   A third copy used to sit inside the open mobile panel; it was removed once the
   bar copy made it reachable without opening the menu.

   Deliberately not covered: select, .gt_selector, .gt_float_switcher and
   .gt_options. Those belong to the plugin's other widget looks and are never
   rendered at this setting (verified zero of each in the DOM), so the rules
   that used to target them were dead weight. */

.vk-lang {
  position: relative !important;   /* positioning context for the panel */
  display: inline-flex;
  align-items: center;
  line-height: 1;
  flex: none;
}
.vk-lang .gtranslate_wrapper { display: inline-flex; align-items: center; }
.vk-lang #google_translate_element2 { display: none !important; }   /* Google's hidden helper node */

/* --- the control --- */
/* The plugin ships .gt_option as position:relative inside an overflow:hidden
   switcher, so opening the panel grew the switcher inline and expanded the
   whole navbar. overflow:visible here plus the absolute panel below fixes it. */
.vk-lang .gt_switcher {
  overflow: visible !important;
  height: auto !important;
  font-family: var(--font-body) !important;
}
/* The plugin paints .gt_selected as a white pill: a background-color AND a
   `linear-gradient(#fff 0%, #fff 70%)` background-image, plus its own border.
   Both layers have to be cleared — the `background` shorthand resets the image
   too, which a bare background-color would not. */
.vk-lang .gt_switcher,
.vk-lang .gt_switcher .gt_selected {
  overflow: visible !important;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}
.vk-lang .gt_switcher .gt_selected a {
  display: inline-flex !important;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  height: auto !important;
  line-height: 1.2 !important;
  padding: 0 !important;
  margin: 0 !important;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  color: rgba(255, 255, 255, .6) !important;
  font-family: var(--font-body) !important;
  font-size: 11px !important;
  font-weight: 400 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-out-expo);
}
.vk-lang .gt_switcher .gt_selected a:hover { color: #fff !important; }
/* The caret is a background-image on ::after, not a DOM node, so nothing that
   targets elements can reach it. It cost 15px plus a flex gap. */
.vk-lang .gt_switcher .gt_selected a::after { display: none !important; }
/* Shrink-to-fit at every level. A fixed width here was overflowed by the
   nowrap content anyway, so the painted control never matched its own box. */
.vk-lang,
.vk-lang .gt_switcher,
.vk-lang .gt_switcher .gt_selected,
.vk-lang .gt_switcher .gt_selected a {
  width: auto !important;
  max-width: none !important;
}

/* --- the dropdown panel --- */
.vk-lang .gt_switcher .gt_option {
  position: absolute !important;
  top: calc(100% + 12px) !important;
  left: 0 !important;
  z-index: 200 !important;
  /* max-content, not a fixed 200px: the panel tracks the longest language name
     and re-fits by itself if the language list is changed in plugin settings.
     It must be max-content rather than auto: shrink-to-fit clamps against the
     containing block, which here is a wrapper only as wide as the collapsed
     label, and that came out 16px short of the real content (the flag fell out
     of the intrinsic-size calculation) so the widest name was clipped. */
  width: max-content !important;
  /* max-content ignores the viewport, so guard the narrow end explicitly. */
  max-width: calc(100vw - 40px) !important;
  /* The plugin keeps .gt_option at height:0 and animates it open. Out of flow
     that animation has nothing useful to do, and the explicit height would
     leave the panel collapsed. */
  height: auto !important;
  max-height: 340px !important;
  overflow-y: auto !important;
  background: var(--color-black) !important;
  border: 1px solid var(--border-subtle) !important;
  border-radius: 8px !important;
  padding: 6px !important;
  box-shadow: 0 24px 60px rgba(0,0,0,.7);
}
.vk-lang .gt_switcher .gt_option a {
  display: flex !important;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  padding: 8px 10px !important;
  margin: 0 !important;
  border-radius: 6px;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  color: rgba(255, 255, 255, .75) !important;
  font-family: var(--font-body) !important;
  font-size: 12px !important;
  font-weight: 400 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease-out-expo);
}
.vk-lang .gt_switcher .gt_option a:hover { background: rgba(255,255,255,.07) !important; color: #fff !important; }
/* Flag spacing comes from the flex gap on both rows above, so the plugin's own
   margin on the image was stacking a further 6px onto every one of them. */
.vk-lang img { display: inline-block !important; vertical-align: middle; margin: 0 !important; }

/* --- per-instance --- */
/* The header-bar copy exists only for the hamburger viewports; above 1024px the
   desktop nav's own switcher is the visible one and this would duplicate it. */
.vk-lang--bar { display: none !important; }
@media (max-width: 1024px) {
  .vk-lang--bar { display: inline-flex !important; }
}
/* It sits hard against the right edge of the viewport, so its panel is
   right-aligned or it would open off-screen. */
.vk-lang--bar .gt_switcher .gt_option { left: auto !important; right: 0 !important; }
