/**
 * OptimWP — Elementor native bridge.
 *
 * The homepage (and, later, other pages) is rebuilt with NATIVE Elementor containers +
 * heading/text-editor widgets that reuse the code-first classes (owp-section, owp-container,
 * owp-cards, owp-feature, owp-service, owp-review, owp-guarantee, owp-about, owp-cta-banner)
 * as the visual skin.
 *
 * Elementor's `.e-con` container base sets `margin:0`, `padding:10px`, `border-radius:0` and
 * `text-align:start` on EVERY container. Those load after our sections.css and, at equal
 * specificity, win — so our classes' margins/padding/radius/alignment silently lose (max-width
 * survives only because Elementor never sets it). This file re-asserts what our design intends,
 * scoped under `.owp-page` so specificity (0,2,0) beats `.e-con` (0,1,0) regardless of load order.
 *
 * Do NOT redefine owp-* component *looks* here (colors, fonts, hovers come from the shared CSS) —
 * only re-assert the box-model/layout properties Elementor's container base clobbers.
 */

/* -------------------------------------------------- centering (margin:auto clobbered).
   padding-block 0 kills Elementor's default 10px `.e-con` padding; keep the 1rem gutter.
   The homepage hero's inner column is excluded: it carries its width, its centering and its
   gutter as NATIVE container settings now (Layout > Width, Advanced > Margin / Padding).
   Elementor consumes those through `.e-con{margin-inline-*:var(--margin-inline-*)}`, which is
   (0,1,0); this rule is (0,2,0) and would silently outrank the panel.
   `:where()` inside the `:not()` keeps the selector at its original (0,2,0) — see the note on
   `.owp-page .owp-section` below for why raising it would be a bug. */
.owp-page .owp-container:not(:where(.owp-hero__inner)) { margin-inline: auto; padding: 0 1rem; }
.owp-page .owp-head           { margin-inline: auto; text-align: center; }
.owp-page .owp-cta-banner     { text-align: center; }

/* -------------------------------------------------- section vertical rhythm (padding clobbered).
   Ceiling stays 6rem (96px) at desktop, matched to the reference's py-24 -- that earlier decision
   is unchanged. What moved is the FLOOR: the reference never drops a section below 5rem at any
   width (py-24 is unconditional, py-20 is its smallest responsive step), while this clamp bottomed
   out at 3.5rem and only reached 6rem past a 1371px viewport. Phones and tablets were 40-56px short
   per section. 5rem floor, and 8vw now reaches the ceiling at 1200px.

   The hero is excluded — its vertical padding is a NATIVE container setting now (Advanced >
   Padding, custom unit: `clamp(3.5rem, 7vw, 6rem)` top / `2rem` bottom / `0px` sides).
   Elementor consumes it through `.e-con-full{padding-block-*:var(--padding-block-*)}`, which is
   (0,1,0); this rule is (0,2,0) and would silently outrank the panel value. The hero closes
   tighter than a normal section on purpose: the tech-chip band above the divider gets 2rem of
   padding-top, so the hero's own bottom padding matches it and the band stays optically
   symmetric (2rem above the chips / 2rem below).

   The exclusion is written `:not(:where(...))` and not `:not(...)` on purpose: `:where()` scores
   zero, so the selector keeps the exact (0,2,0) it had before the hero was carved out. A plain
   `:not(.owp-hero)` would take it to (0,3,0) and it would start beating `.owp-page
   .owp-section--flush-top` (0,2,0) further down this file, silently putting 96px back on top of
   every flush-top section on the other pages. */
.owp-page .owp-section:not(:where(.owp-hero)) { padding-block: clamp(5rem, 8vw, 6rem); padding-inline: 0; }

/* -------------------------------------------------- page-hero (inner pages) as native container:
   re-assert its own padding / centering / text-align that Elementor's `.e-con` base clobbers. */
.owp-page .owp-page-hero        { padding-block: clamp(3rem, 6vw, 5rem) clamp(2rem, 4vw, 3rem); padding-inline: 0; text-align: center; }
/* 54rem = the homepage hero's own inner width, so inner pages open at the same measure. */
.owp-page .owp-page-hero__inner { max-width: 54rem; margin-inline: auto; padding: 0; }

/* -------------------------------------------------- section heading treatment matched to vercel:
   36px / line-height 1.25 (vs our 40px/1.15), and NO 42rem cap so long headings stay on one line.
   Targets the native <h2> (`.elementor-heading-title`).

   The subtitle measure is NOT set here. It used to say `max-width:42rem`, but that rule is (0,2,0)
   and Elementor's own `.elementor.elementor .e-con>.elementor-widget{max-width:100%}` is (0,4,0)
   and loads after us, so the cap never applied to any of the 45 native subtitle widgets -- it only
   bit the handful still written as raw HTML, which is why the homepage looked inconsistent with
   itself: three subtitles full width, one boxed at 672px. Both kinds are now capped at 52rem, by a
   rule written at (0,5,0) at the FOOT of this file, where it can actually win. `margin-inline:auto`
   stays here for the raw-HTML subtitles. */
.owp-page .owp-head            { max-width: none; }
/* letter-spacing is restated here for the same reason the font-size is: the native section titles
   are `.elementor-heading-title`, and Elementor's global typography rule for them is (0,2,0) and
   prints after our sheets, so anything we want guaranteed on them has to be at least that specific.
   -0.025em = the reference's `tracking-tight`, the same value base.css now gives every h1/h2. */
.owp-page .owp-head .elementor-heading-title,
.owp-page .owp-head__title     { font-size: clamp(2rem, 3.6vw, 2.5rem); line-height: 1.25; letter-spacing: -.025em; }
.owp-page .owp-head__subtitle  { margin-inline: auto; }

/* -------------------------------------------------- hero tech-chips matched to vercel:
   a divider + "Tehnologii pe care le folosim" label + chips (normal case, 14px, icon+text).
   (Elementor-only for now; mirror to code-first sections.css when the sites are synced.)
   The band's own top margin, top padding and divider line USED to live here; on the homepage
   they are native container settings now (see the HOMEPAGE HERO block at the foot of this file). */
.owp-body .owp-hero__techlabel { margin: 0 0 1.25rem; font-size: .8125rem; font-weight: 600; text-transform: uppercase; letter-spacing: .18em; color: var(--owp-muted); }
.owp-body .owp-hero__tech      { margin-top: 0; gap: 1rem 2.5rem; font-size: 1rem; text-transform: none; letter-spacing: normal; }
.owp-body .owp-hero__tech span { display: inline-flex; align-items: center; gap: .5rem; font-weight: 500; }
.owp-body .owp-hero__tech svg  { width: 1.05rem; height: 1.05rem; flex-shrink: 0; color: var(--owp-brand); }
.owp-body .owp-hero__tech-wp   { font-weight: 700; color: color-mix(in oklab, var(--owp-fg) 85%, transparent); }
.owp-body .owp-btn__arrow      { width: 1.05rem; height: 1.05rem; flex-shrink: 0; }

/* -------------------------------------------------- card box (feature/service/review) = NATIVE
   Elementor settings now (bg/border/radius/padding, panel-editable) — no bridge needed for them.
   These one-off boxes stay class/bridge driven (clamp/gradient values can't be native settings). */
.owp-page .owp-guarantee__box  { padding: clamp(2rem, 5vw, 3.5rem); border-radius: var(--owp-radius-3xl); }
.owp-page .owp-about__quotecard{ padding: 2rem; border-radius: var(--owp-radius-3xl); }
.owp-page .owp-cta-banner      { padding: clamp(3rem, 6vw, 5rem) 2rem; border-radius: var(--owp-radius-3xl); }

/* -------------------------------------------------- structural containers keep NO inner padding */
.owp-page .owp-cards,
.owp-page .owp-services__grid,
.owp-page .owp-reviews__grid,
.owp-page .owp-steps,
.owp-page .owp-contact__cards,
.owp-page .owp-contact__grid,
.owp-page .owp-about__grid,
.owp-page .owp-about__grid > .e-con:first-child,
.owp-page .owp-head,
.owp-page .owp-guarantee__inner,
.owp-page .owp-guarantee__inner > .e-con,
.owp-page .owp-cta-banner__inner,
.owp-page .owp-services__more  { padding: 0; }

/* -------------------------------------------------- card rows are CSS grids, not flex.
   margin-top (head→grid gap) is on these grid containers in sections.css; Elementor's
   `.e-con{margin:0}` collapses it → the whole page reads cramped. Re-assert it here. */
.owp-page .owp-cards           { display: grid; gap: 1.25rem; margin-top: 3.5rem; }
.owp-page .owp-services__grid  { display: grid; gap: 1.25rem; margin-top: 3.5rem; }
.owp-page .owp-reviews__grid   { display: grid; gap: 1.5rem; margin-top: 3.5rem; }
.owp-page .owp-about__grid     { display: grid; gap: 3rem; align-items: stretch; }
/* About left column: equal height with the quote card; push the "Află mai multe" button to the
   bottom so it lines up with the quote card's bottom edge, and give it a bit more padding. */
.owp-page .owp-about__grid > .e-con:first-child { display: flex; flex-direction: column; }
.owp-page .owp-about__grid > .e-con:first-child > .elementor-widget-html:last-child { margin-top: auto; }
/* Same bottom-alignment for the RAW-HTML about section (generic-converted pages), where the left
   column is a plain <div> and the button is a direct <a class="owp-btn"> child.
   MUST stay `> a.owp-btn`: a bare `> .owp-btn` also matched the NATIVE button widget's wrapper
   (Elementor puts owp-btn on the wrapper div), whose 1.9rem side padding then indented the
   "Află mai multe despre noi" button ~30px away from the column's left edge. */
.owp-page .owp-about__grid > div:first-child { display: flex; flex-direction: column; }
.owp-page .owp-about__grid > div:first-child > a.owp-btn { margin-top: auto; padding: .75rem 1.5rem; font-size: 1rem; line-height: 1.5; }
/* About CTA (native button widget) — vercel metrics: flush left, 28px under the copy,
   12px/24px padding, 16px label. */
.owp-page .owp-about__grid .elementor-widget-button.owp-btn { margin-top: 1.75rem; text-align: left; }
.owp-page .owp-about__grid .elementor-widget-button.owp-btn .elementor-button-wrapper { text-align: left; }
.owp-page .owp-about__grid .elementor-widget-button.owp-btn .elementor-button { padding: .75rem 1.5rem; font-size: 1rem; line-height: 1.5; }
/* "Vezi toate serviciile" — vercel metrics: 48px above the button, 14px/28px padding, 16px label. */
.owp-page .owp-services__more  { margin-top: 3rem; }
.owp-page .owp-services__more .elementor-widget-button.owp-btn .elementor-button { padding: .875rem 1.75rem; font-size: 1rem; line-height: 1.5; }

/* -------------------------------------------------- widget wrappers must not add spacing */
.owp-page .e-con .elementor-widget-container { margin: 0; padding: 0; }

/* -------------------------------------------------- heading/subtitle alignment inside a head */
.owp-page .owp-head .elementor-widget-heading,
.owp-page .owp-head .elementor-heading-title,
.owp-page .owp-head .elementor-widget-text-editor { text-align: center; }
.owp-page .elementor-widget-heading .elementor-heading-title { color: inherit; }

/* Closing CTA band: its heading must stay white on the violet gradient, in BOTH themes, exactly as
   on the code-first build. The rule above (`color: inherit`, 0,3,0) makes the heading inherit the
   body colour, which on the LIGHT theme is near-black -> dark title on a violet band. Repaired by
   specificity only (0,4,0 beats 0,3,0), never with `!important`, and no other value is changed. */
