/* Lovable c408a998: studio colors, motion and purchase panels.
 * Presentation only. Gate visibility, form controls and checkout are not reset.
 */
:root { --lv-ink:oklch(.24 .06 255); --lv-primary:oklch(.27 .07 255); --lv-muted:oklch(.5 .03 250); --lv-line:oklch(.9 .012 240); --lv-cobalt:oklch(.52 .17 258); --lv-aqua:oklch(.76 .12 195); --lv-ease:cubic-bezier(.22,1,.36,1); }
/* Fade timing stays on the children; only their shared peak changes. */
dialog#research-entry .entry-falls { opacity:.78; }

/* Live WooCommerce cards on the homepage and catalog. */
.edp-shop-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:24px; margin-top:40px; }
.edp-shop-grid .material-card { min-width:0; margin:0; }
.material-card { border:1px solid #c7e8ef; border-radius:24px; background:#fff; box-shadow:0 12px 38px -30px #0b31584d; }
.material-card .product-info { padding:22px; }
.material-card .product-art { border-radius:20px; }
.material-card .product-title-link { font-family:"Manrope",sans-serif; font-weight:800; }
.material-card .edp-price-band .price { font-family:"Manrope",sans-serif; font-size:28px; font-weight:800; color:var(--lv-primary); }
.material-card .variant-row select { min-height:46px; border:1px solid #b9e5ef; border-radius:14px; background:#f8fcff; color:var(--lv-ink); }
.edp-card-quantity { display:flex; align-items:center; justify-content:space-between; gap:12px; font-size:12px; color:var(--lv-muted); margin:12px 0 16px; }
.edp-card-quantity input.edp-card-qty { width:80px; min-height:44px; border:1px solid #b9e5ef; border-radius:99px; padding:8px 12px; background:#fff; color:var(--lv-ink); text-align:center; font:600 16px "Geist",sans-serif; }
.material-card .inquiry-button { border-radius:99px; min-height:46px; background:var(--lv-primary); color:#fff; }
.material-card :is(select,input,a):focus-visible { outline:3px solid #087b9a; outline-offset:3px; }

/* NextGen-inspired hierarchy, using ED art and native variation/cart forms. */
.single-product #main { background:linear-gradient(145deg,#f8fcff,#edf7fc 60%,#fff); padding-bottom:72px; }
.single-product.woocommerce div.product { grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:40px; max-width:1280px; font-family:"Geist",sans-serif; }
/* The reference's own panel-navy wash and padding. This had a gradient
   of its own -- #f8fcff/#dbeefa/#b9d4e9 against the reference's
   #f9fcff/#dbeaf7/#b8d1ea/#9fbee1, with different stops -- which read as
   a slightly different blue beside the catalog cards. px-8 py-16 is what
   gives the vial its margin.

   Declared twice on purpose. The stops are the same colours either way
   -- the hex are exact conversions -- but a gradient written in hex
   interpolates through sRGB and one written in oklch through oklab, so
   the midtones differ. The cards use oklch; this matches them, and the
   hex line above is what a browser without oklch falls back to. */
.single-product.woocommerce div.product > .edp-single-art { grid-row:auto; max-width:none; width:100%; aspect-ratio:auto; overflow:visible; padding:64px 32px; display:grid; place-items:center; border:1px solid #b4e0ee; border-radius:32px; background-color:#a7c4e3; background-color:oklch(.81 .054 250); background-image:radial-gradient(78% 68% at 50% 46%,#f9fcff 0%,#dbeaf7 40%,#b8d1ea 74%,#9fbee1 100%); background-image:radial-gradient(78% 68% at 50% 46%,oklch(.99 .005 240) 0%,oklch(.93 .024 244) 40%,oklch(.85 .044 249) 74%,oklch(.79 .06 252) 100%); box-shadow:0 24px 60px -42px #123b6266; }
/* Sized by height, as the reference does: h-72 on a phone, h-96 above it.
   Width-filling made the vial crowd the panel edge to edge.

   The stage carries .vial-art, which navy.css gives aspect-ratio
   1122 / 1402 for the width-sized cards. Against a height-sized image
   that ratio drives the box instead of the content. site-white.css also
   gives it container-type:inline-size, and size containment in the inline
   axis means the contents cannot give the box a width at all -- which is
   what kept collapsing fit-content to 0, leaving the vial a sliver pushed
   to the right. Releasing the ratio, the containment and the inherited
   height:100% hands the sizing back to the image. The cards that need all
   three are untouched. */
.single-product.woocommerce div.product .edp-single-art .vial-stage { width:fit-content; max-width:none; height:auto; aspect-ratio:auto; container-type:normal; margin:0 auto; overflow:visible; }
.single-product.woocommerce div.product .edp-single-art .vial-stage img { height:18rem; width:auto; max-width:none; }
@media (min-width:768px) { .single-product.woocommerce div.product .edp-single-art .vial-stage img { height:24rem; } }
.single-product.woocommerce div.product > .summary { min-width:0; width:auto; float:none; padding:28px; border:1px solid #c7e8ef; border-radius:28px; background:#fff; }
.single-product.woocommerce div.product .product_title { font-family:"Manrope",sans-serif; font-weight:800; font-size:clamp(36px,4vw,56px); line-height:1.08; letter-spacing:-.035em; color:var(--lv-primary); margin-bottom:20px; }
.single-product.woocommerce div.product :is(p.price,span.price) { font-family:"Manrope",sans-serif; font-size:30px; font-weight:800; color:var(--lv-primary); }
.single-product.woocommerce div.product .woocommerce-product-details__short-description { font-size:15px; line-height:1.7; border-color:#d4edf3; }
.single-product.woocommerce div.product form.cart { padding:20px; border:1px solid #c7e8ef; border-radius:22px; background:linear-gradient(135deg,#f7fcff,#fff); }
.single-product.woocommerce div.product table.variations select { min-height:50px; border:1px solid #a9dce9; border-radius:14px; font-size:16px; padding:12px 16px; background:#fff; }
.single-product.woocommerce div.product table.variations label { color:#456779; font-size:11px; letter-spacing:.13em; }
.single-product.woocommerce div.product form.cart .quantity input.qty { min-height:50px; width:80px; font-size:18px; border:1px solid #a9dce9; background:#fff; }
.single-product.woocommerce div.product form.cart .single_add_to_cart_button { min-height:50px; font:700 15px "Geist",sans-serif; letter-spacing:0; text-transform:none; background:var(--lv-primary); border-color:var(--lv-primary); padding:14px 28px; }
.single-product.woocommerce div.product form.cart .single_add_to_cart_button:hover { background:#126083; border-color:#126083; }
.single-product.woocommerce div.product form.cart .single_add_to_cart_button:disabled { background:#8c9fb0; border-color:#8c9fb0; }
.single-product.woocommerce div.product form.cart .stock { display:inline-block; border:1px solid #b9e5ef; border-radius:99px; padding:6px 12px; font-size:12px; background:#edf9fc; color:#087b9a; }
.single-product.woocommerce div.product :is(.edp-coa-panel,.edp-compound) { border:1px solid #c7e8ef; border-radius:24px; padding:24px; background:#fff; }
.single-product.woocommerce div.product .edp-coa-panel { margin-top:26px; }
.single-product.woocommerce div.product .edp-coa-item { padding:18px; border:1px solid #d4edf3; border-radius:16px; background:#f8fcff; }
.single-product.woocommerce div.product .edp-coa-item + .edp-coa-item { margin-top:16px; }
.single-product.woocommerce div.product .edp-coa-links { display:flex; flex-wrap:wrap; gap:12px; }
.single-product.woocommerce div.product .edp-compound { grid-column:1/-1; }
.single-product.woocommerce div.product :is(select,input,button,a):focus-visible { outline:3px solid #087b9a; outline-offset:3px; }
@media(max-width:1000px) { .edp-shop-grid { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media(max-width:900px) {
 .single-product.woocommerce div.product { grid-template-columns:minmax(0,1fr); gap:24px; }
 .single-product.woocommerce div.product > .edp-single-art { max-width:600px; margin-inline:auto; }
 .single-product.woocommerce div.product > .summary { padding:24px; }
}
@media(max-width:560px) {
 .edp-shop-grid { grid-template-columns:minmax(0,1fr); gap:20px; }
 .single-product.woocommerce div.product { padding-inline:16px; }
 .single-product.woocommerce div.product > .edp-single-art { padding:48px 20px; border-radius:24px; }
 .single-product.woocommerce div.product > .summary { padding:20px; }
 .single-product.woocommerce div.product form.cart { padding:16px; }
 .single-product.woocommerce div.product form.cart .single_add_to_cart_button { margin-top:12px; width:100%; }
}
.edp-lovable-home { background:oklch(.975 .01 242); color:var(--lv-ink); font-family:"Geist",system-ui,sans-serif; }
.edp-lovable-home :is(h1,h2,h3,.edp-fname,.edp-proof-line,.edp-stage-name,.edp-card-name,.edp-lineup-name) { font-family:"Manrope",system-ui,sans-serif; font-weight:800; letter-spacing:-.03em; }
.edp-lovable-home .edp-sec { padding:96px 0; border-color:var(--lv-line); }
.edp-lovable-home .edp-h2 { font-size:36px; line-height:1.12; max-width:42rem; margin-top:16px; color:var(--lv-ink); }
.edp-lovable-home .edp-lede { font-size:16px; line-height:1.5; max-width:36rem; margin-top:16px; color:var(--lv-muted); }
.edp-lovable-home .edp-eyebrow { font-size:12px; letter-spacing:.2em; }
.edp-lovable-home #records { padding:80px 0; }
.edp-lovable-home .edp-cards { margin-top:48px; }
.edp-lovable-home .edp-card-name { font-size:20px; }
.edp-lovable-home .edp-card-meta { font-size:12px; }
.edp-lovable-home .edp-card-lot { border:0; padding-top:0; margin-top:16px; font-size:12px; }
.edp-lovable-home :is(.edp-card-art,.edp-lineup-art),.material-card .product-art,.edp-product-photo,.edp-lot-art { background-color:oklch(.81 .054 250); background-image:radial-gradient(78% 68% at 50% 46%,oklch(.99 .005 240) 0%,oklch(.93 .024 244) 40%,oklch(.85 .044 249) 74%,oklch(.79 .06 252) 100%); }
.edp-lovable-home .hero-v2 { background-color:oklch(.89 .036 248); background-image:radial-gradient(60% 55% at 50% 18%,oklch(.97 .01 240),transparent 72%),radial-gradient(70% 80% at 85% 8%,color-mix(in oklab,oklch(.72 .11 235) 30%,transparent),transparent 70%),linear-gradient(180deg,oklch(.92 .026 244),oklch(.81 .054 250)); }
.edp-lovable-home .hero-v2-inner { z-index:1; }
.edp-lovable-home .hero-v2-title { max-width:none; font-size:48px; line-height:1.02; }
.edp-lovable-home .hero-v2-title em { color:oklch(.42 .075 250); }
.edp-lovable-home .hero-v2-sub { margin-top:24px; font-size:18px; }
.edp-lovable-home .hero-v2-trust ul { padding-block:24px; gap:24px; }
.edp-lovable-home .hero-v2-trust { z-index:1; }
.edp-lovable-home .edp-lineup { margin-top:56px; gap:24px; }
.edp-lovable-home .edp-lineup-item { padding:12px; }
.edp-lovable-home .edp-lineup-name { font-size:18px; }
.edp-lovable-home .edp-lineup-amt { font-size:11px; }
.edp-lovable-home #vials { background-image:radial-gradient(60% 70% at 78% 40%,#93cbea42,transparent 70%),radial-gradient(40% 50% at 10% 90%,#0b264819,transparent 70%); }
.edp-lovable-home .edp-stages { gap:16px; margin-top:56px; }
.edp-lovable-home .edp-stages li { padding:24px; border:0; background:oklch(.95 .012 240); transition:translate .5s; }
.edp-lovable-home .edp-stages li:nth-child(2) { background:oklch(.95 .01 240); }
.edp-lovable-home .edp-stages li:nth-child(3) { background:#57afe019; }
.edp-lovable-home .edp-stages li:nth-child(4) { background:#26935c19; }
.edp-lovable-home .edp-stages li:nth-child(5) { background:#9d630019; }
.edp-lovable-home .edp-stage-num { font:800 30px/1.2 "Manrope",sans-serif; }
.edp-lovable-home .edp-stage-name { font-size:18px; }
.edp-lovable-home .edp-stage-text { font-size:14px; }
.edp-lovable-home .edp-verify-points li::before { content:"\2713"; }

/* Quality protocol: cobalt/aqua connecting rail, nodes, finite halo and orbit. */
.edp-lovable-home #standards { position:relative; overflow:hidden; background:oklch(.975 .014 240); }
#standards::before { content:""; position:absolute; inset:0; pointer-events:none; background:radial-gradient(50% 60% at 85% 30%,color-mix(in oklab,var(--lv-cobalt) 14%,transparent),transparent 70%),radial-gradient(40% 50% at 5% 90%,color-mix(in oklab,var(--lv-aqua) 14%,transparent),transparent 70%); }
.edp-quality-layout { position:relative; display:grid; gap:48px; }
.edp-quality-intro .edp-lede { max-width:28rem; }
.edp-quality-seal { position:relative; display:grid; place-items:center; width:160px; height:160px; margin-top:40px; }
.edp-quality-orbit { position:absolute; inset:0; border:1px dashed color-mix(in oklab,var(--lv-cobalt) 50%,transparent); border-radius:50%; }
.edp-quality-orbit::before { content:""; position:absolute; top:-4px; left:calc(50% - 4px); width:8px; height:8px; border-radius:50%; background:var(--lv-aqua); box-shadow:0 0 10px var(--lv-aqua); }
.edp-quality-seal-core { display:grid; place-items:center; width:112px; height:112px; background:white; border:2px solid color-mix(in oklab,var(--lv-cobalt) 40%,transparent); border-radius:50%; box-shadow:0 18px 40px -20px var(--lv-cobalt); }
.edp-quality-seal-core strong { font:800 24px "Manrope",sans-serif; }
.edp-quality-seal-core span { font:10px "IBM Plex Mono",monospace; text-transform:uppercase; color:var(--lv-muted); }
.edp-lovable-home .edp-fields { position:relative; overflow:visible; margin:0; padding:0; border:0; border-radius:0; background:none; }
.edp-fields::before,.edp-fields::after { content:""; position:absolute; left:21px; top:24px; bottom:24px; width:2px; border-radius:2px; background:#3465b726; }
.edp-fields::after { background:linear-gradient(var(--lv-cobalt),oklch(.7 .13 235),var(--lv-aqua)); transform-origin:top; transition:transform 1.6s var(--lv-ease) .25s; }
.edp-lovable-home .edp-fields li { position:relative; z-index:1; gap:16px; padding:0; border:0; margin-bottom:16px; }
.edp-field-node { position:relative; display:grid; place-items:center; flex:0 0 44px; width:44px; height:44px; background:white; border:2px solid color-mix(in oklab,var(--lv-cobalt) 60%,transparent); border-radius:50%; color:oklch(.4 .15 260); }
.edp-field-node::before { content:""; position:absolute; width:32px; height:32px; border-radius:50%; background:color-mix(in oklab,var(--lv-cobalt) 12%,transparent); }
.edp-field-node svg { position:relative; width:16px; height:16px; }
.edp-fields li:nth-child(even) .edp-field-node { border-color:color-mix(in oklab,var(--lv-aqua) 60%,transparent); color:oklch(.42 .08 200); }
.edp-fields li:nth-child(even) .edp-field-node::before { background:color-mix(in oklab,var(--lv-aqua) 15%,transparent); }
.edp-field-card { display:flex; flex-wrap:wrap; flex:1; min-width:0; gap:8px 12px; padding:16px; background:white; border:1px solid color-mix(in oklab,var(--lv-cobalt) 25%,transparent); border-radius:12px; box-shadow:0 14px 30px -24px var(--lv-cobalt); transition:translate .3s,border-color .3s,box-shadow .3s; }
.edp-fields li:hover .edp-field-card { translate:0 -2px; border-color:color-mix(in oklab,var(--lv-cobalt) 60%,transparent); box-shadow:0 20px 36px -22px var(--lv-cobalt); }
.edp-lovable-home .edp-fnum { font-size:12px; color:oklch(.4 .15 260); }
.edp-lovable-home .edp-fname { font-size:18px; }
.edp-lovable-home .edp-ftext { font-size:14px; color:var(--lv-muted); }
.edp-lovable-home .edp-ftag { align-self:flex-start; padding:4px 10px; font-size:10px; border-color:color-mix(in oklab,var(--lv-cobalt) 40%,transparent); background:color-mix(in oklab,var(--lv-cobalt) 5%,transparent); color:oklch(.4 .15 260); }
.edp-lovable-home .edp-proof { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:16px; margin-top:24px; padding:16px 20px; border:1px solid color-mix(in oklab,var(--lv-aqua) 40%,transparent); background:linear-gradient(135deg,oklch(.22 .06 258),var(--lv-primary),oklch(.4 .15 260)); box-shadow:0 24px 50px -28px var(--lv-cobalt); }
.edp-lovable-home .edp-proof-line { margin:4px 0 0; font-size:18px; }
.edp-lovable-home .edp-proof .edp-eyebrow { font-size:10px; }
.edp-lovable-home .edp-proof .hero-v2-btn { width:auto; font-size:14px; padding:8px 16px; }
.edp-why-grid { display:grid; gap:20px; margin-top:56px; }
.edp-why-card { position:relative; overflow:hidden; padding:28px; border:1px solid var(--lv-line); border-radius:16px; background:white radial-gradient(120% 100% at 100% 0%,#57afe024,transparent 62%); transition:translate .5s,border-color .5s,box-shadow .5s; }
.edp-why-card::after { content:""; position:absolute; top:0; bottom:0; left:-33.3%; width:33.3%; pointer-events:none; transform:skewX(-12deg); background:linear-gradient(90deg,transparent,#0b26480d,transparent); transition:transform .7s; }
.edp-why-card:hover::after { transform:translateX(420%) skewX(-12deg); }
.edp-why-icon { display:grid; place-items:center; width:40px; height:40px; border-radius:8px; background:#57afe026; color:var(--lv-primary); }
.edp-why-icon svg { width:20px; height:20px; }
.edp-lovable-home .edp-why-card h3 { margin:20px 0 0; font-size:20px; line-height:1.4; }
.edp-why-card p { margin:8px 0 0; font-size:14px; line-height:1.5; color:var(--lv-muted); }
.edp-why-card:hover { translate:0 -4px; border-color:var(--lv-primary); box-shadow:0 20px 25px -5px #0b26481a; }
.edp-faq .edp-wrap { max-width:48rem; }
.edp-lovable-home .edp-faq :is(.edp-eyebrow,.edp-h2) { text-align:center; max-width:none; }
.edp-faq-items { margin-top:40px; border-top:1px solid var(--lv-line); }
.edp-faq details { border-bottom:1px solid var(--lv-line); }
.edp-faq summary { display:flex; align-items:center; justify-content:space-between; gap:24px; padding:20px 0; list-style:none; cursor:pointer; font:800 20px/1.4 "Manrope",sans-serif; color:var(--lv-ink); }
.edp-faq summary::-webkit-details-marker { display:none; }
.edp-lovable-home .edp-faq details summary::after { content:none !important; display:none !important; }
.edp-faq summary>span::before { content:"+"; font:18px "IBM Plex Mono",monospace; }
.edp-faq [open] summary>span::before { content:"−"; }
.edp-faq details p { margin:0; padding-bottom:20px; color:var(--lv-muted); line-height:1.5; }
.edp-faq summary:focus-visible { outline:2px solid var(--lv-cobalt); outline-offset:4px; border-radius:4px; }

/* Motion stays on the separate translate property; existing image rotations remain intact. */
@keyframes edp-lv-rise { from { opacity:0; translate:0 18px; } to { opacity:1; translate:none; } }
.edp-entered .hero-v2-stage,.edp-entered .hero-v2-badge,.edp-entered .hero-v2-title,.edp-entered .hero-v2-sub,.edp-entered .hero-v2-actions,.edp-entered .hero-v2-stats { animation:edp-lv-rise .9s var(--lv-ease) both; }
/* The reference staggers these; without the delays all six rose at once
   and the hero read as one block appearing rather than assembling.
   Its own values: 200, 300, 560, 820, 940, 1080ms. */
.edp-entered .hero-v2-stage   { animation-delay:200ms; }
.edp-entered .hero-v2-badge   { animation-delay:300ms; }
.edp-entered .hero-v2-title   { animation-delay:560ms; }
.edp-entered .hero-v2-sub     { animation-delay:820ms; }
.edp-entered .hero-v2-actions { animation-delay:940ms; }
.edp-entered .hero-v2-stats   { animation-delay:1080ms; }
/* A second copy of these delays used to sit here, restating four of the
   six with different numbers -- the title at 380ms against the
   reference's 560ms. The block above carries the reference's values. */
.edp-entered .hero-v2-actions { animation-delay:.94s; }
.edp-entered .hero-v2-stats { animation-delay:1.08s; }
@keyframes edp-lv-float { 0%,100% { translate:0 0; } 50% { translate:0 -10px; } }
.edp-proof-card .vial-stage > img { animation:edp-lv-float 7s ease-in-out infinite; }
/* The reference's own float-hero: from rest to -18px and +0.8deg, not
   from +5px/-0.6deg to -20px/+0.6deg. The old curve started the vial
   already displaced, so it never sat still at the top of the loop. */
@keyframes edp-lv-hero-float { 0%,100% { translate:0 0; rotate:0deg; } 50% { translate:0 -18px; rotate:.8deg; } }
.hero-v2-stage .hv { animation:edp-lv-hero-float 7s ease-in-out infinite; will-change:transform; }
/* Negative delays put the three vials at different points of the same
   loop, as the reference does, instead of all three rising together. */
.hero-v2-stage .hv-2 { animation-delay:-2.33s; }
.hero-v2-stage .hv-3 { animation-delay:-4.67s; }
.hero-v2-stage .hv-2 .hv { animation-delay:-2s; }
.hero-v2-stage .hv-3 .hv { animation-delay:-4s; }
/* Only the hero vials float. This drifted every vial on the site --
   catalog cards, the lineup, lot records -- which turned a hero flourish
   into a page that never settles. The reference floats the three in the
   hero and the one on the proof card, and nothing else. */
.edp-lv-reveal { transition:opacity .8s var(--lv-ease),translate .8s var(--lv-ease); transition-delay:var(--lv-delay,0ms); }
.edp-lv-pending { opacity:0; translate:0 24px; }
.edp-lv-shown { opacity:1; translate:none; }
.edp-quality-detail.edp-lv-pending .edp-fields::after { transform:scaleY(0); }
@keyframes edp-lv-orbit { to { transform:rotate(360deg); } }
/* The orbit runs continuously rather than once on reveal.
   It was gated on .edp-quality-intro gaining .edp-lv-shown, which the
   observer grants when 8% of that block appears -- the eyebrow. The dial
   is most of a screen further down, so on a phone the single 4.8s
   rotation had finished before the dial was ever in view and it read as
   a static graphic. Same duration, linear so a loop has no seam.
   prefers-reduced-motion still stops it outright, below. */
.edp-quality-orbit { animation:edp-lv-orbit 4.8s linear infinite; }
@keyframes edp-lv-halo { from { box-shadow:0 0 0 0 color-mix(in oklab,var(--lv-cobalt) 35%,transparent); } to { box-shadow:0 0 0 10px transparent; } }
.edp-quality-detail.edp-lv-shown .edp-field-node { animation:edp-lv-halo 1.4s ease-out 2; animation-delay:calc(.4s + var(--lv-step,0)*.11s); }
.edp-lv-bar-pending { transform:scaleX(0); }
.edp-card-bar > span { transform-origin:left; transition:transform 1.4s ease-out; }
/* The hero's dot field, replacing the dripping water.

   Small solid dots scattered across the canvas, each drifting out to its
   own offset and back. The reference's own path: 25% goes a little over
   half the sway and 1.2x the rise, 50% reaches the full offset, 75% pulls
   back past the start, 100% closes the loop -- which is what keeps it
   wandering rather than pulsing. Colour is its --sky, oklch(.7 .13 235). */
.edp-hero-orbs { position:absolute; inset:0; overflow:hidden; pointer-events:none; }
@keyframes edp-lv-orb-float {
  0%   { transform:translate(0,0); opacity:var(--orb-o,.4); }
  25%  { transform:translate(calc(var(--orb-x,10px) * .55),calc(var(--orb-y,-14px) * 1.2)); opacity:calc(var(--orb-o,.4) * .94); }
  50%  { transform:translate(var(--orb-x,10px),var(--orb-y,-14px)); opacity:var(--orb-o,.4); }
  75%  { transform:translate(calc(var(--orb-x,10px) * -.35),calc(var(--orb-y,-14px) * .45)); opacity:calc(var(--orb-o,.4) * .96); }
  100% { transform:translate(0,0); opacity:var(--orb-o,.4); }
}
.edp-hero-orb { position:absolute; border-radius:50%; background:#37aae3; background:oklch(.7 .13 235); animation:edp-lv-orb-float 9s ease-in-out infinite; }
.edp-motion-toggle { position:absolute; top:10px; right:16px; z-index:2; padding:6px 12px; border:1px solid var(--lv-line); border-radius:999px; background:#ffffffd9; color:var(--lv-muted); font:11px "Geist",sans-serif; cursor:pointer; }
html.edp-motion-paused :is(.vial-stage img,.edp-hero-orb,.vial-fall,.edp-ticker-run,.hero-v2-dot,.edp-quality-orbit,.edp-field-node) { animation-play-state:paused !important; }
html.edp-motion-paused :is(.hero-v2-stage,.hero-v2-badge,.hero-v2-title,.hero-v2-sub,.hero-v2-actions,.hero-v2-stats) { animation:none; }
.edp-ticker:hover .edp-ticker-run { animation-play-state:paused; }
.hero-v2-btn,.edp-account-btn { transition:translate .3s,box-shadow .3s,background-color .3s,border-color .3s; }
@media (min-width:640px) { .edp-field-card { padding:20px; } .edp-lovable-home .hero-v2-trust ul { grid-template-columns:repeat(3,1fr); } .edp-why-grid { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (min-width:768px) { .edp-lovable-home .hero-v2-title { font-size:72px; } .edp-lovable-home .edp-h2 { font-size:48px; } }
@media (min-width:1024px) { .edp-quality-layout { grid-template-columns:.85fr 1.15fr; } .edp-lovable-home .hero-v2-trust ul { grid-template-columns:repeat(5,minmax(0,1fr)); } .edp-why-grid { grid-template-columns:repeat(3,minmax(0,1fr)); } }
@media (hover:hover) { .hero-v2-btn:hover,.edp-account-btn:hover { translate:0 -2px; } .edp-lovable-home .edp-stages li:hover { translate:0 -4px; } }
@media (max-width:420px) { .edp-field-card .edp-ftag { margin-left:20px; } }
@media (prefers-reduced-motion:reduce) {
  .hero-v2-stage .hv,.vial-stage:not(.hv-1):not(.hv-2):not(.hv-3)>img,.edp-hero-orb,.edp-quality-orbit,.edp-field-node { animation:none !important; }
  .edp-motion-toggle { display:none; }
  /* The dots stay: the reference only stops them moving. */
  .edp-lv-reveal { opacity:1; translate:none; transition:none; }
  .edp-entered :is(.hero-v2-stage,.hero-v2-badge,.hero-v2-title,.hero-v2-sub,.hero-v2-actions,.hero-v2-stats) { animation:none; }
  .edp-card-bar>span,.edp-quality-detail .edp-fields::after { transform:none; transition:none; }
}




/* 3.39: Lovable product cards. The source PNG is shown unfiltered; the
   artwork link must shrink to the photo, not inherit section 31's 100% height. */
.material-card .product-art,
.material-card:is(.is-soon,.is-oos) .product-art {
  border-radius: 0;
  filter: none;
  opacity: 1;
}
.material-card .product-art .product-art-link {
  height: auto;
  align-self: center;
}
.material-card .product-art .vial-stage {
  display: block;
  width: 100%;
  max-width: none;
}
.material-card .product-art > .vial-stage {
  flex: 0 0 58%;
  width: 58%;
}
.material-card .product-art .vial-stage > img {
  animation: none;
  translate: none;
  filter: none;
  mix-blend-mode: normal;
  opacity: 1;
  transition: transform 500ms cubic-bezier(.22,1,.36,1);
}
.material-card .product-art-link:hover .vial-art { transform: none; }
.material-card .product-info { padding: 24px; }
.material-card .card-research-label {
  margin: 0;
  font: 10px/1.5 "IBM Plex Mono",monospace;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--lv-muted);
}
.material-card .product-title-row { margin: 8px 0 16px; }
.material-card .product-title-row h3 {
  margin: 0;
  font: 800 20px/1.4 "Manrope",sans-serif;
  letter-spacing: -.03em;
  color: var(--lv-ink);
}
.material-card :is(.material-identity,.material-summary,.product-restriction,.button-disclaimer,.edp-per,.view-product) { display: none; }
.material-card .variant-row { margin-top: auto; display: flex; flex-wrap: wrap; gap: 8px; }
.material-card .edp-amount-pills { display: none; flex-wrap: wrap; gap: 8px; }
.material-card.edp-controls-ready .edp-amount-fallback { display: none; }
.material-card.edp-controls-ready .edp-amount-pills { display: flex; }
.material-card .edp-amount-pills button {
  border: 1px solid color-mix(in oklab,var(--lv-aqua) 40%,transparent);
  border-radius: 999px;
  padding: 6px 14px;
  background: oklch(.975 .01 242);
  color: var(--lv-ink);
  font: 12px/1.5 "IBM Plex Mono",monospace;
  cursor: pointer;
}
.material-card .edp-amount-pills button[aria-pressed=true] {
  border-color: var(--lv-primary);
  background: var(--lv-primary);
  color: #fff;
}
.material-card .edp-price-band { margin: 16px 0 0; padding: 0; border: 0; background: none; }
.material-card .edp-price-band .price {
  color: var(--lv-primary);
  font: 800 24px/1.35 "Manrope",sans-serif;
  white-space: normal;
}
.material-card .card-actions { display: flex; align-items: center; gap: 12px; margin-top: 20px; }
.material-card .edp-card-quantity {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  margin: 0;
  padding: 0;
  border: 1px solid color-mix(in oklab,var(--lv-aqua) 40%,transparent);
  border-radius: 999px;
  background: oklch(.975 .01 242);
}
.material-card .edp-card-quantity button {
  display: none;
  place-items: center;
  width: 40px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--lv-ink);
  font: 22px/1 "Geist",sans-serif;
  cursor: pointer;
}
.material-card.edp-controls-ready .edp-card-quantity button { display: grid; }
.material-card .edp-card-quantity input.edp-card-qty {
  width: 32px;
  min-height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  border-radius: 0;
  color: var(--lv-ink);
  font: 14px/1.5 "IBM Plex Mono",monospace;
  text-align: center;
  appearance: textfield;
  -moz-appearance: textfield;
}
.material-card .edp-card-qty::-webkit-inner-spin-button,
.material-card .edp-card-qty::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.material-card .card-actions .inquiry-button {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 0;
  min-height: 44px;
  margin: 0;
  padding: 10px 16px;
  border: 0;
  border-radius: 999px;
  background: var(--lv-primary);
  color: #fff;
  font: 500 14px/1.4 "Geist",sans-serif;
  text-decoration: none;
}
.material-card .card-actions .inquiry-button[aria-disabled=true],
.material-card .card-actions .inquiry-button:disabled {
  background: oklch(.95 .01 240);
  color: var(--lv-muted);
  cursor: default;
}
.material-card .art-badge {
  padding: 4px 12px;
  font-size: 10px;
  line-height: 1.5;
}
@media (hover:hover) and (pointer:fine) {
  .material-card:hover .product-art .vial-stage > img { transform: rotate(0deg) scale(1.04); }
}
@media (hover:none), (pointer:coarse) {
  .material-card:hover .product-art .vial-stage > img { transform: rotate(16deg); }
}
@media (prefers-reduced-motion:reduce) {
  .material-card .product-art .vial-stage > img { transition: none; }
}


/* Match the reference's word-by-word hero entrance, with the same gate trigger. */
.edp-entered .hero-v2-title { animation: none; }
.edp-entered .hero-v2-title .hero-word {
  display: inline-block;
  animation: edp-lv-rise .9s var(--lv-ease) both;
  animation-delay: var(--word-delay);
}
html.edp-motion-paused .hero-v2-title .hero-word { animation: none; }
@media (prefers-reduced-motion:reduce) {
  .edp-entered .hero-v2-title .hero-word { animation: none; }
}

.edp-lovable-home .edp-shop-featured { padding: 64px 0; }
.edp-shop-featured h2.edp-eyebrow {
  margin: 0;
  font: 12px/1.5 "IBM Plex Mono",monospace;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--lv-muted);
}
.edp-shop-featured .edp-shop-grid { margin-top: 32px; }


/* Catalog and featured grids share Lovable's 2 / 2 / 3-column breakpoints.
 *
 * Lovable's own base was a single column below 640px, and that is what shipped
 * until the owner asked for two across on a phone. It is the one place this
 * file departs from the build on purpose.
 *
 * Note for whoever reads style.css next: section 28 there already wrote this
 * rule against `.products`, and it never fired. `.catalog-section .products`
 * is the more specific selector and this file loads after, so the single
 * column won twice over. The working rule is this one. Section 28 still owns
 * the card internals at half width -- paddings, type, the artwork's aspect
 * ratio -- which is why only the column count moves here.
 */
.catalog-section .wrap,
.edp-shop-featured .edp-wrap {
  width: 100%;
  max-width: 1280px;
  padding-inline: 24px;
}
.catalog-section .products,
.edp-shop-featured .edp-shop-grid {
  grid-template-columns: repeat(2,minmax(0,1fr));
  gap: 10px;
}
@media (min-width:640px) {
  .catalog-section .products,
  .edp-shop-featured .edp-shop-grid { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 20px; }
}
@media (min-width:1024px) {
  .catalog-section .products,
  .edp-shop-featured .edp-shop-grid { grid-template-columns: repeat(3,minmax(0,1fr)); }
}



/* The search box, on the front page under the hero and on the catalog page.
 *
 * Shaped after the reference the owner sent: one full-width rounded field, a
 * drawn magnifier at the left, placeholder text, and nothing at the right-hand
 * end. The three ported stylesheets each dress .search-box their own way --
 * one gives it a 22px radius and a heavy purple shadow, another a 12px radius
 * and a border -- so this settles the parts that have to agree across themes
 * and leaves the colour to whichever is active.
 */
.search-box {
  width: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 12px;
  border-radius: 14px;
  padding: 15px 18px;
  cursor: text;
}
.search-box .edp-search-icon {
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
  opacity: .55;
}
.search-box input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  font: inherit;
  font-size: 15px;
  padding: 2px 0;
}
/* Safari draws its own clear button inside type="search" and reserves room
   for it even while the field is empty, which knocked the placeholder off
   centre against the icon. */
.search-box input::-webkit-search-decoration,
.search-box input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* The block under the hero: heading, a line of context, the catalog button,
 * then the field -- in that order, after the reference the owner marked up.
 *
 * The earlier version was the field on its own, pulled up by a negative margin
 * so it lapped over the hero. That pull is gone: there is a heading above the
 * field now, and dragging the whole block upward would have run it into the
 * hero's own text rather than sitting under it.
 */
/* Scoped with .edp-lovable-home because that is what the section padding above
 * is scoped with. A bare .edp-home-search lost to `.edp-lovable-home .edp-sec`
 * on specificity and the block kept the full 96px below it, which is the gap
 * the owner saw between the field and the first row of products. The featured
 * grid's own 64px sat under that, so the two stacked to about 160px of nothing.
 *
 * The adjacent-sibling rule only pulls the grid up where it actually follows
 * this block. The featured section keeps its normal spacing anywhere else it
 * is used. */
.edp-lovable-home .edp-home-search { padding-block: 44px 20px; }
.edp-lovable-home .edp-home-search + .edp-shop-featured { padding-top: 34px; }

@media (max-width: 760px) {
  .edp-lovable-home .edp-home-search { padding-block: 30px 12px; }
  .edp-lovable-home .edp-home-search + .edp-shop-featured { padding-top: 24px; }
}

.edp-home-search { padding-block: 44px 20px; }
.edp-home-search .edp-h2 { margin: 0 0 10px; }
.edp-home-search-sub {
  margin: 0 0 22px;
  max-width: 54ch;
  opacity: .72;
  font-size: 16px;
  line-height: 1.5;
}
.edp-home-search-cta { margin: 0 0 20px; }
.edp-home-search .catalog-controls { margin: 0; }
.edp-home-search .search-box { margin: 0; }

@media (max-width: 760px) {
  .edp-home-search { padding-block: 30px 14px; }
  .edp-home-search-sub { margin-bottom: 18px; font-size: 15px; }
  .edp-home-search-cta { margin-bottom: 16px; }
}

/* The catalog's control bar, now that something renders it. The stylesheets
 * that dress .search-box were written for the single-page build, where the
 * bar sat directly under a full-bleed heading band. */
.catalog-section .catalog-controls { margin-bottom: 28px; }

@media (max-width: 760px) {
  .catalog-section .catalog-controls { margin-bottom: 18px; }
  .catalog-filter-row { flex-wrap: wrap; justify-content: flex-start; gap: 10px; }
  .filter-pills { flex-wrap: wrap; }
}

/* An in-stock, documented product wears no badge at all.
 *
 * Hidden here rather than skipped in the template because js/catalog.js
 * retags this same element when the amount changes: switching to an amount
 * that is out of stock has to have something to write to. See the note in
 * inc/catalog.php where the COA badge used to be. */
.art-badge.is-stock { display: none !important; }
