/* ===========================================================================
 * evps-pdp.css - storefront product-page component.
 *
 * WHY THIS LIVES IN THE THEME (not inline in the product description):
 * WHMCS 9 sanitises admin-authored product descriptions at RENDER time and strips
 * <style>, <article>, <section>, <svg> and <img>. WHMCS 8.13 did not. An embedded
 * <style> block therefore silently dies on WHMCS 9 and every product page loses its
 * styling. Shipping the CSS from the theme fixes that, loads it once instead of once
 * per product, and survives the store listing's nl2br() (which used to inject <br>
 * into the inline <style> and invalidate the whole stylesheet).
 * Descriptions must only use sanitiser-safe tags: div, span, h1/h3/h4, p, br, ul, li,
 * table/thead/tbody/tr/th/td, small, b, strong, em, a and <i> (Font Awesome icons).
 *
 * TOKEN-DRIVEN: every colour, radius, type size, shadow, font and duration below is
 * read from the theme's --evps-* design tokens with a LIGHT fallback baked into the
 * var(). Consequences, all of them deliberate:
 *   - On evps_1000x the component inherits whatever the admin set in the Style
 *     Manager (or a per-user skin), in dark AND light, with zero component edits.
 *   - On stock Twenty-One / Six, where no --evps-* exist, every fallback fires and the
 *     card renders as a light card that matches the 1000X LIGHT palette exactly. The
 *     fallbacks are literally the 1000X [data-theme="light"] values, so there is one
 *     set of numbers to audit, not two.
 *
 * KNOWN GAP - THIS FILE IS NOT LOADED ON A STOCK THEME. The only <link> that pulls
 * it in lives in templates/evps_1000x/header.tpl, and Twenty-One / Six use their own
 * header.tpl. The .evps-pdp markup lives in tblproducts descriptions, so on a stock
 * theme the markup renders and this stylesheet does not - the fallbacks above are
 * currently unreachable. Closing it needs a ClientAreaHeadOutput hook in
 * modules/addons/evps_theme/hooks.php that emits the <link> from a theme-independent
 * path when the active template is not evps_1000x, then a verification pass on
 * dev.freeit.us with Template switched to twenty-one. Until that lands, treat every
 * "stock theme" fallback below as designed-but-unproven.
 *
 * ONE ACCENT, NO RAINBOW: this file used to ship seven per-family accent blocks
 * (.cf/.vps/.host/.sec/.api/.eng/.dcim) with fourteen hardcoded hues. They are GONE.
 * Those class names are still valid in existing markup - they simply carry no styling
 * now, which is the point: every product page uses the brand primary. Do not
 * reintroduce per-family colour; a storefront that changes hue per SKU reads as seven
 * different websites, and none of those hues followed a rebrand.
 *
 * ACCENT CONTRACT (obey this when adding rules):
 *   --a       decoration only: fills, borders, gradients, tints. Never inked type.
 *   --a-text  anything inked: text, icon glyphs. Mode-adaptive. See its comment for
 *             the one case CSS alone cannot reach (an extreme brand luminance).
 *   --on-a    label colour ON a solid --a fill. Never write a raw #fff there.
 * ======================================================================== */