.owp-page .owp-cta-banner .elementor-widget-heading .elementor-heading-title { color: #fff; }

/* (service description styling now scoped to .owp-service__desc p — the old broad
   `.owp-service .elementor-widget-text-editor p` rule was removed: it also hit the num/icon widgets.) */

/* -------------------------------------------------- reviews: quote grows so footers align */
.owp-page .owp-review          { display: flex; flex-direction: column; }
.owp-page .owp-review > .elementor-widget-text-editor { flex: 1; }

/* -------------------------------------------------- service card number (01–06).
   Elementor sets `.elementor-widget{position:relative}`, so the absolute `.owp-service__num`
   was anchoring to its little icon widget instead of the card corner. Make the card's html
   widgets static → the number falls back to `.owp-service` (position:relative) = card corner,
   like code-first. Keep the card clipping the oversized number. */
.owp-page .owp-service .elementor-widget-html { position: static; }
.owp-page .owp-service { overflow: hidden; }

/* -------------------------------------------------- guarantee: icon keeps its fixed size */
.owp-page .owp-guarantee__inner > .elementor-widget-html { flex-shrink: 0; }

/* -------------------------------------------------- CTA banner: keep the button block centered */
.owp-page .owp-cta-banner__inner .elementor-widget-html { text-align: center; }

/* ---- Native-widget bridges (converted from HTML widgets, keep the owp look) ---- */
/* Checklist = native Elementor icon-list (.owp-checklist-el) styled like .owp-checklist */
.owp-checklist-el .elementor-icon-list-items { display: grid; grid-template-columns: 1fr; gap: .75rem 2rem; margin-top: 2.5rem; }
@media (min-width: 640px)  { .owp-checklist-el .elementor-icon-list-items { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .owp-checklist-el .elementor-icon-list-items { grid-template-columns: 1fr 1fr 1fr; } }
.owp-checklist-el .elementor-icon-list-item { align-items: flex-start; padding: 0 !important; }
.owp-checklist-el .elementor-icon-list-item > a { align-items: flex-start; }
.owp-checklist-el .elementor-icon-list-icon { padding-top: .15rem; }
.owp-checklist-el .elementor-icon-list-icon i,
.owp-checklist-el .elementor-icon-list-icon svg { color: var(--owp-success); fill: var(--owp-success); font-size: 1rem; width: 1.1rem; height: 1.1rem; }
.owp-checklist-el .elementor-icon-list-text { font-size: 1rem; color: color-mix(in oklab, var(--owp-fg) 92%, transparent); padding-left: .6rem; }
/* Head -> checklist gap. The 2.5rem above is the code-first value (sections.css .owp-checklist),
   but it never reached the page: widget-icon-list.min.css ships
   `.elementor-widget .elementor-icon-list-items{margin:0}` at the SAME specificity (0,2,0) and is
   enqueued AFTER elementor-native.css (widget CSS loads on render), so it won the tie and the space
   under the section subtitle collapsed to 0. Re-assert it at (0,3,0) — order-independent.
   `display:grid` and `gap` survived because Elementor's rule only resets `margin`. */
.owp-page .owp-checklist-el .elementor-icon-list-items { margin-top: 2.5rem; }

/* Steps = native container(.owp-steps) with per-step containers(.owp-step) + a native num badge */
.owp-page .owp-steps { display: grid; grid-template-columns: 1fr; gap: 1.25rem; margin-top: 3rem; }
@media (min-width: 768px) { .owp-page .owp-steps { grid-template-columns: repeat(3, 1fr); } }
/* Four-step sections lay out 2x2 instead of 3+1 (orphan 4th card on its own row).
   `:has(> :nth-child(4):last-child)` selects only grids whose 4th child is also the last, so the
   twelve 3-card grids cannot match. Specificity (0,4,0) -- `:has()` takes the specificity of its
   most specific argument, the compound `:nth-child(4):last-child` at (0,2,0), on top of
   `.owp-page .owp-steps` -- which beats every Elementor selector that could reach this container
   (`.e-con` (0,1,0); a generated per-element rule would be (0,3,0)). Verified against the served
   sheets: elementor/assets/css/frontend.min.css and uploads/elementor/css/base-desktop.css
   contain zero `owp-` selectors, so nothing here is contested.
   No max-width cap on the grid: cards widen from ~360px to ~550px, deliberately. */
@media (min-width: 768px) { .owp-page .owp-steps:has(> :nth-child(4):last-child) { grid-template-columns: repeat(2, 1fr); } }
/* Step card box: the only card family without a bridge — `.e-con` was giving it the 10px fallback
   padding and no radius. Match code-first sections.css:248 (border + background already survive). */
/* `display` is NOT set here: the card interior is laid out by the "STEP CARD INTERIOR" block at
   the end of this file, which has to sit after the `gap: 0` normalization further down. */
.owp-page .owp-step { padding: 1.75rem; border-radius: var(--owp-radius-xl); }
/* -aa, matching sections.css: the number inside is white text. */
.owp-step .owp-step__num.elementor-element { display: inline-flex; align-self: flex-start; width: 2.5rem; height: 2.5rem; border-radius: var(--owp-radius-lg); background-image: var(--owp-gradient-brand-aa); }
.owp-step .owp-step__num > .elementor-widget-container { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.owp-step .owp-step__num p { margin: 0; color: #fff; font-family: var(--wp--preset--font-family--heading, Poppins), sans-serif; font-weight: 800; line-height: 1; }
/* Step titles that still wrap must wrap readably. Elementor's `.elementor-heading-title{line-height:1}`
   (frontend.min.css) beats base.css's `h1..h6{line-height:1.12}`, so a 2-line title had its lines
   touching. Specificity here is (0,3,1) — it beats `.elementor-heading-title` (0,1,0) and `h1..h6`
   (0,0,1) whatever the load order, so widget-heading.min.css loading later cannot undo it.
   `text-wrap: balance` already comes from base.css:33; restated locally so the wrap behaviour of
   these cards is readable in one place (and survives a narrowing of the global rule). It is what
   keeps the 768-1023px tablet band clean: there the 3-card grids give the title a 174px column at
   768px, and plain greedy wrapping would leave last lines as short as "site" or "fixes". Balanced,
   all 52 step titles break into at most two lines with no orphan at any width in the band (measured
   against the shipped Poppins 700 metrics, 1px steps).
   `overflow-wrap: break-word` never fires on today's corpus (longest single word 129px vs a 174px
   column); it is there so a future longer word breaks instead of spilling out of the card. */
.owp-page .owp-step h3.elementor-heading-title { line-height: 1.25; text-wrap: balance; overflow-wrap: break-word; }

/* ---- Button = native Elementor button widget carrying owp-btn class on the wrapper ----
   Elementor puts .owp-btn on the widget wrapper; the real <a> is .elementor-button. Re-skin the
   <a> to the owp-btn look (ghost by default; gradient/outline via modifier classes). */
/* The owp-btn / owp-btn--primary / owp-btn--outline classes sit on the widget WRAPPER, so the base
   component rules would paint the wrapper as a second full-width button. Neutralize the wrapper; the
   real look lives on the inner .elementor-button below. */
.owp-page .elementor-widget-button.owp-btn { display: block; text-align: inherit; padding: 0; border: 0; background: none; box-shadow: none; border-radius: 0; }
.owp-page .elementor-widget-button.owp-btn .elementor-button-wrapper { display: inline-block; }
/* Size and weight mirror `.owp-btn` in components.css and must stay in step with it — one button
   size across the whole site, and the same size the code-first build uses.
   The four-class selector is what keeps us ahead of Elementor's own `.elementor-widget-button
   .elementor-button` typography rule, which loads later — specificity, not `!important`.
   Contrast is handled by the gradient below, not by this size: the primary variant paints
   --owp-gradient-brand-aa (6% darker), which clears 4.5:1 at normal text size. */
.owp-page .elementor-widget-button.owp-btn .elementor-button {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .7rem 1.4rem; border-radius: var(--owp-radius-pill);
  font-weight: 600; font-size: 1rem; line-height: 1; border: 1px solid transparent;
  background: transparent; color: var(--owp-fg); box-shadow: none; text-decoration: none;
  transition: transform .15s ease, background-color .15s ease, border-color .15s ease, filter .15s ease;
}
.owp-page .elementor-widget-button.owp-btn .elementor-button:active { transform: translateY(1px); }
.owp-page .elementor-widget-button.owp-btn--primary .elementor-button { background-image: var(--owp-gradient-brand-aa); color: #fff; box-shadow: var(--owp-shadow-brand); }
.owp-page .elementor-widget-button.owp-btn--primary .elementor-button:hover { filter: brightness(1.07); color: #fff; }
.owp-page .elementor-widget-button.owp-btn--outline .elementor-button { border-color: var(--owp-border); }
.owp-page .elementor-widget-button.owp-btn--outline .elementor-button:hover { border-color: color-mix(in oklab, var(--owp-brand) 55%, transparent); background: color-mix(in oklab, var(--owp-brand) 9%, transparent); }
/* Arrow on the section CTA buttons (`owp-btn--arrow`). The native button widget can only hold
   plain text, so the arrow is a decorative pseudo-element: the exact lucide `arrow-right` used by
   the reference, drawn with a CSS mask so it takes the brand violet (the label text stays a plain,
   client-editable string in the Elementor panel). */
.owp-page .owp-btn--arrow .elementor-button-content-wrapper { display: inline-flex; align-items: center; gap: .5rem; }
.owp-page .owp-btn--arrow .elementor-button-content-wrapper::after {
  content: ""; width: 1rem; height: 1rem; flex: 0 0 auto; background-color: var(--owp-brand);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* CTA banner button = solid black (Vercel-style), overriding the ghost base skin. */
/* px-8 py-3.5 at 16px/1.5, the reference's banner button -- the only standalone CTA it sets wider
   than px-7. Without this the widget fell back to the ghost base (0.7rem/1.4rem at 15.2px/1) set
   further up, i.e. about 25% smaller than the design and smaller than the hero pair it echoes. */
.owp-page .owp-cta-banner .owp-btn .elementor-button { background: #000; background-image: none; color: #fff; box-shadow: none; border-color: transparent; padding: .875rem 2rem; font-size: 1rem; line-height: 1.5; }
.owp-page .owp-cta-banner .owp-btn .elementor-button:hover { background: #262626; color: #fff; filter: none; }

/* ---- Review card = native container(.owp-review) with text widgets + unicode stars + avatar ---- */
.owp-page .owp-reviews__grid--single { grid-template-columns: 1fr; max-width: 40rem; margin-inline: auto; }
.owp-page .owp-review { padding: 1.5rem; border: 1px solid var(--owp-border); background: var(--owp-card); border-radius: var(--owp-radius-2xl); }
.owp-page .owp-review__quote .elementor-widget-container { flex: 1; }
/* Footer row: 24px of air above the divider + 16px below it, like the reference figcaption
   (`mt-6 pt-4`). The margin-top has to be re-asserted here because Elementor's `.e-con{margin:0}`
   wipes the one sections.css puts on .owp-review__foot — without it the divider sat flush against
   the quote in the card with the longest quote. */
.owp-page .owp-review__foot { flex-direction: row; align-items: center; margin-top: 1.5rem; padding: 1rem 0 0; }
.owp-page .owp-review__meta  { padding: 0; gap: 0; }
/* flex:0 0 auto — as a flex item the avatar was shrinking to 34px wide (an oval, not a circle). */
/* -aa, matching sections.css: the initial inside is white text. */
.owp-page .owp-avatar { width: 2.5rem; height: 2.5rem; flex: 0 0 auto; background-image: var(--owp-gradient-brand-aa); color: #fff; }
.owp-page .owp-avatar .elementor-widget-container { display: contents; }
.owp-page .owp-review p, .owp-page .owp-avatar p { margin: 0; }

/* ---- Feature cards = native container(.owp-feature): icon(text w/ svg) + heading + text ---- */
.owp-page .owp-cards--4 { display: grid; }
@media (min-width: 640px)  { .owp-page .owp-cards--4 { grid-template-columns: repeat(2, 1fr); } }
/* Four across only from 1200px (mirrors sections.css). At 1024 the four tracks were ~228px wide,
   leaving ~180px of text inside the 1.5rem card padding: titles broke mid-word and the body copy
   dropped to roughly three words a line. */
@media (min-width: 1200px) { .owp-page .owp-cards--4 { grid-template-columns: repeat(4, 1fr); } }
.owp-page .owp-feature { gap: 0; padding: 1.5rem; border: 1px solid var(--owp-border); background: var(--owp-card); border-radius: var(--owp-radius-2xl); }
.owp-page .owp-feature__icon, .owp-page .owp-service__icon { align-self: flex-start; width: 3rem; height: 3rem; flex: 0 0 auto; }
.owp-page .owp-feature__icon .elementor-widget-container, .owp-page .owp-service__icon .elementor-widget-container { display: contents; }
.owp-page .owp-feature__desc p { margin: 0; }

/* ---- Service blocks = native container(.owp-service): num badge + icon + heading + desc + icon-list ---- */
.owp-page .owp-service { gap: 0; position: relative; overflow: hidden; padding: 1.5rem; border: 1px solid var(--owp-border); background: var(--owp-card); border-radius: var(--owp-radius-2xl); }
/* Number aligned with the icon: same 1.5rem inset as the card's padding on both sides, and the
   3rem/line-height:1 text box is exactly as tall as the 3rem icon, so the two read as symmetric. */
.owp-page .owp-service__num { position: absolute; right: 1.5rem; top: 1.5rem; z-index: 0; pointer-events: none; }
.owp-page .owp-service__num, .owp-page .owp-service__num p { margin: 0; font-family: var(--wp--preset--font-family--heading, Poppins), sans-serif; font-size: 3rem; font-weight: 800; line-height: 1; color: color-mix(in oklab, var(--owp-fg) 6%, transparent) !important; }
.owp-page .owp-service__desc p { margin: .5rem 0 0; font-size: 1rem; line-height: 1.6; color: var(--owp-muted); }
/* Native service card renders the number/description straight into the text-editor div (no <p>, no
   .owp-service__desc class), so scope colour + spacing to the direct children — keeps the 01-06 numbers
   faint and the copy muted, with the same vertical rhythm as optimwp.local (code-first). */
.owp-page .owp-service > .elementor-widget-heading { margin-top: 1.25rem; }
/* BUGFIX (docs/13 §2.5): the "01/02/03" watermark is ALSO a text-editor widget and, on /servicii/,
   /en/ and /en/services/, a DIRECT child of .owp-service -- so this rule (0,3,0 / 0,3,1) was beating
   `.owp-page .owp-service__num` (0,2,0 / 0,2,1) and rendering the 48px numeral at the card-body size.
   Excluding the numeral widget here is the minimal fix: the selector simply stops matching it, so
   the numeral rule applies unopposed -- no `!important`, and no escalation on either side.
   Written `:not(:where(.owp-service__num))` and NOT `:not(.owp-service__num)` on purpose: a bare
   `:not()` would push this from (0,3,0)/(0,3,1) to (0,4,0)/(0,4,1) and start out-ranking Elementor's
   own per-widget page CSS. `:where()` carries zero specificity, so these three lines score exactly
   what they scored before the fix. (Same trap as §6 note 3 in docs/12.) */
.owp-page .owp-service > .elementor-widget-text-editor:not(:where(.owp-service__num)),
.owp-page .owp-service > .elementor-widget-text-editor:not(:where(.owp-service__num)) p { color: var(--owp-muted); font-size: 1rem; line-height: 1.6; }
.owp-page .owp-service > .elementor-widget-text-editor:not(:where(.owp-service__num)) { margin-top: .5rem; }
.owp-page .owp-service__list-el .elementor-icon-list-items { display: flex; flex-direction: column; gap: .65rem; margin-top: 1.25rem; padding-top: 1.25rem; border-top: 1px solid var(--owp-border); }
/* Elementor's own `.elementor .elementor-element ul.elementor-icon-list-items{padding:0}` (0,3,1)
   out-specifies the rule above (0,3,0) and was collapsing the 20px gap UNDER the divider — the list
   started 1px below the line instead of the reference's 20px. Re-assert it at (0,4,1). */
.owp-page .owp-service .owp-service__list-el ul.elementor-icon-list-items { padding-top: 1.25rem; }
.owp-page .owp-service__list-el .elementor-icon-list-item { align-items: flex-start; padding: 0; }
.owp-page .owp-service__list-el .elementor-icon-list-icon { padding-top: .1rem; }
.owp-page .owp-service__list-el .elementor-icon-list-icon i, .owp-page .owp-service__list-el .elementor-icon-list-icon svg { color: var(--owp-success); fill: var(--owp-success); font-size: .85rem; width: .95rem; height: .95rem; }
.owp-page .owp-service__list-el .elementor-icon-list-text { font-size: 1rem; color: color-mix(in oklab, var(--owp-fg) 90%, transparent); padding-left: .5rem; }

/* ---- About grid: founder column (label,h2,desc,button) + quote card ---- */
.owp-page .owp-about__col { gap: 0; }
.owp-page .owp-about__col > .elementor-widget-button { margin-top: 1.5rem; }
/* The quote card is the SHORTER cell of a two-column grid row whose cells stretch, so it is taller
   than its own content. `justify-content: center` used to park the whole leftover height in two
   equal lumps -- one ABOVE the quotation mark, one BELOW the founder's name (26.7px each on the RO
   homepage at 1440px, on top of the card's own 32px padding, so the visible top/bottom gap read
   59.7px against 33px at the sides). That centring was the ONLY source of it: no leading on the
   quotation glyph, no margin, no min-height contributes.
   Client's instruction (17.08.2026): the gap above the quotation mark and the gap below the name
   must both equal the 32px side padding, the leftover height goes into the single interior gap,
   and the separator line sits centred in that gap -- equidistant from the bottom of the quote and
   the top of the attribution.
   Mechanism: the line is no longer the attribution's `border-top` (which pinned it hard against
   the quote, 0px above / 25px below). It is a 25px-tall strip generated as the card's `::after`,
   ordered between the quote and the attribution, with the 1px rule painted down its middle, and
   `margin-block: auto`. Flexbox splits free space EQUALLY between two auto margins, so at any row
   height the line stays exactly midway. The strip is 25px because that is precisely what the old
   `1px border + 1.5rem padding-top` occupied -- total content height is unchanged, so no card
   changes height at any width.
   `justify-content: center` is kept as the fallback for a browser that fails to generate the
   pseudo-element; auto margins outrank justify-content, so it does not affect what renders now.
   It has to be restated in THIS sheet, because `.e-con.e-flex{justify-content:var(--justify-content)}`
   in Elementor's frontend.min.css is (0,2,0) and prints after sections.css.
   `::after` (not `::before`): Elementor already owns `.e-con:before` for the background overlay,
   where it is `position:absolute`; `.e-con:after` is untouched by Elementor. */
.owp-page .owp-about__quotecard { gap: 0; position: relative; justify-content: center; padding: 2rem; border: 1px solid var(--owp-border); background: var(--owp-card); border-radius: var(--owp-radius-3xl); }
.owp-page .owp-about__quotecard::after {
  content: ""; order: 1; flex: 0 0 auto; align-self: stretch; height: 25px; margin-block: auto;
  background: linear-gradient(var(--owp-border), var(--owp-border)) center / 100% 1px no-repeat;
}
/* The attribution moves after the strip and gives up the rule + top padding it used to carry. */
.owp-page .owp-about__quotecard > .owp-about__person { order: 2; border-top: 0; padding-top: 0; }
.owp-page .owp-quote-mark .elementor-widget-container { display: contents; }
.owp-page .owp-quote-mark svg { width: 2.5rem; height: 2.5rem; color: color-mix(in oklab, var(--owp-brand) 40%, transparent); }
.owp-page .owp-about__label p { margin: 0; }
/* "Despre noi" eyebrow stays violet — the text-editor global colour would otherwise inherit white. */
.owp-page .owp-about__label, .owp-page .owp-about__label p { color: var(--owp-brand); }
.owp-page .owp-about__desc p { margin: 0; }
.owp-page .owp-about__quote p { margin: 0; }
.owp-page .owp-about__person { flex-direction: row; gap: 1rem; padding: 1.5rem 0 0; }
.owp-page .owp-about__person .owp-avatar { width: 3rem; height: 3rem; font-size: 1.125rem; }

/* Service card head fragment (RO home): wrapper vanishes so the absolute num anchors to the card, not the wrapper */
.owp-page .owp-service__head { display: contents; }

/* ---- Contact grid: native info cards + form kept as an HTML widget ---- */
.owp-page .owp-contact__grid { display: grid; }
/* `center`, not `start`: the left column is three short info cards against a full message form,
   so at `start` it hung from the top of a much taller row with a large gap beneath it. */
@media (min-width: 900px) { .owp-page .owp-contact__grid { grid-template-columns: 1fr 1.2fr; align-items: center; } }
.owp-page .owp-contact__cards { gap: 1rem; }
.owp-page .owp-contact-card { flex-direction: row; align-items: flex-start; gap: 1rem; padding: 1.35rem; border: 1px solid var(--owp-border); background: var(--owp-card); border-radius: var(--owp-radius-xl); }
.owp-page .owp-contact-card__icon { align-self: flex-start; width: 2.75rem; height: 2.75rem; flex: 0 0 auto; }
.owp-page .owp-contact-card__icon .elementor-widget-container { display: contents; }
.owp-page .owp-contact-card__body { gap: 0; }
.owp-page .owp-contact-card__val a, .owp-page .owp-contact-card__val p { margin: .25rem 0 0; }

/* ---- FAQ = native Nested Accordion (Elementor 4.x, <details>-based) skinned like .owp-faq ---- */
/* beat Elementor's `.elementor.elementor .e-con > .elementor-widget{max-width:100%}` (0,4,0) */
.owp-page .owp-container.e-con > .elementor-widget.owp-faq { max-width: 48rem; margin-inline: auto; }
.owp-page .owp-faq {
  --n-accordion-title-text-color: var(--owp-fg);
  --n-accordion-title-text-color-hover: var(--owp-brand);
  --n-accordion-title-text-color-active: var(--owp-fg);
  --n-accordion-border-width: 0; --n-accordion-padding: 0;
  --n-accordion-item-title-space-between: 0;
}
.owp-page .owp-faq .e-n-accordion { display: flex; flex-direction: column; gap: .75rem; }
.owp-page .owp-faq details.e-n-accordion-item { border: 1px solid var(--owp-border); background: var(--owp-card); border-radius: var(--owp-radius-lg); overflow: hidden; }
.owp-page .owp-faq .e-n-accordion-item-title { display: flex; align-items: center; gap: 1rem; padding: 1.15rem 1.35rem; cursor: pointer; }
.owp-page .owp-faq .e-n-accordion-item-title-header,
.owp-page .owp-faq .e-n-accordion-item-title-text { margin: 0; font-weight: 600; font-size: 1.25rem; line-height: 1.4; color: var(--owp-fg); }
.owp-page .owp-faq .e-n-accordion-item-title:hover .e-n-accordion-item-title-text { color: var(--owp-brand); }
.owp-page .owp-faq .e-n-accordion-item-title-icon { display: none; }         /* replace chevron with +/- */
.owp-page .owp-faq .e-n-accordion-item-title::after { content: "+"; margin-left: auto; font-size: 1.4rem; line-height: 1; color: var(--owp-brand); flex-shrink: 0; }
.owp-page .owp-faq details[open].e-n-accordion-item .e-n-accordion-item-title::after { content: "\2212"; }
.owp-page .owp-faq .owp-faq__answer-el { padding: 0 1.35rem 1.25rem; }
.owp-page .owp-faq .owp-faq__answer-el, .owp-page .owp-faq .owp-faq__answer-el p { font-size: 1.125rem; color: var(--owp-muted); line-height: 1.65; }
.owp-page .owp-faq .owp-faq__answer-el p { margin: 0; }

/* ---- eyebrow label as a native Text widget ---- */
.owp-page .owp-eyebrow .elementor-widget-container { display: contents; }
.owp-page .owp-eyebrow p { margin: 0; }
.owp-page .owp-page-hero .owp-eyebrow, .owp-page .owp-hero .owp-eyebrow { align-self: center; }
/* Elementor zeroes widget spacing, so force the eyebrow-to-title gap to match code-first (abonamente). */
.owp-page .owp-page-hero .owp-eyebrow { margin-bottom: 1rem !important; }
/* The HOMEPAGE hero's eyebrow no longer needs its own line: the 20px it used to force is now the
   TITLE widget's native top margin (Advanced > Layout > Margin), which is how the hero's other
   three gaps already work — every gap is the top margin of the element below it.
   It had to move there rather than stay a bottom margin on the eyebrow, because helpers.css
   carries `.owp-page .elementor-widget { margin-bottom: 0 !important }` for the whole build: no
   widget on any `.owp-page` can render a bottom margin, from the panel or from anywhere else. */

/* ---- guarantee icon/badge as native Text widgets (glow/blob are empty native containers) ---- */
.owp-page .owp-guarantee__icon { width: 5rem; height: 5rem; flex: 0 0 auto; }
.owp-page .owp-guarantee__icon .elementor-widget-container { display: contents; }
.owp-page .owp-guarantee__badge { align-self: flex-start; }
.owp-page .owp-guarantee__badge .elementor-widget-container { display: contents; }
.owp-page .owp-guarantee__badge p { margin: 0; }

/* ===== FIXES: native-conversion regressions vs the code-first reference ===== */
/* Decorative empty containers must stay ABSOLUTE. Elementor's .e-con forces position:relative, which
   turned the aspect-ratio:1 hero glow into a ~1900px in-flow block that pushed the whole page down. */
.owp-page .owp-page-hero__glow { position: absolute; top: -30%; left: 50%; transform: translateX(-50%); width: min(38rem, 100%); padding: 0; }
.owp-page .owp-guarantee__blob { position: absolute; right: -4rem; top: -4rem; width: 14rem; height: 14rem; padding: 0; }
.owp-page .owp-hero__glow      { position: absolute; }
/* eyebrow pill (green dot + text) — re-assert the inline-flex layout Elementor's widget defaults clobber */
.owp-page .elementor-widget.owp-eyebrow { display: inline-flex; align-items: center; gap: .5rem; }
.owp-page .owp-eyebrow .elementor-widget-container { display: contents; }

/* ===== Container GAP normalization — match code-first rhythm exactly =====
   Elementor gives every flex container a default gap (~16–20px) that DOUBLES with the margin-based
   spacing the code-first design uses (e.g. .owp-review__quote{margin-top:1rem}, .owp-step h3{margin-top:1rem}).
   Zero it on the margin-based containers so the code-first margins alone define the rhythm; the flex-gap
   containers below re-assert the exact gap value code-first uses (their base rules lose to Elementor's). */
.owp-page .owp-section, .owp-page .owp-container, .owp-page .owp-page-hero, .owp-page .owp-page-hero__inner,
.owp-page .owp-head, .owp-page .owp-review, .owp-page .owp-step, .owp-page .owp-about__quotecard,
.owp-page .owp-about__col, .owp-page .owp-guarantee__box, .owp-page .owp-cta-banner__inner { gap: 0; }
.owp-page .owp-guarantee__inner { gap: 2rem; }
.owp-page .owp-review__foot     { gap: .75rem; }
.owp-page .owp-about__person    { gap: 1rem; }

/* ===== FIX round 2 — icon/number centering, title→text spacing, FAQ width ===== */
/* Every icon or number badge was rendering its content top-left. Make the box a centering flex, fill it
   with the widget-container, and neutralize the wpautop <p> line-height + svg baseline so content centers. */
.owp-page .owp-feature__icon, .owp-page .owp-service__icon, .owp-page .owp-step__num,
.owp-page .owp-guarantee__icon, .owp-page .owp-contact-card__icon, .owp-page .owp-avatar {
  display: inline-flex; align-items: center; justify-content: center; text-align: center;
}
.owp-page .owp-feature__icon > .elementor-widget-container, .owp-page .owp-service__icon > .elementor-widget-container,
.owp-page .owp-step__num > .elementor-widget-container, .owp-page .owp-guarantee__icon > .elementor-widget-container,
.owp-page .owp-contact-card__icon > .elementor-widget-container, .owp-page .owp-avatar > .elementor-widget-container {
  display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; margin: 0; padding: 0;
}
.owp-page .owp-feature__icon p, .owp-page .owp-service__icon p, .owp-page .owp-step__num p,
.owp-page .owp-guarantee__icon p, .owp-page .owp-contact-card__icon p, .owp-page .owp-avatar p {
  margin: 0; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.owp-page .owp-feature__icon svg, .owp-page .owp-service__icon svg, .owp-page .owp-guarantee__icon svg,
.owp-page .owp-contact-card__icon svg { display: block; }

/* A touch more breathing room between card titles and their descriptions */
.owp-page .owp-feature__desc p { margin-top: .65rem; }
.owp-page .owp-service__desc p { margin-top: .65rem; }

/* FAQ nested-accordion: fill the 48rem container (stays centered) even when all items are closed */
.owp-page .owp-faq .e-n-accordion, .owp-page .owp-faq details.e-n-accordion-item,
.owp-page .owp-faq .e-n-accordion-item-title { width: 100%; box-sizing: border-box; }

/* ============================================================== CARD HALO — HOVER ONLY
   Mirror of the block at the end of the code-first theme's sections.css -- same token, same
   families, same exclusions. The value lives once, in tokens.css as `--owp-shadow-card-violet`
   (with its own lighter value under :root[data-theme="light"]); change the intensity there.

   The halo appears on pointer hover and is absent at rest; at rest each family keeps whatever
   shadow it already had (`.owp-card` its neutral `--owp-shadow-card`, everything else none).

   HOVER IS POINTER-ONLY: touch screens have no hover state, so on phones and tablets these cards
   simply never show the halo. Intended, not a regression.

   Why here and not in sections.css: elementor-native.css is the LAST theme sheet on this site
   (order: ... components -> sections -> helpers -> elementor/frontend -> elementor-native), so a
   rule written here lands after both the theme's own card painting and Elementor's frontend CSS.
   Nothing that loads after it (widget-heading, widget-icon-list, the uploads/elementor kit CSS)
   declares box-shadow on these elements -- verified against the served files, not assumed.

   Deliberate exclusions, identical to code-first:
   - `.owp-plan--featured` keeps its amber "recommended" glow (box-shadow does not accumulate
     across rules, so including it would silently replace the amber, at rest and on hover alike).
   - `.owp-feature:hover` / `.owp-service:hover` declare their own hover halo in sections.css at
     (0,2,0) and are NOT listed below, so the service cards keep their stronger lift.
   - Chrome/controls are not cards: header, footer, menus, cookie bar, modal, floating buttons,
     pricing toggle, filter/tag pills, section backgrounds.
   The FAQ is a native nested-accordion here (not `.owp-faq__item`), so it needs its own selector
   at the specificity the existing accordion rule uses.
   `.owp-cta-banner` (the closing "Hai sa-ti punem site-ul la punct!" band) is included by the
   brief: not a card, but it takes the same hover halo. It appears on most pages. */
.owp-card,
.owp-step,
.owp-plan:not(.owp-plan--featured),
.owp-faq__item,
.owp-contact-card,
.owp-contact__formbox,
.owp-guarantee__box,
.owp-about__quotecard,
.owp-article-cta,
.owp-article-fig,
.owp-cta-banner { transition: box-shadow .2s ease; }
.owp-page .owp-faq details.e-n-accordion-item { transition: box-shadow .2s ease; }
/* `.owp-review` is absent from the transition lists above and present below: its transition is
   declared with its base rule in sections.css so that `border-color` survives (note is there). */
.owp-card:hover,
.owp-step:hover,
.owp-review:hover,
.owp-plan:not(.owp-plan--featured):hover,
.owp-faq__item:hover,
.owp-contact-card:hover,
.owp-contact__formbox:hover,
.owp-guarantee__box:hover,
.owp-about__quotecard:hover,
.owp-article-cta:hover,
.owp-article-fig:hover,
.owp-cta-banner:hover { box-shadow: var(--owp-shadow-card-violet); }
.owp-page .owp-faq details.e-n-accordion-item:hover { box-shadow: var(--owp-shadow-card-violet); }

/* ============================================================== STEP CARD INTERIOR
   Mirror of the block in the code-first theme's sections.css: the title and body sit BESIDE the
   number instead of under it. Three inherited variables drive it, set on `.owp-steps`:
     --owp-step-cols       track list          1 track = stacked, 2 tracks = side by side
     --owp-step-text-col   column for the text 1 = under the number, 2 = beside it
     --owp-step-title-gap  h3 margin-top       1rem when stacked, 0 when beside (it is on row 1)
   The defaults ARE the stacked layout, so any width no media query opts in keeps the old look.

   Why at the very end of the file: `.owp-page .owp-step` appears in the "Container GAP
   normalization" list above with `gap: 0`, at the same (0,2,0) specificity. A `column-gap`
   written next to the card's padding rule (line ~173) would be reset by it; written here it
   wins on source order. `display` is declared here for the same reason -- one place only.
   Elementor's own container layout (`.elementor-element:where(.e-con-full,...)` at (0,1,0), and
   `.e-con` which only sets custom properties) is beaten by every selector below. */
.owp-page .owp-step {
  display: grid; grid-template-columns: var(--owp-step-cols, minmax(0, 1fr));
  column-gap: 1rem; row-gap: 0;
}
.owp-page .owp-step > .owp-step__num { grid-column: 1; grid-row: 1; }
.owp-page .owp-step > :not(.owp-step__num) { grid-column: var(--owp-step-text-col, 1); min-width: 0; }
/* The widget right after the number is the heading; centring it in its row lines a one-line title
   up with the middle of the 2.5rem badge. A no-op once the title wraps, and in the stacked layout.
   This beats the `align-self: flex-start` that the badge rule sets on itself -- different element,
   no conflict -- and Elementor's `--container-widget-align-self: initial`. */
.owp-page .owp-step > .owp-step__num + * { align-self: center; }
/* Side-by-side is opted into only where the text column stays readable. Measured against the
   72rem container (1120px of content), the card's 1.75rem padding + 1px border, the 2.5rem
   number and the 1rem gap -- i.e. the text column is (card width - 114px):
     one column,    >= 360px viewport : card 328px -> text 214px  (~29 chars of 0.9rem body)
     two columns,   >= 768px viewport : card 358px -> text 244px, growing to 436px at 1152px
     three columns, >=1024px viewport : card 317px -> text 203px, growing to 246px at 1152px
   Below those widths the stacked default stays. Three columns on a 768px tablet would leave a
   118px text column (~12 characters), which is why the 3-card grids wait for 1024px; a 320px
   phone keeps the stack for the same reason. */
@media (min-width: 360px) and (max-width: 767.98px) {
  .owp-page .owp-steps { --owp-step-cols: auto minmax(0, 1fr); --owp-step-text-col: 2; --owp-step-title-gap: 0; }
}
@media (min-width: 768px) {
  .owp-page .owp-steps:has(> :nth-child(4):last-child) { --owp-step-cols: auto minmax(0, 1fr); --owp-step-text-col: 2; --owp-step-title-gap: 0; }
}
@media (min-width: 1024px) {
  .owp-page .owp-steps { --owp-step-cols: auto minmax(0, 1fr); --owp-step-text-col: 2; --owp-step-title-gap: 0; }
}
/* The 1rem that separates a stacked number from its title lives on the h3's margin-top
   (sections.css `.owp-step h3`). Restated at (0,3,1) so the variable can zero it when the title
   moves onto row 1 -- and so no later Elementor sheet can reintroduce a margin here. */
.owp-page .owp-step h3.elementor-heading-title { margin-top: var(--owp-step-title-gap, 1rem); }

/* ==================================================================================
   SECTION HEADS REBUILT AS NATIVE WIDGETS
   The score sections, the two form boxes and the About trust note used to be raw HTML
   with their sizing and alignment written inline on the element. Their heads are now
   `.owp-head` containers holding a real Heading widget, so the look comes from here.
   Only the interactive bodies (score rings, contact forms) are still raw markup.
   ================================================================================== */

/* Left-aligned head. `.owp-head--left` is defined in sections.css at (0,1,0) and loses to the
   centering block near the top of this file; restated at matching specificity, later in source
   order, so the modifier actually wins. Used by the About/Despre trust note (which has no title
   and was left-aligned before the rebuild) and by the two contact form boxes. */
.owp-page .owp-head--left { margin-inline: 0; text-align: left; }
.owp-page .owp-head--left .elementor-widget-heading,
.owp-page .owp-head--left .elementor-heading-title,
.owp-page .owp-head--left .elementor-widget-text-editor { text-align: left; }

/* The form box is a container now, so Elementor's 10px `.e-con` padding and its 20px widget
   gap have to be overridden with the values sections.css already declares for the box. */
.owp-page .owp-contact__formbox { padding: clamp(1.5rem, 3vw, 2.25rem); gap: 0; }

/* Form-box head: a smaller title and a tighter subtitle than a page section head. These two
   values used to live in `style="font-size:1.5rem"` / `style="margin-top:.5rem"` on the raw
   elements; they belong in the sheet. Written at (0,4,0)/(0,3,0) so they beat the generic
   `.owp-page .owp-head ...` title rule regardless of source order. */
.owp-page .owp-contact__formbox .owp-head .elementor-heading-title,
.owp-page .owp-contact__formbox .owp-head__title { font-size: 1.625rem; }
.owp-page .owp-contact__formbox .owp-head__subtitle { margin-top: .5rem; }

/* Two modifiers that replace inline styles on the audit-page form section: it butts straight
   against the section above it, and its container is narrower than the 72rem default. */
.owp-page .owp-section--flush-top { padding-top: 0; }
.owp-page .owp-container--narrow { max-width: 40rem; }

/* ==============================================================================================
   ROUND: nine screen-review defects. Everything below exists because a rule that reads correctly
   in sections.css is silently outranked on this build. The load order on every page is:
     inline element CSS -> block-library -> fonts,tokens,base,components,sections,helpers
     -> elementor/frontend.min.css -> THIS FILE -> widget-heading, widget-icon-list -> kit CSS.
   So a rule here beats frontend.min.css at equal specificity, and the two widget sheets and the
   kit sheet that follow were checked against the served files: neither declares any of the
   properties below on any of these selectors.
   ============================================================================================== */

/* -- 3. Horizontal scrollbar below 1024px ------------------------------------------------------
   The violet blob in the guarantee box is `right:-4rem; top:-4rem`, i.e. 64px outside the box on
   two sides, and sections.css clips it with `.owp-guarantee__box{overflow:hidden}` -- (0,1,0).
   Elementor's `.e-con{overflow:var(--overflow)}` with `--overflow:visible` is ALSO (0,1,0) and
   prints later, so on this build the clip never applied and the blob pushed 64px past the right
   edge of the container. Below 1024px the container has only ~16px of side padding to absorb it,
   so the document itself grew wider than the viewport and every page carrying the box slid
   sideways. Restated at (0,2,0), and the custom property is set too so the value survives even if
   the shorthand is ever taken over by an element setting from the editor. */
.owp-page .owp-guarantee__box { overflow: hidden; --overflow: hidden; }

/* -- 5. Guarantee box: centre the icon + copy pair --------------------------------------------
   The copy beside the shield icon is a nested container, and `.e-con{width:var(--width)}` gives
   every container `width:100%` -- so the copy column always fills whatever is left of the row and
   `justify-content` on its own has nothing to distribute. Capping the ROW at 52rem is what
   actually balances the box: 832px, the same optical column the subtitles and lead-ins use, with
   the paragraph's own 44rem measure sitting comfortably inside it. */
.owp-page .owp-guarantee__inner { max-width: 52rem; margin-inline: auto; }
@media (min-width: 768px) { .owp-page .owp-guarantee__inner { justify-content: center; } }

/* -- 4. Prose measures -------------------------------------------------------------------------
   Section subtitles and money-page lead-ins are TEXT WIDGETS on this build, and Elementor's
   `.elementor.elementor .e-con>.elementor-widget{max-width:100%}` is (0,4,0) -- it beats any
   plain class rule in sections.css no matter what that rule says. These two are written at
   (0,5,0) and (0,5,1) so the measures actually apply, and they carry `margin-inline:auto` so the
   capped block stays centred in its container instead of hugging the left edge.
   The `:not(:has())` guard on the lead-in mirrors sections.css: only a prose block that is
   nothing but paragraphs is a lead-in; the legal documents (which are raw HTML here, not widgets)
   keep the 46rem document measure. */
.owp-page .elementor .e-con > .elementor-widget.owp-head__subtitle { max-width: 52rem; margin-inline: auto; }
/* Lead-in width, client decision 18 August 2026: the intro paragraph block on the money pages (and
   /despre/) is capped at 85 CHARACTERS PER LINE. It was 54rem/864px until 16 August, then the full
   1120px of its container (~129 characters), which is what this line said. The measure itself --
   how 85 characters becomes 738px, and why it is written as a multiple of the paragraph size
   rather than a flat length -- is derived in sections.css on `.owp-prose`; `--owp-prose-measure`
   is declared there, on this very element, so it resolves here with no duplication.
   `margin-inline:auto` keeps the narrower block centred in the 1120px container.
   The legal documents are raw HTML, not widgets, so they are untouched and keep 46rem. */
.owp-page .elementor .e-con > .elementor-widget.owp-prose:not(:has(:is(h1, h2, h3, h4, h5, h6, ul, ol, table, dl))) { max-width: var(--owp-prose-measure); margin-inline: auto; }

/* -- 8. Service checklists start at the same height --------------------------------------------
   The service card is a flex column and the cards in a grid row are all the same height, so
   pushing the tick list to the bottom of the card lines every list up: each card carries exactly
   four ticks, so equal bottoms mean equal tops. `margin-top:auto` on the list widget takes the
   leftover height; the 1.25rem gap above the divider lives on the <ul> inside and is unaffected. */
.owp-page .owp-service > .elementor-widget-icon-list { margin-top: auto; }

/* -- 2. Featured plan reacts on hover ----------------------------------------------------------
   Copy of the sections.css rule, restated after Elementor's frontend sheet so it cannot be
   outranked. Same amber, taken from 42% to 62% and spread wider -- never violet. */
.owp-plan--featured { transition: box-shadow .2s ease; }
.owp-plan--featured:hover { box-shadow: 0 26px 70px -16px color-mix(in oklab, var(--owp-amber) 62%, transparent); }

/* ==============================================================================================
   HOMEPAGE HERO — native rebuild (2026-08-16)
   The hero used to be one raw `html` widget holding the whole `<section class="owp-section
   owp-hero">`. It is now built from native Elementor elements: a Container section (html_tag
   `section`), an empty Container for the glow, a Container for the inner column, a Text widget
   (eyebrow), a Heading widget (h1, with the rotator span inline in its Title), a Text widget
   (lead), a Container with two Button widgets, a Container for the tech band, and one Icon List
   widget (inline view) for the four technology chips.
   Everything below re-asserts what `.e-con` / the Elementor widget sheets clobber. The load order
   on this build is: inline element CSS -> block-library -> fonts,tokens,base,components,sections,
   helpers -> elementor/frontend.min.css -> THIS FILE -> widget-heading.min.css,
   widget-icon-list.min.css -> kit CSS. So the two widget sheets and the kit print AFTER us and a
   tie at equal specificity is lost — every rule here that touches a widget internal is written
   one step more specific than the Elementor rule it has to beat, and the winner was verified
   against the served files, not assumed.
   ============================================================================================== */

/* -- section shell ------------------------------------------------------------------------------
   `overflow` and `text-align` are the two that bite. `.e-con{overflow:var(--overflow)}` with
   `--overflow:visible` and `.e-con-full{text-align:var(--text-align)}` with `--text-align:initial`
   are both (0,1,0) and print after sections.css, so the raw section's `overflow:hidden` (which is
   what CLIPS the glow — it hangs 90px above the hero) and `text-align:center` both lost silently.
   The custom property is set alongside the real property so an editor-side change cannot undo it.
   Vertical padding is NOT here any more: it is a native container setting (Advanced > Padding,
   custom unit). `text-align` stays because it is the inherited default for everything in the hero
   that has no alignment control of its own; the three text widgets set their own on top of it from
   the panel (Style > Alignment), and a widget's own declaration always beats inheritance. */
.owp-page .owp-hero { overflow: hidden; --overflow: hidden; text-align: center; --text-align: center; }

/* Glow: an empty native container. `.e-con{width:var(--width)}` (--width:100%) and
   `z-index:var(--z-index)` (--z-index:revert) are (0,1,0) and print later, so the 42rem circle
   became a full-width block. `aspect-ratio`, `top/left/transform`, the radial gradient and the
   blur all survive from sections.css untouched. */
.owp-page .owp-hero__glow { position: absolute; width: min(42rem, 100%); z-index: 0; padding: 0; }

/* Inner column: `.e-con` forces `z-index:revert` (= auto). The glow paints at z-index 0, so the
   copy has to stay explicitly above it.
   The measure, the centering and the 1rem gutter are NATIVE settings now (Layout > Width =
   `min(54rem, 100%)`, `min(64rem, 100%)` on the English page; Advanced > Margin = auto left/right;
   Advanced > Padding = 0 / 16px). `max-width:none` is the one line that makes that panel value
   real: base.css caps every `.owp-container` at `var(--owp-container)` and sections.css caps
   `.owp-hero__inner` at 54rem (64rem for `html[lang^="en"]`) — none of which Elementor contests,
   so without this the panel's Width could only ever shrink the column, never widen it. */
.owp-page .owp-hero__inner { z-index: 1; max-width: none; }

/* -- headline -----------------------------------------------------------------------------------
   `owp-hero__title` sits on the Heading WIDGET, so the four display-type properties have to be
   restated on the `<h1.elementor-heading-title>` inside it: on the wrapper they would be inherited
   only where the h1 does not set them itself, and base.css sets font-size/weight/letter-spacing on
   every `h1` (0,0,1). 4.25rem, not base.css's 4.5rem — the hero headline is deliberately one step
   smaller than the global h1. (0,4,0) clears widget-heading.min.css (0,2,0) and the kit (0,2,0). */
.owp-page .owp-hero .owp-hero__title .elementor-heading-title {
  font-size: clamp(2.5rem, 6vw, 4.25rem); font-weight: 800; line-height: 1.06; letter-spacing: -.02em;
}

/* -- eyebrow ------------------------------------------------------------------------------------
   The eyebrow is a Text widget now, and the Elementor KIT prints
   `.elementor-widget-text-editor{color:var(--e-global-color-text);font-weight:var(--e-global-typography-
   text-font-weight)}` inline in the head, at (0,1,0) — the same specificity as `.owp-eyebrow` in
   sections.css and later in the document, so it silently repainted the pill's label full white at
   weight 400 instead of muted at 600. Restated at (0,3,0). Deliberately scoped to `.owp-hero`: the
   inner pages' `.owp-page-hero` eyebrows are the same widget and lose the same way, but they are
   outside this change and are left exactly as they render today. */
.owp-page .owp-hero .owp-eyebrow { color: var(--owp-muted); font-weight: 600; }

/* -- lead ---------------------------------------------------------------------------------------
   Measure, top gap and centering are NATIVE widget settings now (Advanced > Layout > Width =
   Custom `min(40rem, 100%)`, and Margin = `1.5rem auto 0 auto`). Note it is the panel's `width`
   that does the work, not its `max-width`: Elementor's own
   `.elementor.elementor .e-con>.elementor-widget{max-width:100%}` is (0,4,0) and outranks the
   element CSS (0,3,0), so a `max-width` alone would be swallowed. Only `color` stays here,
   because the kit rule that repaints the eyebrow repaints this paragraph too. */
.owp-page .elementor .e-con > .elementor-widget.owp-hero__lead { color: var(--owp-muted); }

/* -- CTA row ------------------------------------------------------------------------------------
   Row / centred / wrapping / 12px gap / 32px above / no padding are all NATIVE container settings
   (Layout > Direction, Justify, Wrap, Gap; Advanced > Margin, Padding). The safety-net copy that
   used to sit here was (0,3,0) and printed after the element CSS, so it silently outranked the
   panel — the Margin and Padding fields were inert. Nothing is restated for this row any more;
   `.owp-hero__cta` in sections.css is (0,1,0) and loses to Elementor's later `.e-con` / `.e-con-full`
   consumers at the same specificity, which is exactly what we want. */

/* Hero buttons are the reference's large size (px-7 py-3.5 at 16px/1.5) rather than the ghost base
   the bridge gives every native button. (0,4,0) beats both the base skin above (0,3,0) and
   Elementor's own `.elementor-button.elementor-size-sm` (0,2,0). */
/* `font-family:inherit` is not cosmetic: the kit prints
   `.elementor-widget-button .elementor-button{font-family:var(--e-global-typography-accent-font-family)}`
   = Poppins, at (0,2,0), and a raw `<a class="owp-btn">` never saw it — the old hero buttons were
   set in Inter like the rest of the body copy. Inheriting takes them back to Inter, and with it to
   their original widths (Poppins ran the pair ~11px and ~14px wide). */
.owp-page .owp-hero .elementor-widget-button.owp-btn .elementor-button { padding: .875rem 1.75rem; font-size: 1rem; line-height: 1.5; font-family: inherit; }
/* The hero's primary CTA has NEVER shown the violet glow on this build, and the rebuild must not
   switch it on. Elementor's frontend.min.css ships `.elementor a{box-shadow:none}` at (0,1,1),
   which outranks components.css's `.owp-btn--primary{box-shadow:var(--owp-shadow-brand)}` (0,1,0)
   — and the old hero button was a raw `<a>` inside `.elementor`, so it lost. A native Button's
   `<a>` is reached by the bridge at (0,3,0) instead, which WOULD light the glow up. Suppressed
   here on purpose, so the conversion changes nothing visible.
   (The code-first site has no `.elementor` wrapper and does show the glow — that is a pre-existing
   difference between the two builds, not something this rebuild introduced. Deleting this one line
   is all it takes to bring the Elementor hero in line with the design intent.) */
.owp-page .owp-hero .elementor-widget-button.owp-btn--primary .elementor-button { box-shadow: none; }

/* The arrow is the shared `owp-btn--arrow` pseudo-element, but on the hero it is the same size as
   the old inline SVG (1.05rem) and takes the button's own colour instead of brand violet. */
.owp-page .owp-hero .owp-btn--arrow .elementor-button-content-wrapper::after {
  width: 1.05rem; height: 1.05rem; background-color: currentColor;
}

/* -- technology band ----------------------------------------------------------------------------
   Top margin (4rem), top padding (2rem), the 52rem measure with its auto centering and the divider
   line above the chips are all NATIVE container settings now (Layout > Width; Advanced > Margin,
   Padding; Style > Border = solid, 1px top only, colour `var(--owp-border)`).
   Two theme caps had to be lifted for the panel to be the only source of truth:
   `html[lang^="en"] .owp-hero__techwrap{max-width:52rem;margin-inline:auto}` in sections.css is
   (0,1,1) and beats Elementor's `.e-con{margin-inline-*:var(--margin-inline-*)}` (0,1,0), and its
   `max-width` is uncontested by Elementor altogether. This rule is (0,2,0): it drops the cap and
   re-feeds Elementor's own margin variables, so both pages take their width and their centering
   from the panel and the two languages stay structurally identical. */
.owp-page .owp-hero__techwrap {
  max-width: none;
  margin-inline: var(--margin-inline-start) var(--margin-inline-end);
}

/* The chips are ONE native Icon List widget. The widget WRAPPER carries the `owp-hero__tech` class,
   which sections.css styles as a flex row for the code-first markup; the two lines below take the
   wrapper back to a plain block so the <ul> inside is the flex row. `margin-top:0` neutralises
   sections.css's 2.75rem — the band's spacing belongs to the techwrap container above.
   Everything the panel now owns is gone from here:
     * the inline row itself (display:flex / flex-wrap) comes from Elementor's own
       `.elementor-widget .elementor-icon-list-items.elementor-inline-items` and is driven by the
       widget's View = Inline setting;
     * horizontal centring comes from Alignment = Center (class `elementor-align-center`);
     * the 40px between two chips comes from Space Between, which Elementor implements as
       `margin-inline: calc(40px/2)` on each item — hence no `margin` reset on the item any more.
   `margin: 0` stays on the <ul>: it was already here before this change, neutralising the
   ±8px compensation Elementor ships by default, and it keeps the row box exactly where it is.
   Row spacing when the chips wrap has NO control in Elementor's Icon List, so `row-gap` stays. */
.owp-page .owp-hero .owp-hero__tech { display: block; margin-top: 0; }
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-items.elementor-inline-items {
  align-items: center; row-gap: 1rem; margin: 0; padding: 0;
}
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-items .elementor-icon-list-item {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: 0;
  font-size: 1rem; font-weight: 500; line-height: 1.6; color: var(--owp-muted);
}
/* The kit paints every `.elementor-icon-list-text` with `--e-global-color-secondary` (blue) at
   (0,2,0) and forces the global text weight at (0,3,1). (0,4,1) takes both back to inheritance. */
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-item > .elementor-icon-list-text {
  color: inherit; font-family: inherit; font-size: inherit; font-weight: inherit; padding: 0;
}
/* The WordPress chip is the brighter one. It is deliberately NOT bolder: on the old markup
   `.owp-body .owp-hero__tech span{font-weight:500}` (0,2,1) already outranked
   `.owp-body .owp-hero__tech-wp{font-weight:700}` (0,2,0), so the chip has always rendered at 500
   and only its colour set it apart. Reproduced exactly. */
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-items .elementor-icon-list-item:nth-child(4) {
  color: color-mix(in oklab, var(--owp-fg) 85%, transparent);
}

/* Chip icons. Native Elementor can only put an icon here from an icon library, and this site ships
   neither Font Awesome CSS nor SVG uploads (both were ruled out: one is weight, the other is an
   upload-security hole the client would inherit). They are drawn instead as CSS masks from the
   theme's own stylesheet — the exact same lucide outlines the old inline SVGs used, so the
   silhouettes are identical, at zero requests and zero bytes of markup. The chip TEXT stays a
   plain, client-editable string in the Icon List repeater.
   The icon is keyed to the item's position, so re-ordering the four chips in the panel re-orders
   the icons with the positions, not with the labels; a fifth chip falls back to the first icon. */
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-items .elementor-icon-list-item::before {
  content: ""; flex: 0 0 auto; width: 1.05rem; height: 1.05rem;
  background-color: var(--owp-brand);
  -webkit-mask: var(--owp-chip-icon) center / contain no-repeat;
          mask: var(--owp-chip-icon) center / contain no-repeat;
}
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-items .elementor-icon-list-item {
  --owp-chip-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='13 2 3 14 12 14 11 22 21 10 12 10 13 2'/%3E%3C/svg%3E");
}
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-items .elementor-icon-list-item:nth-child(2) {
  --owp-chip-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E");
}
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-items .elementor-icon-list-item:nth-child(3) {
  --owp-chip-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z'/%3E%3C/svg%3E");
}
.owp-page .owp-hero .owp-hero__tech .elementor-icon-list-items .elementor-icon-list-item:nth-child(4) {
  --owp-chip-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64' fill='%23000'%3E%3Cpath d='M4.548 31.999c0 10.9 6.3 20.3 15.5 24.706L6.925 20.827C5.402 24.2 4.5 28 4.5 31.999z M50.531 30.614c0-3.394-1.219-5.742-2.264-7.57c-1.391-2.263-2.695-4.177-2.695-6.439c0-2.523 1.912-4.872 4.609-4.872 c0.121 0 0.2 0 0.4 0.022C45.653 7.3 39.1 4.5 32 4.548c-9.591 0-18.027 4.921-22.936 12.4 c0.645 0 1.3 0 1.8 0.033c2.871 0 7.316-0.349 7.316-0.349c1.479-0.086 1.7 2.1 0.2 2.3 c0 0-1.487 0.174-3.142 0.261l9.997 29.735l6.008-18.017l-4.276-11.718c-1.479-0.087-2.879-0.261-2.879-0.261 c-1.48-0.087-1.306-2.349 0.174-2.262c0 0 4.5 0.3 7.2 0.349c2.87 0 7.317-0.349 7.317-0.349 c1.479-0.086 1.7 2.1 0.2 2.262c0 0-1.489 0.174-3.142 0.261l9.92 29.508l2.739-9.148 C49.628 35.7 50.5 33 50.5 30.614z M32.481 34.4l-8.237 23.934c2.46 0.7 5.1 1.1 7.8 1.1 c3.197 0 6.262-0.552 9.116-1.556c-0.072-0.118-0.141-0.243-0.196-0.379L32.481 34.4z M56.088 18.8 c0.119 0.9 0.2 1.8 0.2 2.823c0 2.785-0.521 5.916-2.088 9.832l-8.385 24.242c8.161-4.758 13.65-13.6 13.65-23.728 C59.451 27.2 58.2 22.7 56.1 18.83z M32 0c-17.645 0-32 14.355-32 32C0 49.6 14.4 64 32 64s32-14.355 32-32.001 C64 14.4 49.6 0 32 0z M32 62.533c-16.835 0-30.533-13.698-30.533-30.534C1.467 15.2 15.2 1.5 32 1.5 s30.534 13.7 30.5 30.532C62.533 48.8 48.8 62.5 32 62.533z'/%3E%3C/svg%3E");
}

/* ==============================================================================================
   HOMEPAGE SCORE RINGS + BEFORE/AFTER — native rebuild (2026-08-18)
   These were the last two raw `html` widgets on the homepage. They are now built from native
   Elementor elements so the client can edit what the blocks SAY:
     * score ring  = Container `.owp-ring` > Container `.owp-ring__box` > Text `.owp-ring__value`
                     (the number), plus a Text `.owp-ring__label` (the label). The two SVG circles
                     are drawn by optimwp.js — they are chrome, they carry no editable value.
     * before/after = Container `.owp-ba` > Image widget (the "after" picture) + Text
                     `.owp-ba__tag owp-ba__tag--after`, then Container `.owp-ba__before` holding
                     the "before" Image widget + Text `.owp-ba__tag owp-ba__tag--before`. The
                     white divider, the round grip and the range input are built by optimwp.js:
                     Elementor free has no widget for a <button> or an <input type="range">, and
                     all three are inert without JS anyway.
   Everything below only re-asserts what Elementor's `.e-con` base and the kit's widget rules
   clobber; not one value differs from sections.css. The load order is unchanged (this file prints
   after elementor/frontend.min.css but BEFORE the widget sheets and the kit), so anything that
   touches a widget internal is written one step more specific than the rule it must beat.
   ============================================================================================== */

/* -- decorative underline over the ring grid -----------------------------------------------------
   An empty native Container, same technique as the hero glow. `.e-con` sets `width:var(--width)`
   (100%), `height:var(--height)` (auto), `border-radius:var(--border-radius)` (0), a 10px default
   padding and `margin:0` — all (0,1,0), all printed after sections.css, so the whole 4rem × .25rem
   pill lost. Restated here at (0,2,0). The green fill is NOT restated: Elementor never sets a
   background on `.e-con`, so sections.css keeps it. */
.owp-page .owp-underline {
  width: 4rem; height: .25rem;
  margin: .75rem auto 0; padding: 0;
  border-radius: var(--owp-radius-pill);
}

/* -- ring grid ------------------------------------------------------------------------------------
   Same treatment `.owp-cards` / `.owp-services__grid` get: the grid display, the gap and the
   head→grid margin have to be re-asserted because `.e-con` turns every container into a flex box
   with its own gap and `margin:0`. `grid-template-columns` is NOT restated — Elementor only sets
   it on `.e-con.e-grid`, and this container is `e-flex`, so the 2-up / 4-up rule in sections.css
   (including its 1024px breakpoint) applies untouched. */
.owp-page .owp-scores__grid { display: grid; gap: 2rem; margin-top: 3rem; padding: 0; }

/* -- one ring -------------------------------------------------------------------------------------
   `align-items` is the one that bites hardest: Elementor's
   `.elementor-element:where(.e-con-full,.elementor-widget){align-items:var(--align-items)}` resolves
   to `normal` (= stretch) at (0,1,0) after our sheet, so the label would stretch to the full column
   width and print left-aligned instead of shrink-wrapping under the gauge. */
.owp-page .owp-ring { display: flex; flex-direction: column; align-items: center; gap: 1rem; padding: 0; }

/* The gauge box is a fixed 8rem square and the positioning context for the number. `display:block`
   reproduces the plain `<div>` it used to be, so the injected `<svg>` (width/height 100%) fills it
   exactly as before instead of being laid out as a flex item. */
.owp-page .owp-ring__box { display: block; position: relative; width: 8rem; height: 8rem; padding: 0; }

/* The number is a Text widget now, so `.owp-ring__value` lands on the WIDGET div: it has to beat
   `.elementor-widget{position:relative}` (0,1,0) to keep filling the box, and the kit's
   `.elementor-widget-text-editor{font-family:…;font-weight:…;color:var(--e-global-color-text)}`
   (0,1,0), which would otherwise repaint the score near-white in the body font.
   The `p` reset covers the day the client edits the value in the panel: TinyMCE wraps what he
   types in a paragraph, and a stray paragraph margin would knock the digits off centre. */
.owp-page .owp-ring__value {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--wp--preset--font-family--heading, Poppins), sans-serif;
  font-size: 1.875rem; font-weight: 800; color: var(--owp-success);
}
.owp-page .owp-ring__value p { margin: 0; }
/* Same kit rule repaints the label; restated at (0,2,0). */
.owp-page .owp-ring__label { font-size: 1rem; font-weight: 500; color: var(--owp-muted); }
.owp-page .owp-ring__label p { margin: 0; }

/* -- before / after -------------------------------------------------------------------------------
   The frame: `display:block` reproduces the plain `<div>`; `overflow`, `border-radius`, the 3rem
   top margin and the 10px default padding are the four `.e-con` variables that win at (0,1,0).
   `aspect-ratio`, the border, the shadow, `user-select` and `touch-action` are uncontested and stay
   in sections.css. */
.owp-page .owp-ba { display: block; overflow: hidden; margin-top: 3rem; padding: 0; border-radius: var(--owp-radius-3xl); }

/* The clipped half. Elementor forces `--position:relative` and `--width:100%`, which would drop the
   wipe entirely (the "before" picture would cover the whole frame and never move). */
.owp-page .owp-ba__before {
  display: block; position: absolute; inset: 0; overflow: hidden;
  width: var(--owp-ba-pos, 55%); padding: 0;
}

/* Both pictures are Image widgets, and `.elementor-widget{position:relative}` would make each
   `<img>` (absolutely positioned, inset 0) anchor to its own zero-height widget div instead of to
   the frame. Taking the wrapper out of the positioning chain puts them back on the frame. */
.owp-page .owp-ba .elementor-widget-image { position: static; }

/* -- the two pictures themselves (REGRESSION FIX, 18.08.2026) -------------------------------------
   Elementor ships `.elementor img { height: auto; max-width: 100% }` in frontend.min.css. That is
   (0,1,1) — exactly the weight of `.owp-ba img` and `.owp-ba__before img` in sections.css — and it
   is printed later, so it took over BOTH of them the moment the pictures became Image widgets:

     * `height: auto` replaced `height: 100%`, so each picture fell back to its intrinsic ratio and
       rendered 1118x1118 inside a 1118x628 frame (490px cropped away by the frame's `overflow`);
     * `max-width: 100%` replaced `max-width: none` on the clipped half, so the "before" picture was
       additionally squeezed to the width of the wipe — 615px at 55%, 279.5px at 25%, 950.3px at 85%
       — i.e. it re-scaled while the divider was dragged and the seam never lined up.

   Restated here at (0,2,1) with the values read out of sections.css, nothing invented. The order of
   the two rules matters and mirrors sections.css: they tie on `width`, so the more specific intent
   (the clipped half takes its width from the custom property the script sets to the FRAME's width,
   which is what keeps the two halves at the same scale) has to come second. */
.owp-page .owp-ba img { width: 100%; height: 100%; max-width: none; }
.owp-page .owp-ba__before img { width: var(--owp-ba-width, 100%); max-width: none; }

/* The two labels are Text widgets, so the class sits on the widget div: it has to out-rank both
   `.elementor-widget{position:relative}` and the kit's text-editor colour/weight rule, or the
   pills would drop into the flow and lose their dark ink. Sizes, padding and the pill radius are
   uncontested and stay in sections.css. */
.owp-page .owp-ba__tag { position: absolute; font-size: .8125rem; font-weight: 600; }
.owp-page .owp-ba__tag--after  { color: #06210f; }
.owp-page .owp-ba__tag--before { color: var(--owp-bg); }
.owp-page .owp-ba__tag p { margin: 0; }

/* -- proof block: several before/after pairs, one at a time (18.08.2026) ---------------------------
   Used by the security page. The homepage pair is a pair of 16:9 photographs; these are SCREENSHOTS
   of scan reports, each pair with its own aspect ratio (663x230, 413x522, 1359x283). So the fixed
   `aspect-ratio: 16/9` and the `object-fit: cover` of the homepage frame would crop them to pieces.
   Here the frame takes its size from the "after" picture instead: that one is pulled back into the
   normal flow, and because the two pictures of a pair are cropped to EXACTLY the same pixel size,
   the clipped half lands on it precisely and the seam stays true at any width. */
/* `display:block` because an Elementor container is a flex box, and the tab strip the script
   inserts must stack above the panels rather than sit beside them. */
.owp-page .owp-proof { display: block; margin-top: 2.5rem; padding: 0; }

/* The tab label of each panel is read by the script to build the buttons; it is not shown itself. */
.owp-page .owp-proof__label { display: none; }

.owp-page .owp-proof__tabs {
  display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin-bottom: 2rem;
}
.owp-page .owp-proof__tab {
  border: 1px solid var(--owp-border); border-radius: var(--owp-radius-pill);
  background: color-mix(in oklab, var(--owp-card) 70%, transparent);
  color: var(--owp-muted-fg); cursor: pointer;
  padding: .5rem 1rem; font: inherit; font-size: .8125rem; font-weight: 600; line-height: 1.2;
  transition: color .18s ease, background-color .18s ease, border-color .18s ease;
}
.owp-page .owp-proof__tab:hover { color: var(--owp-fg); border-color: color-mix(in oklab, var(--owp-brand) 55%, transparent); }
.owp-page .owp-proof__tab[aria-selected="true"] {
  /* --owp-brand-aa, not --owp-brand: this is a FLAT fill under white 13px text and measured
     3.98 : 1 on rendered pixels; axe-core flagged it independently at 3.97. See tokens.css. */
  background: var(--owp-brand-aa); border-color: var(--owp-brand-aa); color: #fff;
}

/* A panel is a native container, so it carries Elementor's 10px default padding. The `is-ready`
   rule below zeroes it for the pair that is on screen, but that rule never fires on a block with a
   SINGLE panel: initProof() returns before it adds `is-ready` when there is nothing to switch
   between (the homepage block, 18.08.2026). Stated once here so both cases match. */
.owp-page .owp-proof__panel { padding: 0; }

/* Before the script runs, only the first panel exists visually. That is deliberate and is what keeps
   the other pairs off the network: a lazy <img> with no layout box is never fetched. It is also the
   no-JS state — one complete, honest pair with its caption, just without the switcher. */
.owp-page .owp-proof__panel + .owp-proof__panel { display: none; }
.owp-page .owp-proof.is-ready .owp-proof__panel { display: none; }
.owp-page .owp-proof.is-ready .owp-proof__panel.is-active { display: block; padding: 0; }

.owp-page .owp-proof .owp-ba {
  aspect-ratio: auto; width: fit-content; max-width: 100%; margin: 0 auto;
  border-radius: var(--owp-radius-lg);
  /* These are screenshots, not photographs. On the homepage the Before/After chips float over a
     picture with nothing important in the corners; here the top-left corner is the report's own
     "Security Report Summary" title and the chips landed on top of it. So the frame gets a strip
     of its own below the picture and the chips live there. Everything positioned against the
     frame — the clipped half, the divider — is pulled up by the same amount. */
  padding-bottom: 2.75rem;
  background: var(--owp-card);
}
.owp-page .owp-proof .owp-ba__tag { top: auto; bottom: .625rem; }
.owp-page .owp-proof .owp-ba__handle { bottom: 2.75rem; }
/* The "after" picture flows and therefore sets the frame's box. `.owp-ba img` in sections.css and its
   restatement above are both (0,2,1); this is (0,3,1) and wins, as it must. */
.owp-page .owp-proof .owp-ba > .elementor-widget-image img {
  position: relative; width: auto; height: auto; max-width: 100%; display: block;
}
/* The clipped half is cut with `clip-path` instead of the frame's width-plus-overflow trick.
   The homepage version narrows `.owp-ba__before` itself and then compensates by stretching the
   picture inside it to `--owp-ba-width`, a value the script reads from the frame at init. That
   cannot work here: these pictures are lazy, an unloaded <img> has no intrinsic size (the width
   and height attributes only supply an aspect ratio), so the frame measured zero at init and the
   "before" half rendered 0px wide until something fired a resize.
   Leaving the half at full width and clipping it means both pictures are always laid out at
   exactly the same size, so the seam is true from the first paint with no measuring at all. */
/* The clipped half still spans the WHOLE frame, label strip included — the "Înainte" chip lives
   inside it and has to be able to sit in that strip, next to its "După" twin. Only the picture
   inside it stops above the strip. */
.owp-page .owp-proof .owp-ba__before {
  width: 100%;
  clip-path: inset(0 calc(100% - var(--owp-ba-pos, 55%)) 0 0);
}
.owp-page .owp-proof .owp-ba__before img {
  position: absolute; top: 0; left: 0;
  width: 100%; height: calc(100% - 2.75rem); max-width: none; object-fit: fill;
}

.owp-page .owp-proof__caption {
  margin: 1.125rem auto 0; max-width: 46rem; text-align: center;
  font-size: .875rem; line-height: 1.6; color: var(--owp-muted-fg);
}
.owp-page .owp-proof__caption p { margin: 0; }

/* The band around the whole section, mirroring `.owp-scores` on the other money pages. */
.owp-page .owp-proof-band {
  border-block: 1px solid var(--owp-border);
  background: color-mix(in oklab, var(--owp-card) 30%, transparent);
}

/* ============================================================================================
   ELEMENTOR "OPTIMIZED CONTAINER LOADING" -- RESTORE OUR GRADIENTS   (26.08.2026, banda X)
   --------------------------------------------------------------------------------------------
   THE BUG THIS FIXES. 49 heading fragments were INVISIBLE on 19 of the 30 Elementor pages, in
   both languages: `.owp-gradient-text` paints its colour as a gradient clipped to the glyphs
   (`background-image` + `background-clip: text` + `color: transparent`), so when the gradient
   does not paint the words simply are not there. The "RECOMANDAT" badge on /gazduire-wordpress/
   measured 1.01 : 1 (black on black) for the same reason, and the three newest service cards
   showed empty icon tiles next to six that glow.

   THE CAUSE -- measured in a rendered page, not deduced. Elementor's frontend prints this inline,
   as part of its lazy-loading of container backgrounds:

     .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; }

   plus the same rule at n+3 under `max-height: 1024px` and n+2 under `max-height: 640px`. The
   `*` is the damaging part: it does not stop at container backgrounds, it wipes the
   background-image of EVERY descendant -- our gradient text, our icon tiles, our plan badges,
   our primary buttons. Elementor is supposed to lift the suppression by adding `.e-lazyloaded`
   from an IntersectionObserver; measured on /servicii/, scrolling the whole page end to end
   lifts it on 15 of 34 containers and the other 19 stay suppressed forever. So it is not a
   first-paint flicker -- for a real visitor those words never appear.

   NOT THE CONTRAST TOKEN. `--owp-gradient-brand-aa` was the first suspect. It is innocent: it
   resolves correctly on the broken elements (checked with getComputedStyle on the element
   itself), plain `--owp-gradient-brand` elements are hit just the same, and the code-first build
   -- which has no Elementor and no `.e-con` -- renders all 30 pages correctly.

   THE FIX. Re-assert the background of exactly the elements our theme paints, with `!important`,
   from inside the same suppressed containers. Specificity arithmetic, because it is the whole
   point: Elementor's selector is (0,5,0) -- `.e-con` `.e-parent` `:nth-of-type()`
   `:not(.e-lazyloaded)` `:not(.e-no-lazyload)`, the `*` adding nothing. The guard below doubles
   `.e-con` to reach (0,5,0) on its own and every target class takes it to (0,6,0) or more, so it
   wins on specificity alone and does not depend on which sheet loads last.

   WHY NOT SOMETHING BROADER. A blanket un-suppression would need a value per element, and CSS
   has no "undo !important". Enumerating the ~20 rules that actually paint a gradient is longer
   to read but cannot resurrect a background nobody asked for. Hover-only gradients are listed in
   their hover form, so `!important` here does not freeze an icon in its hover state.

   IF ELEMENTOR'S LAZY-LOAD IS EVER TURNED OFF (Elementor > Settings > Features, or by adding
   `e-no-lazyload` to the containers) this block becomes dead weight and can be deleted whole.
   Nothing else in the theme depends on it.
   ============================================================================================ */

/* Brand gradient (blue -> violet) */
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-gradient-text,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-logo__wp,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-service__icon,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-icon-chip,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-guarantee__icon,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-feature:hover .owp-feature__icon,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-post-card__cat:hover
  { background-image: var(--owp-gradient-brand) !important; }

/* Amber gradient (warm) */
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-gradient-text--amber,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-plan--featured .owp-plan__badge
  { background-image: var(--owp-gradient-amber) !important; }

/* The 6%-darker brand gradient -- every white-on-brand surface. Keeping these on the AA token is
   what preserves the 4.5 : 1 contrast fix of docs/29 and docs/35 inside suppressed containers;
   pointing them back at --owp-gradient-brand here would have quietly undone it. */
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-btn--primary,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .elementor-widget-button.owp-btn--primary .elementor-button,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-plan__badge,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-pricing__toggle button.is-active,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-blogfilter__item.is-active,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-pagination .page-numbers.current,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-avatar,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-step__num,
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-cta-banner,
.e-con.e-con.e-parent.owp-cta-banner:not(.e-lazyloaded):not(.e-no-lazyload)
  { background-image: var(--owp-gradient-brand-aa) !important; }

/* Soft radial glows (painted with the `background` shorthand, so the image half is wiped too) */
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-glow
  { background-image: var(--owp-glow) !important; }
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-hero__glow
  { background-image: radial-gradient(circle, color-mix(in oklab, var(--owp-brand) 24%, transparent), transparent 65%) !important; }
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-page-hero__glow
  { background-image: radial-gradient(circle, color-mix(in oklab, var(--owp-brand) 20%, transparent), transparent 65%) !important; }

/* One exception to the block above. The hero's rotating word wants NO gradient on the container
   once JavaScript takes over -- sections.css hands the paint to its `> b` children instead
   (`.owp-rotator.owp-gradient-text.is-live { background-image: none }`). That declaration is not
   `!important`, so the restore above would beat it and paint a second gradient underneath the
   crossfading words if a rotator ever sat in a suppressed container (possible at short viewport
   heights, where Elementor suppresses from the 2nd container down). Put it back. */
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-rotator.owp-gradient-text.is-live
  { background-image: none !important; }

/* ...and the other half of the same exception, which was missed and produced a REAL invisible H1
   (reproduced 05.09.2026: 1 load in 6 at 1440x900, ~250ms after DOMContentLoaded). The word slots
   `.owp-rotator > b` carry NO class, so the enumerated restore list above never reached them.
   Sequence: optimwp.js adds `.is-live`, which moves the paint from the parent down onto each `> b`
   (background-image + background-clip:text + color:transparent). If Elementor has not yet stamped
   `e-lazyloaded` on the hero container at that moment, its blanket `* { background-image: none
   !important }` strips the gradient off the `> b` while `color: transparent` stays -- transparent
   glyphs with nothing painted behind them, i.e. a hole in the headline until the container
   hydrates. Restoring the word slots' own gradient closes it; the parent above stays `none`, so no
   second gradient appears underneath the crossfade. `--owp-rot-grad` carries the amber variant. */
.e-con.e-con.e-parent:not(.e-lazyloaded):not(.e-no-lazyload) .owp-rotator.owp-gradient-text.is-live > b
  { background-image: var(--owp-rot-grad) !important; }

/* ==============================================================================================
   ACCESSIBILITY -- CASCADE FIXES THAT ONLY THIS BUILD NEEDS   (05.09.2026, docs/49)
   ----------------------------------------------------------------------------------------------
   Elementor prints its kit into the page AFTER every theme sheet, so at equal specificity the kit
   wins. Its `link_normal_color` produced `.elementor-kit-57 a { color: #9561F3 }` -- specificity
   (0,1,1), one class plus one element -- which beat every single-class rule this theme has. Two
   distinct defects came out of that one declaration, and both are repaired by specificity, never
   by `!important`.
   The kit setting itself has been changed to `var(--owp-brand)` so link colour follows the theme
   the way it does on the code-first build (that is what removed 56 axe `color-contrast` nodes on
   the light theme). The rule below is still needed: the kit selector also beats `.owp-skip`.
   ============================================================================================== */

/* THE SKIP LINK WAS INVISIBLE. `.owp-skip { color: #fff }` is (0,1,0) and lost to the kit, so the
   link painted violet text on its own violet background: measured 1.00 : 1, a solid violet
   rectangle with no readable word in it -- the one element in the whole audit that disappeared
   completely, and it is the keyboard-navigation affordance. `body a.owp-skip` is (0,1,2) and wins
   over (0,1,1) with no `!important`. The background moves to the flat -aa companion at the same
   time, so the restored white label clears 4.5 : 1 instead of landing on 3.98. */
body a.owp-skip,
body a.owp-skip:focus,
body a.owp-skip:hover { color: #fff; background: var(--owp-brand-aa); text-decoration: none; }

/* "After" tag on the light theme. Written without `.owp-page`, like the code-first rule in
   sections.css, so it also holds on a page that is not an `.owp-page` (a blog article); at (0,2,1)
   it still beats `.owp-page .owp-ba__tag--after` (0,2,0), which pins the near-black
   #06210f on both themes, but the success green underneath goes from oklch(0.78 …) to
   oklch(0.5 …) when the theme flips, so light theme rendered dark-on-dark: 3.11 : 1 measured.
   White on that same green measures 5.48 : 1. Dark theme is untouched (9.20 : 1 there). */
html[data-theme="light"] .owp-ba__tag--after { color: #fff; }

/* Links inside running text must not rely on colour alone (WCAG 1.4.1). Measured, a link differs
   from the paragraph around it by 1.96 : 1 here, far under the 3 : 1 that would let colour carry
   the distinction on its own, and axe-core flags it as `link-in-text-block`. An underline is the
   second signal. Scoped to paragraph and list text inside <main> only, and explicitly excluding
   anything that renders as a button, so navigation, cards, badges and CTAs are untouched. */
.owp-main p a:not(.owp-btn):not(.elementor-button):not([class*="owp-btn"]),
.owp-main li a:not(.owp-btn):not(.elementor-button):not([class*="owp-btn"]) {
  text-decoration: underline; text-underline-offset: 0.15em;
}

/* The onboarding-fee badge is painted by an inline <style> inside its own HTML widget
   (`_elementor_data` on the two pricing pages), at `.owp-page .owp-onboard__badge p` = (0,2,1),
   and it still points at the un-corrected gradient: white 13px text measured 4.20 : 1 on dark.
   Re-pointed at the -aa gradient from here rather than by editing page content; the extra
   `.owp-onboard` class takes this to (0,3,1) so it wins on specificity, not on load order. */
.owp-page .owp-onboard .owp-onboard__badge p { background-image: var(--owp-gradient-brand-aa); }

/* ---------- Pricing-matrix horizontal overflow (docs/44, defect 2) ----------
   At 360 px `/abonamente/` scrolled the whole document 284 px sideways (298 px on `/en/pricing/`).
   The wrapper already does the right thing on its own -- `overflow-x: auto`, 326 px wide over a
   717 px table -- but the table carries `position: sticky` cells in its first column, and a sticky
   descendant inside a scroll container still contributes its full intrinsic width to the scroll
   width of every ancestor above the scroller. `contain: paint` closes that leak: it makes the
   wrapper a containment box, so nothing inside it is measured by the document any more. The table
   keeps its own 717 px scroll range, all 51 rows and all columns, and the sticky feature column
   still pins to the wrapper's left edge (verified at scrollLeft 300).
   `.owp-matrix-panel .owp-matrix-wrap` is (0,3,0) and beats the page's own (0,2,0) rule without
   `!important`. */
.owp-page .owp-matrix-panel .owp-matrix-wrap { contain: paint; }

/* ---------- Amber-as-text contrast (docs/43 point 8, deferred in docs/49) ----------
   The "Recomandat" badge in the pricing matrix is a unicode glyph here, so WCAG measures it as
   text at 4.5 : 1, not as a graphic at 3 : 1. Measured on the rendered pixels it came out at
   3.52 : 1 on the light theme (the review stars, since removed, were at 3.84 : 1) -- the last two
   `color-contrast` nodes axe-core still reported. It takes `--owp-amber-text`, which is the
   unchanged amber on dark and the darker oklch(0.53 0.15 55) on light. The badge rule lives in the
   page's own inline <style> at (0,2,0), so the theme rule adds `html[data-theme]` to reach (0,3,1)
   and win on specificity. Graphic amber -- icon fills, gradients, the amber column tint -- is not
   touched, because at 3 : 1 it already passes. */
html[data-theme] .owp-page .owp-matrix__badge { color: var(--owp-amber-text); }