.evps-pdp{
  /* ---- Brand accent -----------------------------------------------------
     The single accent for every product page: the theme primary. Change
     primary_color in the Style Manager and every product page follows. */
  --a:var(--evps-primary,#3b6cf6);

  /* Second stop of the hero's decorative hairline. DERIVED from --a.
     It used to read var(--evps-accent), which is a SECOND, INDEPENDENT
     Style-Manager field: Tokens.php emits --evps-primary and --evps-accent
     from two separate admin inputs, and the generated evps-1000x-custom.css
     currently ships --evps-accent:#22d3ee (cyan) against a cobalt primary.
     That put a second hue family on the page and made the promise above false
     for the hairline - change primary only and it stayed half-violet; the
     high-contrast profile rewrites --evps-primary and leaves --evps-accent
     alone, giving a navy->mauve hairline. Do NOT "fix" this to
     --evps-primary-hover either: Tokens.php does not regenerate that token
     from primary_color, so it stays stock cobalt after a rebrand, exactly like
     --evps-primary-soft below. */
  --acc:color-mix(in srgb,var(--a) 45%,transparent);

  /* Accent tints. TWO tokens, on purpose:
       --awash  translucent, DECORATIVE ONLY (the hero's radial corner wash).
                Nothing is ever inked on top of it.
       --asoft  OPAQUE - mixed with --s1, not with `transparent` - for every
                fill that carries text or a glyph: the eyebrow, .evps-pdp__plus,
                the icon plates, the highlighted comparison column.
     --asoft used to mix with `transparent`, which kept alpha .13 and composited
     onto whatever sat behind it, so its measured contrast depended on the host
     surface AND on other tints stacking underneath it. Two real failures came
     out of that: the eyebrow chip on the hero's --s2 gradient measured 4.22:1
     in dark at the STOCK brand (no admin change, default render), and a soft
     chip dropped inside the call-out band composited to ~23% accent and fell to
     4.32:1 in light. Mixing with --s1 pins the value, stops tints compounding,
     and lifts both back over AA (5.4:1 dark / 5.9:1 light).
     Both are DERIVED from --a rather than read from --evps-primary-soft: that
     token is a hardcoded rgba() of the STOCK cobalt and is not rewritten when
     the admin changes the brand, so consuming it would leave every tint on this
     page blue after a rebrand. */
  --awash:color-mix(in srgb,var(--a) 13%,transparent);
  --asoft:color-mix(in srgb,var(--a) 13%,var(--s1));
  /* The call-out band's wash is deliberately WEAKER than --asoft so a soft chip
     or icon plate dropped inside the band still reads as a distinct fill. */
  --aband-fill:color-mix(in srgb,var(--a) 7%,var(--s1));
  /* Accent edges. Hoisted into tokens so the color-mix() fallback block below
     has a single place to override (see the long note there). --a-rim covers
     both the tinted-plate borders and the eyebrow dot's ring; the hover rim on
     spec tiles and feature cards is unified at 40% (it was 40/45, a difference
     no one can see). */
  --a-rim:color-mix(in srgb,var(--a) 28%,transparent);
  --a-edge:color-mix(in srgb,var(--a) 40%,var(--bd));
  --a-band:color-mix(in srgb,var(--a) 30%,var(--bd));
  --a-row:color-mix(in srgb,var(--a) 6%,transparent);
  --a-row-hl:color-mix(in srgb,var(--a) 15%,var(--s1));

  /* Accent tuned for TYPE. The raw brand hue is only ~4.5:1 on white and ~4.4:1
     on the dark surface - a marginal pass with no headroom once it sits on the
     --asoft tint. Mixing 30% of the body-text colour into it darkens the accent
     on a light theme and lightens it on a dark one, in one declaration, with no
     mode-specific block and no hardcoded hue. At the stock primary that measures
     7.0:1 light / 6.1:1 dark on the plain surface, and 5.9:1 / 5.4:1 on the
     --asoft tint the chips are actually painted on. It was an 82/18 mix, which
     left the dark eyebrow at 4.22:1 and the colour-blind profile's #0072B2 at
     4.14:1 - both under AA for 11px bold.
     THE LIMIT, and why the var() hook is here: no fixed mix percentage can
     rescue an extreme brand luminance. A #ffd400 brand still measures ~3.1:1 on
     white at any mix that keeps the hue recognisable, and a near-black brand
     fails the same way in dark. The real fix is a luminance-WALKED value
     computed where the brand is known - extend Tokens.php::onColor() to emit
     --evps-primary-text per mode (walk the brand toward the surface-contrasting
     end until it measures >=4.5:1 against #ffffff and against #12161f, then
     alias it from the light/dark token blocks). This var() is the hook: when the
     theme supplies it, it wins; until then the mix is the fallback, which is
     correct for every mid-luminance brand. Do not raise the percentage instead -
     65/35 still leaves #ffd400 at 3.09:1 and only flattens normal brands. */
  --a-text:var(--evps-primary-text,color-mix(in srgb,var(--a) 70%,var(--tx)));

  /* Label colour on a SOLID --a fill (the "most popular" ribbon). The theme
     recomputes --evps-on-primary from the brand's relative luminance, so a light
     brand colour gets near-black type instead of illegible white. Never #fff.
     Tokens.php::onColor() picks the better of #ffffff / #0a0c12, which leaves a
     DEAD BAND: white drops under 4.5:1 once the brand's luminance passes 0.1833
     and near-black does not reach 4.5:1 until 0.19170, so any brand in between
     fails both (worst case 4.4214:1, at the crossover L=0.18748 where the two
     labels tie). NOTE these numbers were re-derived after Tokens.php stopped
     hardcoding 0.0056 as #0a0c12's luminance and started computing the true
     0.00371: the old constant yielded 0.2002 / 4.3457, so a wider and deeper
     dead band than really exists. Do not "restore" those figures - they are the
     signature of the bug that was fixed. The stock #3b6cf6 sits at L=0.18309,
     i.e. white-on-brand measures 4.505:1 - it clears AA by 0.005 of RATIO, not
     of luminance. The ribbon is 10px/700 uppercase - small
     text at 4.5:1, not large text at 3:1 - so that margin is not safe. Closing
     it needs onColor() to darken/lighten the FILL when neither label wins and
     emit the adjusted hue as --evps-primary-strong; the ribbon already reads
     that token (see .evps-pdp__pop) and falls back to --a until it exists. */
  --on-a:var(--evps-on-primary,#ffffff);

  /* Inline links. Honours the admin's link_color when set, falls back to the
     brand primary, then to a literal that clears AA on white (stock Twenty-One's
     own #007bff is only 3.99:1). Darkened/lightened toward --tx exactly like
     --a-text, and it carries the same hook and the same limit: --evps-link
     defaults to --evps-primary (tokens.css), so an admin who sets a light
     primary and never touches link_color gets body links at ~2:1 with no warning.
     --evps-link-text is where a luminance-walked link colour belongs.
     NOTE for future readers: under [data-evps-contrast="high"] and
     [data-evps-a11y="on"] the theme pins --evps-link independently of
     --evps-primary. That decoupling is DELIBERATE accessibility behaviour - the
     link hue is allowed to differ from the accent there. Do not "fix" it into
     --a. Link identification never rests on colour alone here anyway: prose
     links are underlined at rest (see the reset block). */
  --lnk:var(--evps-link-text,color-mix(in srgb,var(--evps-link,var(--evps-primary,#3b6cf6)) 70%,var(--tx)));

  /* Semantic "included" tick. Stays GREEN by house convention - checkmarks are
     --evps-success theme-wide (.evps-tier__feat i, .evps-prod li::before), never
     the accent. --evps-success-text is the mode-aware variant: the base #2bb673
     is only 2.9:1 on white and would fail even the 3:1 non-text floor.
     This is a semantic status hue, not a second BRAND accent: it tracks the
     admin's success_color and both contrast profiles, so a rebrand still
     follows it. The "one accent" rule is about per-SKU brand hues, not about
     status semantics. */
  --ok:var(--evps-success-text,var(--evps-success,#15803d));

  /* ---- Surfaces / text --------------------------------------------------
     Fallbacks are the 1000X [data-theme="light"] values verbatim, so a stock
     render and a 1000X-light render are pixel-identical. */
  --s1:var(--evps-surface,#ffffff);
  --s2:var(--evps-surface-2,#f8fafc);
  --bd:var(--evps-border,#dde3ee);
  --tx:var(--evps-text,#0e1422);
  --tm:var(--evps-text-muted,#4d5567);
  /* Dim text: spec-tile labels, table column heads, the "not included" glyph and
     the footnote. This used to be color-mix(var(--tm) 72%,transparent), which
     composites to ~#848ca0 = 3.35:1 on white - a hard AA failure on 11px
     uppercase type. A solid token removes the alpha dependency (a translucent
     text colour also shifts whenever the card sits on a tinted order-form panel
     instead of white).
     MEASURED IN BOTH MODES, because the light number alone hid a failure:
     light  #5e6878 on #ffffff = 5.6:1, on --s2 #f8fafc = 5.3:1.
     dark   #868fa3 on --s1 #12161f = 5.6:1, on --s2 #181d28 = 5.2:1, on the
            --asoft tint = 4.9:1.
     The dark token was #5d667d, which measured 3.16:1 / 2.94:1 / 2.78:1 - every
     one of the five roles above failed AA on every dark surface, and only the
     prefers-contrast override masked it. It was raised in
     evps-1000x-tokens.css; if that token is ever re-darkened, re-measure here. */
  --td:var(--evps-text-dim,#5e6878);

  /* ---- Shadow / motion --------------------------------------------------
     The theme's shadow tokens are already redefined per theme, per OS
     preference and per high-contrast profile, so adopting them deletes the two
     shadow-override rules this file used to carry and gains those profiles free.
     Note a var() fallback may itself contain commas - the whole tail after the
     first comma is the fallback, which is what makes multi-layer shadows work. */
  --sh-sm:var(--evps-shadow-sm,0 1px 2px rgba(15,23,42,.06),0 0 0 1px rgba(15,23,42,.04));
  --sh-md:var(--evps-shadow-md,0 8px 24px -6px rgba(15,23,42,.10),0 2px 6px rgba(15,23,42,.06));
  --eo:var(--evps-ease-out,cubic-bezier(.22,1,.36,1));
  --dur:var(--evps-dur-base,200ms);

  container-type:inline-size;
  /* A single-product group gives the component the full page width (~2500px), which stretches
     4 spec tiles into near-empty 600px boxes. Cap and centre so a one-product page reads as
     designed; in a 247-560px storefront grid cell this never binds. */
  max-width:1140px;margin-inline:auto;
  /* container-type above applies contain:inline-size, so the width is resolved WITHOUT looking
     at the contents. In a shrink-to-fit parent (float/inline-block/table-cell - what the stock
     order form uses) there is no definite width to take, the box collapses to 0 and every
     character wraps onto its own line. width:100% makes the inline size definite. Do not remove. */
  width:100%;
  /* Companion guard for the same class of parent: min-width:0 stops a flex/grid
     ancestor from refusing to let the box shrink.
     overflow-wrap is deliberately NOT set here - see the container-scoped rule
     immediately below for why. */
  min-width:0;
  /* Declared explicitly, not inherited. Outside .evps-app (the store listing and
     the order form) the card would otherwise fall back to Bootstrap's Helvetica
     stack while every other theme surface renders in Inter - and that silently
     voids the font-variant-numeric:tabular-nums below, because Helvetica/Arial
     have no tabular figures. `inherit` is the correct stock-theme answer: the
     alternative (pinning a font here) fights the host on every stock page to buy
     figure alignment in two places. The numeric classes carry a belt-and-braces
     font-feature-settings:"tnum" as well, which some stacks honour where
     font-variant-numeric is ignored - but on a host whose font has no tabular
     figures at all, the comparison column WILL render ragged. That is an
     accepted stock-theme tradeoff, not a solved problem. */
  font-family:var(--evps-font-sans,inherit);
  color:var(--tx);
  line-height:var(--evps-lh-normal,1.5);
  text-align:left}

/* Long-token protection, GATED ON THE CONTAINER HAVING A REAL WIDTH.
   A long unbroken hostname (server-01.datacenter.enterprisevpssolutions.com)
   otherwise blows out Six's ~250px standard_cart product cell, so the component
   needs word-breaking. But declaring `overflow-wrap:break-word` (or `anywhere`)
   on .evps-pdp itself is inherited by all of it and re-creates, in the
   degenerate zero-width case, the one-character-per-line symptom that
   width:100% above exists to prevent: when the shrink-to-fit parent contains
   ONLY this component, contain:inline-size (implied by container-type) zeroes
   the intrinsic contribution, the parent resolves to 0, width:100% of 0 is 0,
   and at a 0px line box EVERY word "does not fit" - so break-word breaks at
   every character exactly like anywhere does.
   MEASURED, because the difference between the two values is a min-content
   SIZING rule and does not apply here: an 81-char lede in a 0-width float came
   out at 1388.7px tall under BOTH `anywhere` and `break-word`, and at 303.8px
   under `normal`. Swapping anywhere->break-word does not fix this; only not
   applying it at 0 width does.
   A container query is the precise gate: `min-width:1px` is false when the
   container has collapsed, so the degenerate case degrades to word-per-line,
   and true at every real width, where the hostname wraps as intended (verified:
   in a 250px cell the lede's scrollWidth stays inside the box). */
@container (min-width:1px){.evps-pdp *{overflow-wrap:break-word}}

/* ---------------------------------------------------------------------------
   color-mix() FALLBACK. Chrome <111, Firefox <113 and Safari <16.2 have no
   color-mix(). Every accent derivation above is a custom property, so in those
   browsers the token still HOLDS the color-mix token stream - custom properties
   accept any token stream - and only goes wrong when it is substituted into a
   real property. At that point the declaration is "invalid at computed-value
   time" and the property computes to unset, which is worse than it sounds:
     - `color` is inherited, so `color:var(--lnk)` computes to inherit and every
       inline link renders in body-text colour, indistinguishable from prose;
     - `border-color` is not inherited, so it computes to its initial value
       `currentcolor` and a spec tile's hover border snaps from pale grey to
       near-black - it reads as a rendering bug, not an affordance;
     - the hero's `background` shorthand loses BOTH layers, including the plain
       linear-gradient that had nothing wrong with it.
   The usual "declare a literal first, then the fancy value" trick does NOT fix
   this: invalid-at-computed-value-time is resolved AFTER the cascade has already
   discarded the earlier declaration, so the literal never gets a turn. (That
   trick only works when the second value is invalid at PARSE time, i.e. contains
   no var().) Overriding the TOKENS is the only fix that holds, and it is why
   every color-mix in this file is hoisted into one of them - if you add a new
   inline color-mix to a rule below, you have re-opened this bug.
   Every fallback stays on the brand hue or on a neutral surface token, so there
   is still exactly one accent.
   --------------------------------------------------------------------------- */
@supports not (color:color-mix(in srgb,red 50%,blue)){
  .evps-pdp{
    --acc:var(--a);              /* solid hairline instead of a fading one      */
    --awash:transparent;         /* hero keeps its linear-gradient layer        */
    --asoft:var(--s2);           /* neutral raised fill, never a stale hue      */
    --aband-fill:var(--s1);      /* flat band, so a chip on it stays visible    */
    --a-rim:var(--bd);
    --a-edge:var(--bd);          /* hover keeps its lift + shadow, loses the rim */
    --a-band:var(--bd);
    --a-row:transparent;
    --a-row-hl:var(--s2);
    --a-text:var(--evps-primary-text,var(--a));
    --lnk:var(--evps-link-text,var(--evps-link,var(--evps-primary,#3b6cf6)))}
}

/* The universal selector matches DESCENDANTS only, so the root and generated
   content need naming explicitly - Bootstrap's own reset covers ::before/::after
   but a non-Bootstrap host may not. */
.evps-pdp,.evps-pdp *,.evps-pdp *::before,.evps-pdp *::after{box-sizing:border-box}

/* WHY THERE IS NO prefers-color-scheme BLOCK HERE (do not add one back):
   this file used to carry @media (prefers-color-scheme:dark){:root:not([data-theme="light"])...}.
   :root always matches <html>, and stock themes never set data-theme, so on stock
   + OS dark mode that selector matched and painted #12161f cards with #e8ecf5 text
   inside a WHITE Bootstrap page - and anything the component does not explicitly
   colour (inline <a>, <em>) went dark-on-dark. Neither stock theme has a dark
   variant at all, so responding to the OS preference is wrong there by construction.
   The correct model is FOLLOW THE HOST, NEVER GUESS THE HOST: where --evps-* exist
   the component already tracks them in both modes for free; where they do not, the
   host is stock, stock is always light, and the light fallbacks above are the answer.
   The old [data-theme="dark"] rule was deleted for the same reason - it overrode the
   shadows ONLY and left --s1/--tx light, giving dark shadows on a white card. */

/* Defensive resets. Bootstrap leaves <ul> at the UA's 40px padding-left and only
   sizes images via .img-fluid/.img-responsive, which admin-authored markup will
   never carry. Keep list-style:none scoped to the BEM class so an intentional
   bulleted list in a description still gets its bullets.
   SPECIFICITY CEILING, stated honestly: these are class-scoped selectors at
   (0,1,1)-(0,2,1). They beat Bootstrap's element and single-class rules, which is
   the CSS that is definitely present on both stock themes. They do NOT beat an
   ID-scoped host rule such as `#main-body table th` (1,0,2) - declaring a property
   explicitly only wins if the declaring SELECTOR wins. Only the doubled-class
   !important guard at the bottom of this file outranks that, and only for the
   properties it names. Before adding specificity here, dump the real Twenty-One
   and Six stylesheets and grep for `#main-body` to find out which rules actually
   exist, rather than arming against a hypothetical. */
.evps-pdp img{max-width:100%;height:auto;display:block}
.evps-pdp svg{max-width:100%}
.evps-pdp ul,.evps-pdp ol{margin:0;padding-left:1.25em}
/* Prose links are UNDERLINED at rest. Colour alone is not an acceptable link cue
   (WCAG 1.4.1), and it is the cue most likely to be missing here: --lnk is a
   derived value, so on a browser without color-mix it degrades, and on a light
   brand primary it can fall to ~2:1 - the previous `text-decoration:none` left
   nothing behind in either case, having already removed Bootstrap's own working
   affordance. The theme's a11y profile underlines prose links too, but only
   under [data-evps-a11y="on"]; this is the unconditional floor. Links carrying a
   class are authored as buttons/chips in the description markup and keep their
   own affordance. */
.evps-pdp a{color:var(--lnk);text-decoration:underline;text-underline-offset:2px}
.evps-pdp a[class]{text-decoration:none}
.evps-pdp a:hover,.evps-pdp a:focus{color:var(--lnk);text-decoration:underline}
.evps-pdp a[class]:hover,.evps-pdp a[class]:focus{text-decoration:underline}
/* Element floor for unclassed headings. Line 11 sanctions h1/h3/h4 in
   descriptions, but every heading rule below is class-scoped, so a bare <h3>
   fell through to Bootstrap's 1.75rem and the host's margins and read as foreign
   next to a __sec-h. All class-scoped rules below outrank this at (0,2,x), so
   __sec-h and __card h4 still win wherever they apply. */
.evps-pdp h2,.evps-pdp h3{font-size:var(--evps-fs-xl,20px);font-weight:var(--evps-fw-bold,700);
  line-height:var(--evps-lh-tight,1.15);letter-spacing:var(--evps-tracking-tight,-.015em);
  margin:0 0 var(--evps-space-1,4px);color:var(--tx)}
.evps-pdp h4{font-size:var(--evps-fs-md,15px);font-weight:var(--evps-fw-semibold,600);
  margin:0 0 var(--evps-space-2,8px);color:var(--tx)}

/* ---------------------------------------------------------------------------
   Hero. Outer shell radius is --evps-radius-xl (16px) to match .evps-tier, the
   theme's own product card, which re-asserts 16px literally in products.tpl and
   is excluded from the dark-theme 14px!important rewrite. Resting elevation is
   --evps-shadow-sm: the house reads as flat-with-a-1px-border until you point at
   it, and --shadow-lg is reserved for modals and drawers.
   --------------------------------------------------------------------------- */
.evps-pdp .evps-pdp__hero{position:relative;overflow:hidden;
  border:1px solid var(--bd);border-radius:var(--evps-radius-xl,16px);
  padding:var(--evps-space-7,32px) var(--evps-space-7,32px) var(--evps-space-6,24px);
  background:radial-gradient(120% 140% at 100% 0%,var(--awash),transparent 60%),linear-gradient(180deg,var(--s2),var(--s1));
  box-shadow:var(--sh-sm)}
/* House signature: a 2-3px full-bleed gradient hairline marks a card as special.
   Always-on here because a product hero is not a hover target. Both stops are
   the SAME hue - --acc is a translucent ramp of --a, not a second accent - so
   the hairline follows a rebrand end to end. */
.evps-pdp .evps-pdp__hero::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;background:linear-gradient(90deg,var(--a),var(--acc))}

/* "Most popular" ribbon for the recommended tier in a family. Clipped by the
   hero's overflow:hidden above - that is what makes the 45deg corner work.
   Solid accent + --on-a, never a gradient with hardcoded white: the old
   linear-gradient(--a,--acc) put #fff on the LIGHTER stop, which measured under
   2:1 on several palettes. The fill reads --evps-primary-strong first - see the
   --on-a comment for the mid-luminance dead band that token exists to close -
   and falls back to the plain brand until the theme emits it.
   10px/700/uppercase matches .evps-tier__ribbon and .evps-prod__badge. It is
   below the type scale's 11px floor DELIBERATELY, but sourced from the scale
   rather than pinned: --evps-fs-xs is rescaled to 12px/13px under the theme's
   text-size preference, so a hardcoded 10px would be the only type on the card
   that ignored that preference (1px below the scale at default, 3px below at
   xl). calc() keeps it exactly 10px today and one step under from then on.
   Shared with .evps-pdp__spec .l below. */
.evps-pdp .evps-pdp__pop{position:absolute;top:14px;right:-34px;transform:rotate(45deg);
  background:var(--evps-primary-strong,var(--a));color:var(--on-a);
  font-size:calc(var(--evps-fs-xs,11px) - 1px);font-weight:var(--evps-fw-bold,700);
  letter-spacing:var(--evps-tracking-caps,.08em);text-transform:uppercase;
  padding:5px 40px;box-shadow:var(--sh-md)}

/* Eyebrow chip - the house category-chip formula (.evps-prod__badge): tiny,
   uppercase, caps tracking, -soft fill, accent border at ~28-30%.
   The fill is the OPAQUE --asoft, not a translucent tint: this chip sits on the
   hero's own gradient, and compositing an alpha tint over the lighter --s2 end
   is what dropped it to 4.22:1 in dark at the stock brand. Measure this chip on
   the composited fill, never on --s1. */
.evps-pdp .evps-pdp__eyebrow{position:relative;display:inline-flex;align-items:center;gap:var(--evps-space-2,8px);
  font-size:var(--evps-fs-xs,11px);font-weight:var(--evps-fw-bold,700);
  letter-spacing:var(--evps-tracking-caps,.08em);text-transform:uppercase;
  color:var(--a-text);background:var(--asoft);
  border:1px solid var(--a-rim);
  padding:var(--evps-space-1,4px) var(--evps-space-3,12px);border-radius:var(--evps-radius-pill,999px)}
/* 50% is an intentional circle, not an off-scale radius. The 4px ring spread is
   a literal: there is no ring-width token in the theme. */
.evps-pdp .evps-pdp__eyebrow .dot{width:7px;height:7px;border-radius:50%;background:var(--a);box-shadow:0 0 0 4px var(--a-rim)}

/* Page-level h1. Capped at --evps-fs-3xl (30px) rather than the old off-scale
   34px - 30px is also the theme's own --evps-section-title-size default. */
.evps-pdp .evps-pdp__title{position:relative;
  font-size:clamp(var(--evps-fs-2xl,24px),3.4vw,var(--evps-fs-3xl,30px));
  line-height:var(--evps-lh-tight,1.15);letter-spacing:var(--evps-tracking-tight,-.015em);
  font-weight:var(--evps-fw-bold,700);
  margin:var(--evps-space-4,16px) 0 var(--evps-space-3,12px);
  color:var(--tx);text-wrap:balance}
/* 1.55 matches .evps-prod, the theme's canonical product-copy block. Sourced
   from --evps-lh-prose (added to evps-1000x-tokens.css alongside the rest of the
   --evps-lh-* scale) rather than pinned, so prose line-height stays adjustable
   in one place; the literal fallback keeps stock renders identical. */
.evps-pdp .evps-pdp__lede{position:relative;max-width:62ch;font-size:var(--evps-fs-md,15px);line-height:var(--evps-lh-prose,1.55);color:var(--tm);margin:0}

.evps-pdp .evps-pdp__chips{position:relative;display:flex;flex-wrap:wrap;gap:var(--evps-space-2,8px);margin-top:var(--evps-space-5,20px)}
/* Factual chip: neutral surface + plain border, accent restricted to the glyph.
   Contrast with the eyebrow above, which is the tinted/promotional variant. */
.evps-pdp .evps-pdp__chip{display:inline-flex;align-items:center;gap:var(--evps-space-2,8px);
  font-size:var(--evps-fs-sm,12px);font-weight:var(--evps-fw-semibold,600);
  color:var(--tx);background:var(--s2);border:1px solid var(--bd);
  border-radius:var(--evps-radius-pill,999px);padding:var(--evps-space-2,8px) var(--evps-space-3,12px)}
/* Fixed width + centring so a Font Awesome glyph that failed to load collapses to
   whitespace instead of shifting the row. */
.evps-pdp .evps-pdp__chip i{color:var(--a-text);font-size:var(--evps-fs-sm,12px);width:14px;text-align:center}

.evps-pdp .evps-pdp__sec{margin-top:var(--evps-space-7,32px)}
.evps-pdp .evps-pdp__sec-h{font-size:var(--evps-fs-xl,20px);font-weight:var(--evps-fw-bold,700);
  letter-spacing:var(--evps-tracking-tight,-.015em);margin:0 0 var(--evps-space-1,4px);color:var(--tx);text-wrap:balance}
.evps-pdp .evps-pdp__sec-sub{color:var(--tm);margin:0 0 var(--evps-space-4,16px);font-size:var(--evps-fs-base,14px)}

/* ---------------------------------------------------------------------------
   Spec tiles. Inner tiles sit one radius step below the outer shell:
   --evps-radius-lg (12px), same as .evps-card / .evps-stat / .evps-service-card.
   --------------------------------------------------------------------------- */
.evps-pdp .evps-pdp__specs{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--evps-space-3,12px)}
.evps-pdp .evps-pdp__spec{border:1px solid var(--bd);border-radius:var(--evps-radius-lg,12px);
  padding:var(--evps-space-4,16px);background:var(--s1);box-shadow:var(--sh-sm);
  transition:transform var(--dur) var(--eo),border-color var(--dur),box-shadow var(--dur)}
/* Elevation is a hover affordance here, not a resting state, and the faint accent
   rim on hover is the house's premium tell. -3px is the inner-tile lift (outer
   storefront cards use -4px, in-app dashboard cards -1px). */
.evps-pdp .evps-pdp__spec:hover{transform:translateY(-3px);border-color:var(--a-edge);box-shadow:var(--sh-md)}
/* Icon-chip formula: rounded-square plate, grid/place-items:center, -soft fill,
   accent glyph. 30px plate -> --evps-radius-md, matching .evps-stat__icon. */
.evps-pdp .evps-pdp__spec .ic{width:30px;height:30px;display:grid;place-items:center;
  border-radius:var(--evps-radius-md,8px);margin-bottom:var(--evps-space-3,12px);
  color:var(--a-text);background:var(--asoft)}
.evps-pdp .evps-pdp__spec .ic i{font-size:var(--evps-fs-md,15px)}
/* line-height:1 is optical trim on a single-line figure, not an un-tokenised
   value - a numeral with no descenders needs no leading, and the token scale has
   no "none" step. Deliberate. */
.evps-pdp .evps-pdp__spec .n{font-size:var(--evps-fs-2xl,24px);font-weight:var(--evps-fw-bold,700);
  letter-spacing:var(--evps-tracking-tight,-.015em);line-height:1;color:var(--tx);
  font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.evps-pdp .evps-pdp__spec .n small{font-size:var(--evps-fs-sm,12px);font-weight:var(--evps-fw-semibold,600);color:var(--tm);letter-spacing:var(--evps-tracking-normal,0)}
.evps-pdp .evps-pdp__spec .l{margin-top:var(--evps-space-1,4px);font-size:var(--evps-fs-xs,11px);
  color:var(--td);text-transform:uppercase;letter-spacing:var(--evps-tracking-caps,.08em);font-weight:var(--evps-fw-semibold,600)}

/* ---------------------------------------------------------------------------
   Feature cards. --evps-card-pad is density-aware (20px, 14px under
   [data-density="compact"]) and is the idiomatic choice over a literal 20px.
   --------------------------------------------------------------------------- */
.evps-pdp .evps-pdp__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:var(--evps-space-4,16px)}
.evps-pdp .evps-pdp__card{border:1px solid var(--bd);border-radius:var(--evps-radius-lg,12px);
  padding:var(--evps-card-pad,20px);background:var(--s1);box-shadow:var(--sh-sm);
  transition:transform var(--dur) var(--eo),border-color var(--dur),box-shadow var(--dur)}
.evps-pdp .evps-pdp__card:hover{transform:translateY(-3px);border-color:var(--a-edge);box-shadow:var(--sh-md)}
/* 38px plate -> --evps-radius-md, matching .evps-service-card__icon. */
.evps-pdp .evps-pdp__card .ic{width:38px;height:38px;display:grid;place-items:center;
  border-radius:var(--evps-radius-md,8px);margin-bottom:var(--evps-space-3,12px);
  color:var(--a-text);background:var(--asoft);border:1px solid var(--a-rim)}
.evps-pdp .evps-pdp__card .ic i{font-size:var(--evps-fs-lg,17px)}
/* Card titles are small here by house rule - .evps-card__title, .evps-tier__name
   and .evps-service-card__name are all 14-17px/600. A 20px+ card heading reads as
   foreign immediately. Do not "fix" this upward. */
.evps-pdp .evps-pdp__card h4{margin:0 0 var(--evps-space-2,8px);font-size:var(--evps-fs-md,15px);font-weight:var(--evps-fw-semibold,600);color:var(--tx)}
.evps-pdp .evps-pdp__card p{margin:0;color:var(--tm);font-size:var(--evps-fs-base,14px);line-height:var(--evps-lh-prose,1.55)}

/* ---------------------------------------------------------------------------
   Feature list. Body copy defaults to muted and <b> promotes it to full --tx,
   which is the house pattern (.evps-prod strong), not the reverse.
   Glyphs stay accent because a description author picks arbitrary icons here;
   only the comparison table's unambiguous "included" tick goes green.
   --------------------------------------------------------------------------- */
.evps-pdp .evps-pdp__list{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:var(--evps-space-3,12px) var(--evps-space-5,20px);margin:0;padding:0;list-style:none}
.evps-pdp .evps-pdp__list li{display:flex;gap:var(--evps-space-3,12px);align-items:flex-start;font-size:var(--evps-fs-base,14px);color:var(--tx)}
.evps-pdp .evps-pdp__list li i{flex:0 0 auto;color:var(--a-text);font-size:var(--evps-fs-md,15px);margin-top:3px;width:16px;text-align:center}
.evps-pdp .evps-pdp__list li b{font-weight:var(--evps-fw-semibold,600);color:var(--tx)}
.evps-pdp .evps-pdp__list li span{color:var(--tm);font-weight:var(--evps-fw-regular,400)}

/* ---------------------------------------------------------------------------
   Call-out band. Its wash is --aband-fill (7% accent), deliberately weaker than
   the 13% --asoft used by the chips and plates that sit INSIDE it, so a
   soft-filled chip still reads as a distinct fill rather than melting into the
   band's tinted end. Because --asoft is opaque, those chips no longer stack
   their tint on top of the band's - which is what used to drop
   .evps-pdp__plus to 4.32:1 in light at the stock brand.
   --------------------------------------------------------------------------- */
.evps-pdp .evps-pdp__band{margin-top:var(--evps-space-6,24px);overflow:hidden;
  border-radius:var(--evps-radius-xl,16px);border:1px solid var(--a-band);
  background:linear-gradient(120deg,var(--aband-fill),var(--s1));
  padding:var(--evps-space-5,20px) var(--evps-space-6,24px);
  display:flex;gap:var(--evps-space-4,16px);align-items:center;flex-wrap:wrap}
/* 46px plate at --evps-radius-lg, matching .evps-tier__icon on the storefront
   product card. It used to be a gradient plate with a hardcoded white glyph and a
   coloured drop-shadow - that is the marketing dialect from homepage.tpl, it does
   not belong beside product cards, and white on the gradient's lighter stop fell
   below even the 3:1 non-text floor. The -soft plate is both house-correct and
   contrast-safe on any brand hue. */
.evps-pdp .evps-pdp__band .bic{width:46px;height:46px;flex:0 0 auto;display:grid;place-items:center;
  border-radius:var(--evps-radius-lg,12px);color:var(--a-text);background:var(--asoft);
  border:1px solid var(--a-rim)}
.evps-pdp .evps-pdp__band .bic i{font-size:var(--evps-fs-xl,20px)}
.evps-pdp .evps-pdp__band .bt{flex:1;min-width:220px}
.evps-pdp .evps-pdp__band .bt strong{display:block;font-size:var(--evps-fs-lg,17px);font-weight:var(--evps-fw-semibold,600);margin-bottom:3px;color:var(--tx)}
.evps-pdp .evps-pdp__band .bt span{color:var(--tm);font-size:var(--evps-fs-base,14px)}
.evps-pdp .evps-pdp__plus{display:inline-flex;align-items:center;gap:var(--evps-space-2,8px);
  font-size:var(--evps-fs-sm,12px);font-weight:var(--evps-fw-bold,700);
  letter-spacing:var(--evps-tracking-caps,.08em);text-transform:uppercase;
  color:var(--a-text);background:var(--asoft);border:1px solid var(--a-rim);
  padding:var(--evps-space-1,4px) var(--evps-space-3,12px);border-radius:var(--evps-radius-pill,999px);margin-bottom:var(--evps-space-3,12px)}

/* ---------------------------------------------------------------------------
   Plan comparison matrix.
   Every geometry AND paint property is set explicitly (width, margin,
   border-collapse, padding, text-align, vertical-align, border, background)
   because some stock WHMCS CSS carries broad `#main-body table` rules and
   Bootstrap ships `.table-striped tbody tr:nth-of-type(odd)`. Leaving
   `background` unset let a host's zebra striping paint straight through the
   tbody, which destroys the meaning of the highlighted column - the one tinted
   region the design has. `border:0` already resets border-top, so a host's
   `td{border-top:1px solid #ddd}` cannot double up with our border-bottom.
   Read the specificity note on the reset block above before assuming this is
   sufficient against an ID-scoped host rule: it is not.
   --------------------------------------------------------------------------- */
.evps-pdp .evps-pdp__compare{margin-top:var(--evps-space-4,16px);border:1px solid var(--bd);
  border-radius:var(--evps-radius-xl,16px);overflow:hidden;background:var(--s1);box-shadow:var(--sh-sm)}
.evps-pdp .evps-pdp__ctab-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.evps-pdp .evps-pdp__ctab{width:100%;margin:0;border-collapse:collapse;border-spacing:0;min-width:560px;font-size:var(--evps-fs-base,14px)}
.evps-pdp .evps-pdp__ctab th,.evps-pdp .evps-pdp__ctab td{padding:var(--evps-space-3,12px) var(--evps-space-4,16px);border:0;border-bottom:1px solid var(--bd);text-align:left;vertical-align:middle;background:var(--s1)}
.evps-pdp .evps-pdp__ctab thead th{font-size:var(--evps-fs-xs,11px);text-transform:uppercase;
  letter-spacing:var(--evps-tracking-caps,.08em);color:var(--td);font-weight:var(--evps-fw-bold,700);
  background:var(--s2);vertical-align:bottom}
.evps-pdp .evps-pdp__ctab thead th.plan{text-align:center;color:var(--tx);font-size:var(--evps-fs-base,14px);letter-spacing:var(--evps-tracking-normal,0);text-transform:none}
.evps-pdp .evps-pdp__ctab thead th.plan small{display:block;font-size:var(--evps-fs-xs,11px);font-weight:var(--evps-fw-semibold,600);color:var(--td);margin-top:3px;text-transform:none;letter-spacing:var(--evps-tracking-normal,0)}
.evps-pdp .evps-pdp__ctab thead th.hl,.evps-pdp .evps-pdp__ctab thead th.hl small{color:var(--a-text)}
.evps-pdp .evps-pdp__ctab tbody .feat{color:var(--tx);font-weight:var(--evps-fw-semibold,600)}
.evps-pdp .evps-pdp__ctab tbody td.cell{text-align:center;color:var(--tm)}
.evps-pdp .evps-pdp__ctab td.hl{background:var(--asoft)}
.evps-pdp .evps-pdp__ctab td.hl.cell{color:var(--tx)}
.evps-pdp .evps-pdp__ctab .yes i{color:var(--ok);font-size:var(--evps-fs-base,14px)}
.evps-pdp .evps-pdp__ctab td.hl .yes i{color:var(--a-text)}
.evps-pdp .evps-pdp__ctab .no{color:var(--td);font-size:var(--evps-fs-md,15px)}
.evps-pdp .evps-pdp__ctab .val{font-weight:var(--evps-fw-semibold,600);color:var(--tx);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.evps-pdp .evps-pdp__ctab tbody tr:last-child td{border-bottom:0}
.evps-pdp .evps-pdp__ctab tbody tr:hover td{background:var(--a-row)}
.evps-pdp .evps-pdp__ctab tbody tr:hover td.hl{background:var(--a-row-hl)}
.evps-pdp .evps-pdp__cnote{margin:var(--evps-space-3,12px) 2px 0;font-size:var(--evps-fs-sm,12px);color:var(--td)}

/* ---------------------------------------------------------------------------
   Container-adaptive: compact card in a narrow grid cell, full page in a wide
   column. These are CONTAINER queries, not viewport queries - the same product
   renders as a ~300px storefront tile and as a ~1140px product page.
   --------------------------------------------------------------------------- */
.evps-pdp .evps-pdp__detail{display:none}
@container (min-width:480px){.evps-pdp .evps-pdp__detail{display:block}.evps-pdp .evps-pdp__band.evps-pdp__detail{display:flex}}
/* Every spec set is 4 tiles. auto-fit lands on 3 columns in a mid-width card and orphans the
   4th on its own row, so pin 2x2 until there is room for a clean single row of four. */
@container (min-width:480px) and (max-width:759px){.evps-pdp .evps-pdp__specs{grid-template-columns:1fr 1fr}}
@container (max-width:479px){
  .evps-pdp .evps-pdp__hero{padding:var(--evps-space-5,20px) var(--evps-space-4,16px);border-radius:var(--evps-radius-lg,12px)}
  .evps-pdp .evps-pdp__title{font-size:var(--evps-fs-xl,20px);margin:var(--evps-space-3,12px) 0 var(--evps-space-2,8px)}
  .evps-pdp .evps-pdp__lede{font-size:var(--evps-fs-base,14px)}
  .evps-pdp .evps-pdp__chips{margin-top:var(--evps-space-3,12px);gap:var(--evps-space-2,8px)}
  .evps-pdp .evps-pdp__chip{font-size:var(--evps-fs-xs,11px);padding:5px var(--evps-space-3,12px)}
  .evps-pdp .evps-pdp__sec{margin-top:var(--evps-space-4,16px)}
  /* The at-a-glance spec tiles are the highest-signal content on the card, so they stay
     visible when everything else in __detail collapses - a storefront grid cell is ~247-351px
     and products link straight to the cart, so a wide container never happens there. NEVER
     class the spec section .evps-pdp__detail: that would hide it from every customer browsing
     the store. The section heading/sub are prose the card has no room for; the tiles carry
     the meaning, so only those two are hidden. */
  .evps-pdp .evps-pdp__sec--specs{margin-top:var(--evps-space-4,16px);padding-top:var(--evps-space-4,16px);border-top:1px solid var(--bd)}
  .evps-pdp .evps-pdp__sec--specs .evps-pdp__sec-h,.evps-pdp .evps-pdp__sec--specs .evps-pdp__sec-sub{display:none}
  .evps-pdp .evps-pdp__specs{grid-template-columns:1fr 1fr;gap:var(--evps-space-2,8px)}
  .evps-pdp .evps-pdp__spec{padding:var(--evps-space-3,12px);border-radius:var(--evps-radius-md,8px)}
  .evps-pdp .evps-pdp__spec .ic{width:24px;height:24px;border-radius:var(--evps-radius-sm,6px);margin-bottom:var(--evps-space-2,8px)}
  .evps-pdp .evps-pdp__spec .ic i{font-size:var(--evps-fs-sm,12px)}
  .evps-pdp .evps-pdp__spec .n{font-size:var(--evps-fs-lg,17px)}
  .evps-pdp .evps-pdp__spec .n small{font-size:var(--evps-fs-xs,11px)}
  /* One step BELOW --evps-fs-xs, computed from it rather than pinned at 10px:
     these labels are 2-up in a ~350px cell and wrap at the full 11px, but a
     literal would ignore the theme's text-size preference entirely (--evps-fs-xs
     becomes 12px/13px under lg/xl). Shared formula with __pop.
     They also switch from --td to --tm here: this is the narrow-container render
     every browsing customer sees, and it would otherwise pair the SMALLEST type
     on the card with the WEAKEST text colour. --tm measures 7.4:1 light /
     7.2:1 dark, against --td's 5.6:1 / 5.2:1. */
  .evps-pdp .evps-pdp__spec .l{font-size:calc(var(--evps-fs-xs,11px) - 1px);margin-top:var(--evps-space-1,4px);color:var(--tm)}
  .evps-pdp .evps-pdp__spec:hover{transform:none}
}
/* Container-query fallback (Chrome <105, Safari <16, Firefox <110, older Android
   WebViews). Those browsers drop every @container block above, including the one
   that RE-SHOWS __detail, so the unconditional `display:none` on __detail would
   never be overridden at any viewport width and the feature cards, call-out band
   and comparison table would be permanently invisible. This block restores the
   wide state and re-applies the narrow one by viewport instead. The `display:flex`
   variant must be carried over or the band renders as a broken block, and the
   narrow hide must name the band too - `.evps-pdp .evps-pdp__band.evps-pdp__detail`
   is (0,3,0) and would otherwise outrank a (0,2,0) hide. */
@supports not (container-type:inline-size){
  /* No container-type here means no contain:inline-size, so the zero-width
     collapse the gate above guards against cannot happen - long-token breaking
     is safe to apply unconditionally. */
  .evps-pdp *{overflow-wrap:break-word}
  .evps-pdp .evps-pdp__detail{display:block}
  .evps-pdp .evps-pdp__band.evps-pdp__detail{display:flex}
  @media (max-width:600px){
    .evps-pdp .evps-pdp__detail,.evps-pdp .evps-pdp__band.evps-pdp__detail{display:none}
  }
}
@media (max-width:560px){.evps-pdp .evps-pdp__hero{padding:var(--evps-space-5,20px) var(--evps-space-4,16px)}}

/* Reduced motion. The theme zeroes --evps-dur-* under this preference, so on
   evps_1000x --dur already resolves to 0ms - but on a stock theme --evps-dur-base
   is undefined and --dur falls back to the LITERAL 200ms, which would animate for
   a user who opted out. This block is what makes the guarantee hold everywhere.
   Every animated surface in the theme ships one; it is not optional. */
@media (prefers-reduced-motion:reduce){
  .evps-pdp .evps-pdp__spec,.evps-pdp .evps-pdp__card{transition:none}
  .evps-pdp .evps-pdp__spec:hover,.evps-pdp .evps-pdp__card:hover{transform:none}
}

/* Legacy-markup compatibility: descriptions authored before the WHMCS-9 rewrite embed inline
   <svg> icons instead of Font Awesome <i>. They still render on WHMCS 8 (9 strips <svg>), so
   size them here or they balloon to full container width. */
.evps-pdp .evps-pdp__chip svg{width:15px;height:15px;color:var(--a-text)}
.evps-pdp .evps-pdp__spec .ic svg{width:17px;height:17px}
.evps-pdp .evps-pdp__card .ic svg{width:20px;height:20px}
.evps-pdp .evps-pdp__list li svg{flex:0 0 auto;width:19px;height:19px;color:var(--a-text);margin-top:1px}
.evps-pdp .evps-pdp__band .bic svg{width:24px;height:24px}
.evps-pdp .evps-pdp__ctab .yes svg{width:17px;height:17px;color:var(--ok);vertical-align:-3px}
.evps-pdp .evps-pdp__ctab td.hl .yes svg{color:var(--a-text)}

/* Host-theme guard: the theme ships `[data-theme="dark"] .evps-app h1..h6` and
   `[data-theme="light"] .evps-app h1..h4` at `color:var(--evps-text)!important`
   (evps-1000x.css). Without this block the component's headings are repainted by
   that rule and go invisible on a light page. You cannot beat !important without
   !important, so re-assert OUR locals - which now track the host tokens - behind a
   DOUBLED root class. Keep the mechanism; only ever re-point the values.
   TWO things this comment used to get wrong, worth knowing before you edit it:
   (1) the upstream rule lists h1..h6 ONLY - there is no `strong, b` in it - so the
       non-heading entries below are belt-and-braces, not load-bearing;
   (2) it is scoped to [data-theme], which stock themes never set, so on stock this
       whole block is inert. It is 1000X protection, not stock protection.
   The `thead th.plan` entry IS load-bearing in the wrong direction: it outranks
   the highlighted-column rule above (0,4,2 + !important vs 0,3,2), so a
   `th.plan.hl` rendered its plan name in --tx while its nested <small> kept the
   accent - the highlight applied to half the header. The explicit .hl override
   below restores it. If you re-point this block, keep them in sync.
   (The real fix is upstream: rewrite the theme rule as `.evps-app :where(h1,...)` so it drops to
   (0,1,0) with no !important, after which this whole block can be deleted. Until then it stays.) */
.evps-pdp.evps-pdp .evps-pdp__title,.evps-pdp.evps-pdp .evps-pdp__sec-h,.evps-pdp.evps-pdp .evps-pdp__card h4,.evps-pdp.evps-pdp .evps-pdp__band .bt strong,.evps-pdp.evps-pdp .evps-pdp__list li b,.evps-pdp.evps-pdp .evps-pdp__spec .n,.evps-pdp.evps-pdp .evps-pdp__ctab .feat,.evps-pdp.evps-pdp .evps-pdp__ctab .val,.evps-pdp.evps-pdp .evps-pdp__ctab thead th.plan{color:var(--tx)!important}
.evps-pdp.evps-pdp .evps-pdp__ctab thead th.plan.hl,.evps-pdp.evps-pdp .evps-pdp__ctab thead th.plan.hl small{color:var(--a-text)!important}
.evps-pdp.evps-pdp .evps-pdp__lede,.evps-pdp.evps-pdp .evps-pdp__sec-sub,.evps-pdp.evps-pdp .evps-pdp__card p,.evps-pdp.evps-pdp .evps-pdp__list li span,.evps-pdp.evps-pdp .evps-pdp__band .bt span{color:var(--tm)!important}
.evps-pdp.evps-pdp .evps-pdp__eyebrow,.evps-pdp.evps-pdp .evps-pdp__plus{color:var(--a-text)!important}
.evps-pdp.evps-pdp .evps-pdp__pop{color:var(--on-a)!important}
