@cookieyes/nextjs 0.5.4 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -97,7 +97,7 @@ import {
97
97
  RecallButton,
98
98
  initCookieYes,
99
99
  } from "@cookieyes/nextjs";
100
- import "@cookieyes/react/styles.css";
100
+ import "@cookieyes/nextjs/styles.css";
101
101
 
102
102
  initCookieYes({
103
103
  mode: "cookie-only", // "cookie-only" | "self-hosted"
@@ -116,10 +116,17 @@ export function CookieYesRoot() {
116
116
  }
117
117
  ```
118
118
 
119
- The `@cookieyes/react/styles.css` import is required — the components ship
120
- no inline styling, so without it they render unstyled. It's exposed from
121
- `@cookieyes/react` (a dependency of this package) rather than duplicated
122
- under `@cookieyes/nextjs`.
119
+ The `@cookieyes/nextjs/styles.css` import is required — the components ship
120
+ no inline styling, so without it they render unstyled.
121
+
122
+ The sheet itself lives in `@cookieyes/react` and is re-exported here as a
123
+ one-line `@import`, so there is still only one copy of it. Import it from
124
+ **this** package, not from `@cookieyes/react`: under pnpm's strict
125
+ `node_modules` layout an app that installed only `@cookieyes/nextjs` cannot
126
+ resolve `@cookieyes/react`, and the import fails with `MODULE_NOT_FOUND`. npm
127
+ and Yarn Classic hoist it and resolve either path; `@cookieyes/nextjs/styles.css`
128
+ is correct under all of them. `@cookieyes/nextjs/critical.css` is re-exported
129
+ the same way.
123
130
 
124
131
  **3. Mount it in your root layout** — the layout itself stays a Server Component:
125
132
 
@@ -314,6 +321,57 @@ Then load the tags on the client with a preset from
314
321
  — `ga4()`, `googleAds()`, or `googleTagManager()`. The SDK broadcasts each
315
322
  consent change to Google as a Consent Mode `update`; you don't wire that up.
316
323
 
324
+ ## Faster first paint (critical CSS)
325
+
326
+ The banner is server-rendered, so it is in the very first HTML — but the browser
327
+ cannot paint it until the stylesheet arrives, and that is a *second* round trip.
328
+ On a slow connection the round trip costs more than the whole SDK: on the
329
+ Lighthouse Mobile profile, first paint is 468 ms with the stylesheet as a
330
+ `<link>` and **224 ms** with the banner's rules inlined. Nil difference on fast
331
+ desktop.
332
+
333
+ Two lines, and it is opt-in — nothing changes unless you add them:
334
+
335
+ ```tsx
336
+ // app/layout.tsx
337
+ import { CookieYesStyles } from "@cookieyes/nextjs/server";
338
+
339
+ export default function RootLayout({ children }) {
340
+ return (
341
+ <html lang="en">
342
+ <head>
343
+ <CookieYesStyles />
344
+ </head>
345
+ <body>{children}</body>
346
+ </html>
347
+ );
348
+ }
349
+ ```
350
+
351
+ ```ts
352
+ // app/cookieyes/styles.css/route.ts — the SDK serves its own stylesheet
353
+ export { GET } from "@cookieyes/nextjs/styles-route";
354
+ ```
355
+
356
+ Then **remove** `import "@cookieyes/nextjs/styles.css"` — leaving it puts the
357
+ sheet back on the critical path and cancels the gain.
358
+
359
+ `<CookieYesStyles />` inlines `critical.css` (only the banner's rules) in
360
+ `<head>` and loads the full sheet with `media="print"`, which the browser
361
+ fetches without blocking render; the SDK switches it on once mounted. There is
362
+ no inline script.
363
+
364
+ **If you run a strict Content-Security-Policy**, the inlined block needs one
365
+ hash on `style-src` — not `'unsafe-inline'`:
366
+
367
+ ```ts
368
+ import { CRITICAL_CSS_HASH } from "@cookieyes/nextjs/server"; // "'sha256-…'"
369
+ ```
370
+
371
+ It changes only when the stylesheet does, and is published in the changelog.
372
+ Nonce users can pass `<CookieYesStyles nonce={nonce} />` instead. Without a CSP
373
+ there is nothing further to configure.
374
+
317
375
  ## API
318
376
 
319
377
  This package re-exports the entire `@cookieyes/react` surface — the setup function
@@ -0,0 +1 @@
1
+ :root{--cy-primary: #1863dc;--cy-primary-hover: color-mix(in srgb,var(--cy-primary) 85%,black);--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-radius: 6px;--cy-font: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;--cy-focus: var(--cy-primary);--cy-on-primary: #ffffff;--cy-on-widget-bg: #ffffff}@media (prefers-color-scheme: dark){:root{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-outline,.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-always-active{color: #3fbf3f}}.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder{font-family: var(--cy-font);font-size: 14px;font-weight: 400;font-style: normal;line-height: 1.5;letter-spacing: normal;word-spacing: normal;text-align: left;text-transform: none;text-decoration: none;text-indent: 0;text-shadow: none;color: var(--cy-text);direction: ltr;white-space: normal;box-sizing: border-box;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::before,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::after{box-sizing: border-box}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) button,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) input,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) label,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) select,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) textarea{font: inherit;color: inherit;letter-spacing: inherit;text-transform: inherit;text-align: inherit;margin: 0}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) a{color: inherit;text-decoration: none;background: transparent}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) p,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h1,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h2,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h3,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h4,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ul,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ol,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) li{margin: 0;padding: 0;list-style: none}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) svg{display: inline-block;vertical-align: middle}.cy-banner-wrap{display: contents}.cy-banner{position: fixed;left: 40px;bottom: 40px;right: auto;z-index: 9999999;pointer-events: all;background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 -1px 10px 0 rgba(172,171,171,0.3);border: 1px solid var(--cy-border);max-width: 440px;width: min(440px,calc(100vw - 80px));padding: 24px 24px 12px;box-sizing: border-box;animation: cy-fade-in 0.2s ease-out both}.cy-banner[data-leaving]{animation: cy-fade-out 0.2s ease forwards}.cy-banner-wrap[data-cy-entered] .cy-banner:not([data-leaving]){animation: none}@keyframes cy-fade-in{from{opacity: 0}to{opacity: 1}}@keyframes cy-fade-out{from{opacity: 1}to{opacity: 0}}.cy-banner-text{margin-bottom: 0}.cy-banner-title{font-size: 18px;font-weight: 700;line-height: 24px;margin: 0 0 12px;color: var(--cy-text);word-break: break-word}.cy-banner-description{font-size: 14px;line-height: 24px;color: var(--cy-text);margin: 0;word-break: break-word}.cy-banner-description a{color: var(--cy-primary);text-decoration: underline;text-underline-offset: 2px}.cy-banner-actions{display: flex;align-items: center;justify-content: flex-start;gap: 8px;flex-wrap: wrap;margin-top: 16px}.cy-btn{flex: auto;max-width: 100%;cursor: pointer;font-family: var(--cy-font);font-size: 14px;font-weight: 500;border-radius: 2px;padding: 8px;line-height: 24px;transition: opacity 0.15s;text-decoration: none;text-align: center;overflow-wrap: break-word;border: none}.cy-btn:hover{opacity: 0.8}.cy-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-btn-primary{background: var(--cy-primary);color: var(--cy-on-primary);border: 2px solid var(--cy-primary)}.cy-btn-primary:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-btn-outline{background: transparent;color: var(--cy-primary);border: 2px solid var(--cy-primary)}.cy-btn-do-not-sell{flex: 1 0 100%;width: 100%;font-size: 14px;line-height: 24px;padding: 6px 0;font-weight: 500;border: none;cursor: pointer;font-family: var(--cy-font);color: var(--cy-primary);background: transparent;text-decoration: underline;text-underline-offset: 2px;text-align: left;word-break: break-word}.cy-btn-do-not-sell:hover{opacity: 0.75}.cy-banner-close{position: absolute;right: 9px;top: 5px;background: none;border: none;cursor: pointer;padding: 0;margin: 0;height: 24px;width: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;color: var(--cy-text)}.cy-banner-close:hover{opacity: 0.6}.cy-banner-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-banner-footer{padding: 20px 0 0;display: flex;justify-content: center;align-items: center}.cy-banner-footer--ccpa{border-top: 1px solid lightgray;margin: 12px -24px 0;padding: 8px 0 0}.cy-branding{display: inline-flex;align-items: center;gap: 5px;font-size: 12px;font-weight: 400;line-height: 20px;color: var(--cy-text);text-decoration: none;opacity: 0.7}.cy-branding:hover{opacity: 1}.cy-branding svg{line-height: 0;color: inherit}@media (prefers-reduced-motion: reduce){.cy-banner,.cy-banner[data-leaving],.cy-dialog-overlay,.cy-dialog,.cy-widget,.cy-reload-notice{animation: none}}@media (max-width: 440px){.cy-banner{left: 0;right: 0;bottom: 0;width: 100%;max-width: 100%;border-radius: 0}.cy-banner-actions{flex-direction: column;gap: 10px}.cy-banner-actions .cy-btn{width: 100%}.cy-banner-actions .cy-btn:nth-child(1){order: 2}.cy-banner-actions .cy-btn:nth-child(2){order: 3}.cy-banner-actions .cy-btn:nth-child(3){order: 1}.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-height: 480px){.cy-banner{max-height: 100vh;overflow-y: auto}.cy-banner-description{max-height: unset;overflow-y: unset}}
package/dist/server.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("@cookieyes/core"),r=require("react/jsx-runtime"),t=require("@cookieyes/scripts");exports.GoogleConsentMode=function(e={}){return r.jsx("script",{dangerouslySetInnerHTML:{__html:t.googleConsentModeSnippet(e)}})},exports.getServerConsent=async function(r={}){const{cookies:t}=await import("next/headers"),o=(await t()).getAll().map(e=>`${e.name}=${e.value}`).join("; ");return e.readServerConsent(o,r)};
1
+ "use strict";var e=require("@cookieyes/core"),r=require("react/jsx-runtime"),o=require("@cookieyes/scripts"),t=require("./styles-CVmKDHmX.cjs");exports.CRITICAL_CSS=t.CRITICAL_CSS,exports.CRITICAL_CSS_HASH=t.CRITICAL_CSS_HASH,exports.CookieYesStyles=t.CookieYesStyles,exports.DEFAULT_STYLES_HREF=t.DEFAULT_STYLES_HREF,exports.GoogleConsentMode=function(e={}){return r.jsx("script",{dangerouslySetInnerHTML:{__html:o.googleConsentModeSnippet(e)}})},exports.getServerConsent=async function(r={}){const{cookies:o}=await import("next/headers"),t=(await o()).getAll().map(e=>`${e.name}=${e.value}`).join("; ");return e.readServerConsent(t,r)};
2
2
  //# sourceMappingURL=server.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.cjs","sources":["../src/google-consent-mode.tsx","../src/server.ts"],"sourcesContent":["import { type ConsentModeOptions, googleConsentModeSnippet } from \"@cookieyes/scripts\";\n\n/**\n * Renders the Google Consent Mode **deny-by-default** as an inline `<script>`,\n * to be placed high in your root layout — before any Google tag and before the\n * SDK boots. This is what lets a returning visitor's saved choice (which the SDK\n * broadcasts as a Consent Mode `update`) land on top of a clean default, instead\n * of the visitor being stuck denied until they act again.\n *\n * The `<script>` is inline and synchronous, so it runs in document order before\n * the client bundle (and before `gtag.js`, which the `ga4()`/`googleAds()`\n * loaders inject). Pass it the same {@link ConsentModeOptions} as the loaders if\n * you need to change the defaults.\n *\n * ```tsx\n * // app/layout.tsx\n * import { GoogleConsentMode } from \"@cookieyes/nextjs/server\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <GoogleConsentMode />\n * {children}\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * Then load the tags on the client with a preset from `@cookieyes/scripts`:\n * `initCookieYes({ integrations: [ga4({ measurementId: \"G-XXXX\" })] })`.\n */\nexport function GoogleConsentMode(props: ConsentModeOptions = {}) {\n return (\n <script\n // biome-ignore lint/security/noDangerouslySetInnerHtml: an inline Consent Mode default is the standard, documented Google pattern.\n dangerouslySetInnerHTML={{ __html: googleConsentModeSnippet(props) }}\n />\n );\n}\n","import {\n type ConsentSnapshot,\n readServerConsent,\n type ServerConsentOptions,\n} from \"@cookieyes/core\";\n\nexport { GoogleConsentMode } from \"./google-consent-mode.js\";\n\n/**\n * Read a returning visitor's stored consent from the incoming request, in a\n * Server Component, Route Handler or middleware.\n *\n * Pass the result to `<CookieYesProvider initialConsent={…}>` and the banner is\n * never sent to a visitor who has already chosen — instead of being sent to\n * everyone and removed on the client, which the visitor sees as the banner\n * appearing and then vanishing.\n *\n * ```tsx\n * // app/layout.tsx\n * import { CookieYesProvider } from \"@cookieyes/nextjs\";\n * import { getServerConsent } from \"@cookieyes/nextjs/server\";\n *\n * export default async function RootLayout({ children }) {\n * const initialConsent = await getServerConsent({ regulation: \"GDPR\" });\n * return (\n * <html lang=\"en\">\n * <body>\n * <CookieYesProvider regulation=\"GDPR\" initialConsent={initialConsent}>\n * {children}\n * </CookieYesProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * Returns `null` when there is no decision on record — a first-time visitor, a\n * cookie recording no choice yet, or one written against a different category\n * taxonomy — in which case the banner renders as usual.\n *\n * This module is server-only: it imports `next/headers`, so keep it out of client\n * components. It lives in `@cookieyes/nextjs/server` rather than the main entry\n * for exactly that reason — the main entry is `\"use client\"`.\n *\n * Reading cookies opts the route into dynamic rendering, as any `cookies()` call\n * does. A statically rendered route has no request to read, so there the banner\n * is server-rendered for everyone and hidden on the client as before.\n */\nexport async function getServerConsent(\n options: ServerConsentOptions = {},\n): Promise<ConsentSnapshot | null> {\n // Imported lazily so merely importing this module doesn't pull `next/headers`\n // into a build that never calls it.\n const { cookies } = await import(\"next/headers\");\n const store = await cookies();\n const header = store\n .getAll()\n .map((c) => `${c.name}=${c.value}`)\n .join(\"; \");\n return readServerConsent(header, options);\n}\n"],"names":["props","jsx","dangerouslySetInnerHTML","__html","googleConsentModeSnippet","async","options","cookies","import","header","getAll","map","c","name","value","join","readServerConsent"],"mappings":"uIAiCO,SAA2BA,EAA4B,IAC5D,OACEC,EAAAA,IAAC,SAAA,CAECC,wBAAyB,CAAEC,OAAQC,EAAAA,yBAAyBJ,KAGlE,2BCQAK,eACEC,EAAgC,IAIhC,MAAMC,QAAEA,SAAkBC,OAAO,gBAE3BC,SADcF,KAEjBG,SACAC,IAAKC,GAAM,GAAGA,EAAEC,QAAQD,EAAEE,SAC1BC,KAAK,MACR,OAAOC,EAAAA,kBAAkBP,EAAQH,EACnC"}
1
+ {"version":3,"file":"server.cjs","sources":["../src/google-consent-mode.tsx","../src/server.ts"],"sourcesContent":["import { type ConsentModeOptions, googleConsentModeSnippet } from \"@cookieyes/scripts\";\n\n/**\n * Renders the Google Consent Mode **deny-by-default** as an inline `<script>`,\n * to be placed high in your root layout — before any Google tag and before the\n * SDK boots. This is what lets a returning visitor's saved choice (which the SDK\n * broadcasts as a Consent Mode `update`) land on top of a clean default, instead\n * of the visitor being stuck denied until they act again.\n *\n * The `<script>` is inline and synchronous, so it runs in document order before\n * the client bundle (and before `gtag.js`, which the `ga4()`/`googleAds()`\n * loaders inject). Pass it the same {@link ConsentModeOptions} as the loaders if\n * you need to change the defaults.\n *\n * ```tsx\n * // app/layout.tsx\n * import { GoogleConsentMode } from \"@cookieyes/nextjs/server\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <GoogleConsentMode />\n * {children}\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * Then load the tags on the client with a preset from `@cookieyes/scripts`:\n * `initCookieYes({ integrations: [ga4({ measurementId: \"G-XXXX\" })] })`.\n */\nexport function GoogleConsentMode(props: ConsentModeOptions = {}) {\n return (\n <script\n // biome-ignore lint/security/noDangerouslySetInnerHtml: an inline Consent Mode default is the standard, documented Google pattern.\n dangerouslySetInnerHTML={{ __html: googleConsentModeSnippet(props) }}\n />\n );\n}\n","import {\n type ConsentSnapshot,\n readServerConsent,\n type ServerConsentOptions,\n} from \"@cookieyes/core\";\n\nexport { GoogleConsentMode } from \"./google-consent-mode.js\";\nexport {\n CookieYesStyles,\n type CookieYesStylesProps,\n CRITICAL_CSS,\n CRITICAL_CSS_HASH,\n DEFAULT_STYLES_HREF,\n} from \"./styles.js\";\n\n/**\n * Read a returning visitor's stored consent from the incoming request, in a\n * Server Component, Route Handler or middleware.\n *\n * Pass the result to `<CookieYesProvider initialConsent={…}>` and the banner is\n * never sent to a visitor who has already chosen — instead of being sent to\n * everyone and removed on the client, which the visitor sees as the banner\n * appearing and then vanishing.\n *\n * ```tsx\n * // app/layout.tsx\n * import { CookieYesProvider } from \"@cookieyes/nextjs\";\n * import { getServerConsent } from \"@cookieyes/nextjs/server\";\n *\n * export default async function RootLayout({ children }) {\n * const initialConsent = await getServerConsent({ regulation: \"GDPR\" });\n * return (\n * <html lang=\"en\">\n * <body>\n * <CookieYesProvider regulation=\"GDPR\" initialConsent={initialConsent}>\n * {children}\n * </CookieYesProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * Returns `null` when there is no decision on record — a first-time visitor, a\n * cookie recording no choice yet, or one written against a different category\n * taxonomy — in which case the banner renders as usual.\n *\n * This module is server-only: it imports `next/headers`, so keep it out of client\n * components. It lives in `@cookieyes/nextjs/server` rather than the main entry\n * for exactly that reason — the main entry is `\"use client\"`.\n *\n * Reading cookies opts the route into dynamic rendering, as any `cookies()` call\n * does. A statically rendered route has no request to read, so there the banner\n * is server-rendered for everyone and hidden on the client as before.\n */\nexport async function getServerConsent(\n options: ServerConsentOptions = {},\n): Promise<ConsentSnapshot | null> {\n // Imported lazily so merely importing this module doesn't pull `next/headers`\n // into a build that never calls it.\n const { cookies } = await import(\"next/headers\");\n const store = await cookies();\n const header = store\n .getAll()\n .map((c) => `${c.name}=${c.value}`)\n .join(\"; \");\n return readServerConsent(header, options);\n}\n"],"names":["props","jsx","dangerouslySetInnerHTML","__html","googleConsentModeSnippet","async","options","cookies","import","header","getAll","map","c","name","value","join","readServerConsent"],"mappings":"wVAiCO,SAA2BA,EAA4B,IAC5D,OACEC,EAAAA,IAAC,SAAA,CAECC,wBAAyB,CAAEC,OAAQC,EAAAA,yBAAyBJ,KAGlE,2BCeAK,eACEC,EAAgC,IAIhC,MAAMC,QAAEA,SAAkBC,OAAO,gBAE3BC,SADcF,KAEjBG,SACAC,IAAKC,GAAM,GAAGA,EAAEC,QAAQD,EAAEE,SAC1BC,KAAK,MACR,OAAOC,EAAAA,kBAAkBP,EAAQH,EACnC"}
package/dist/server.d.ts CHANGED
@@ -35,6 +35,91 @@ import { ConsentModeOptions } from '@cookieyes/scripts';
35
35
  */
36
36
  declare function GoogleConsentMode(props?: ConsentModeOptions): react.JSX.Element;
37
37
 
38
+ /**
39
+ * Build-time constants. Each string below is a sentinel that
40
+ * `rollup.config.mjs`'s `injectCss` plugin replaces with the real value from
41
+ * `@cookieyes/react`'s built output — the same pattern `injectPkgVersion` uses
42
+ * for `CORE_VERSION`. Sentinels rather than an `import` of the CSS because a
43
+ * Server Component cannot import a stylesheet (Turbopack rejects it as a
44
+ * "non-ecmascript placeable asset"), and because the inlined bytes must be
45
+ * exactly the bytes a consumer's CSP hash was computed over.
46
+ *
47
+ * In tests, which run against source, these are the sentinels themselves; the
48
+ * dist-level test in `__tests__/styles.test.tsx` checks the real values.
49
+ */
50
+ /** The banner's paint-critical rules — `@cookieyes/react/critical.css`, verbatim. */
51
+ declare const CRITICAL_CSS = "__CY_CRITICAL_CSS__";
52
+ /**
53
+ * CSP source expression for {@link CRITICAL_CSS}, e.g. `'sha256-…'`, ready to
54
+ * append to `style-src`. Stable for a given SDK version; published in the
55
+ * changelog on every release that changes the stylesheet.
56
+ */
57
+ declare const CRITICAL_CSS_HASH = "__CY_CRITICAL_CSS_HASH__";
58
+ /** The path {@link CookieYesStyles} points at unless told otherwise. */
59
+ declare const DEFAULT_STYLES_HREF = "/cookieyes/styles.css";
60
+ interface CookieYesStylesProps {
61
+ /**
62
+ * Where the full stylesheet is served from — the path of your
63
+ * `styles-route` handler. Defaults to `/cookieyes/styles.css`, matching
64
+ * `app/cookieyes/styles.css/route.ts`.
65
+ */
66
+ href?: string;
67
+ /**
68
+ * A per-request CSP nonce, if you use nonces rather than the published
69
+ * {@link CRITICAL_CSS_HASH}. Either works; the hash needs no server-side
70
+ * plumbing and keeps the page statically cacheable.
71
+ */
72
+ nonce?: string;
73
+ }
74
+ /**
75
+ * Puts the banner's CSS in the first response, so the banner paints in the
76
+ * same frame as the page instead of after a second round trip.
77
+ *
78
+ * Render it once, in your root layout's `<head>`, **instead of** importing
79
+ * `@cookieyes/nextjs/styles.css`. Leaving that import in place puts the full
80
+ * sheet back on the critical path and cancels the gain.
81
+ *
82
+ * ```tsx
83
+ * // app/layout.tsx
84
+ * import { CookieYesStyles } from "@cookieyes/nextjs/server";
85
+ *
86
+ * export default function RootLayout({ children }) {
87
+ * return (
88
+ * <html lang="en">
89
+ * <head>
90
+ * <CookieYesStyles />
91
+ * </head>
92
+ * <body>{children}</body>
93
+ * </html>
94
+ * );
95
+ * }
96
+ * ```
97
+ *
98
+ * ```ts
99
+ * // app/cookieyes/styles.css/route.ts — the SDK serves its own stylesheet
100
+ * export { GET } from "@cookieyes/nextjs/styles-route";
101
+ * ```
102
+ *
103
+ * What it renders:
104
+ *
105
+ * 1. An inline `<style>` holding `critical.css` — only the rules the banner
106
+ * needs to paint. This is the one piece of inline markup, and it is static,
107
+ * so a strict `style-src` policy admits it with a single hash:
108
+ * `style-src 'self' ${CRITICAL_CSS_HASH}`.
109
+ * 2. A `<link>` to the full stylesheet with `media="print"`, which the browser
110
+ * fetches at low priority **without blocking render**. The SDK's client
111
+ * runtime flips it to `media="all"` once mounted — from code that is already
112
+ * shipping, so there is no inline `<script>` and nothing for `script-src`.
113
+ *
114
+ * Measured on the Lighthouse Mobile profile, cold cache: first paint
115
+ * 468 → 224 ms, banner styled 451 → 183 ms. Neutral on fast desktop, where
116
+ * there is no round trip worth saving.
117
+ *
118
+ * Without JavaScript the full sheet stays inert, but the banner is styled by
119
+ * the critical block and the dialogs cannot open without JavaScript anyway.
120
+ */
121
+ declare function CookieYesStyles({ href, nonce }?: CookieYesStylesProps): react.JSX.Element;
122
+
38
123
  /**
39
124
  * Read a returning visitor's stored consent from the incoming request, in a
40
125
  * Server Component, Route Handler or middleware.
@@ -77,4 +162,5 @@ declare function GoogleConsentMode(props?: ConsentModeOptions): react.JSX.Elemen
77
162
  */
78
163
  declare function getServerConsent(options?: ServerConsentOptions): Promise<ConsentSnapshot | null>;
79
164
 
80
- export { GoogleConsentMode, getServerConsent };
165
+ export { CRITICAL_CSS, CRITICAL_CSS_HASH, CookieYesStyles, DEFAULT_STYLES_HREF, GoogleConsentMode, getServerConsent };
166
+ export type { CookieYesStylesProps };
package/dist/server.js CHANGED
@@ -1,2 +1,2 @@
1
- import{readServerConsent as e}from"@cookieyes/core";import{jsx as o}from"react/jsx-runtime";import{googleConsentModeSnippet as r}from"@cookieyes/scripts";function t(e={}){return o("script",{dangerouslySetInnerHTML:{__html:r(e)}})}async function i(o={}){const{cookies:r}=await import("next/headers"),t=(await r()).getAll().map(e=>`${e.name}=${e.value}`).join("; ");return e(t,o)}export{t as GoogleConsentMode,i as getServerConsent};
1
+ import{readServerConsent as e}from"@cookieyes/core";import{jsx as o}from"react/jsx-runtime";import{googleConsentModeSnippet as t}from"@cookieyes/scripts";export{C as CRITICAL_CSS,b as CRITICAL_CSS_HASH,c as CookieYesStyles,D as DEFAULT_STYLES_HREF}from"./styles-DjICYGmj.js";function r(e={}){return o("script",{dangerouslySetInnerHTML:{__html:t(e)}})}async function s(o={}){const{cookies:t}=await import("next/headers"),r=(await t()).getAll().map(e=>`${e.name}=${e.value}`).join("; ");return e(r,o)}export{r as GoogleConsentMode,s as getServerConsent};
2
2
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sources":["../src/google-consent-mode.tsx","../src/server.ts"],"sourcesContent":["import { type ConsentModeOptions, googleConsentModeSnippet } from \"@cookieyes/scripts\";\n\n/**\n * Renders the Google Consent Mode **deny-by-default** as an inline `<script>`,\n * to be placed high in your root layout — before any Google tag and before the\n * SDK boots. This is what lets a returning visitor's saved choice (which the SDK\n * broadcasts as a Consent Mode `update`) land on top of a clean default, instead\n * of the visitor being stuck denied until they act again.\n *\n * The `<script>` is inline and synchronous, so it runs in document order before\n * the client bundle (and before `gtag.js`, which the `ga4()`/`googleAds()`\n * loaders inject). Pass it the same {@link ConsentModeOptions} as the loaders if\n * you need to change the defaults.\n *\n * ```tsx\n * // app/layout.tsx\n * import { GoogleConsentMode } from \"@cookieyes/nextjs/server\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <GoogleConsentMode />\n * {children}\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * Then load the tags on the client with a preset from `@cookieyes/scripts`:\n * `initCookieYes({ integrations: [ga4({ measurementId: \"G-XXXX\" })] })`.\n */\nexport function GoogleConsentMode(props: ConsentModeOptions = {}) {\n return (\n <script\n // biome-ignore lint/security/noDangerouslySetInnerHtml: an inline Consent Mode default is the standard, documented Google pattern.\n dangerouslySetInnerHTML={{ __html: googleConsentModeSnippet(props) }}\n />\n );\n}\n","import {\n type ConsentSnapshot,\n readServerConsent,\n type ServerConsentOptions,\n} from \"@cookieyes/core\";\n\nexport { GoogleConsentMode } from \"./google-consent-mode.js\";\n\n/**\n * Read a returning visitor's stored consent from the incoming request, in a\n * Server Component, Route Handler or middleware.\n *\n * Pass the result to `<CookieYesProvider initialConsent={…}>` and the banner is\n * never sent to a visitor who has already chosen — instead of being sent to\n * everyone and removed on the client, which the visitor sees as the banner\n * appearing and then vanishing.\n *\n * ```tsx\n * // app/layout.tsx\n * import { CookieYesProvider } from \"@cookieyes/nextjs\";\n * import { getServerConsent } from \"@cookieyes/nextjs/server\";\n *\n * export default async function RootLayout({ children }) {\n * const initialConsent = await getServerConsent({ regulation: \"GDPR\" });\n * return (\n * <html lang=\"en\">\n * <body>\n * <CookieYesProvider regulation=\"GDPR\" initialConsent={initialConsent}>\n * {children}\n * </CookieYesProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * Returns `null` when there is no decision on record — a first-time visitor, a\n * cookie recording no choice yet, or one written against a different category\n * taxonomy — in which case the banner renders as usual.\n *\n * This module is server-only: it imports `next/headers`, so keep it out of client\n * components. It lives in `@cookieyes/nextjs/server` rather than the main entry\n * for exactly that reason — the main entry is `\"use client\"`.\n *\n * Reading cookies opts the route into dynamic rendering, as any `cookies()` call\n * does. A statically rendered route has no request to read, so there the banner\n * is server-rendered for everyone and hidden on the client as before.\n */\nexport async function getServerConsent(\n options: ServerConsentOptions = {},\n): Promise<ConsentSnapshot | null> {\n // Imported lazily so merely importing this module doesn't pull `next/headers`\n // into a build that never calls it.\n const { cookies } = await import(\"next/headers\");\n const store = await cookies();\n const header = store\n .getAll()\n .map((c) => `${c.name}=${c.value}`)\n .join(\"; \");\n return readServerConsent(header, options);\n}\n"],"names":["GoogleConsentMode","props","jsx","dangerouslySetInnerHTML","__html","googleConsentModeSnippet","async","getServerConsent","options","cookies","import","header","getAll","map","c","name","value","join","readServerConsent"],"mappings":"0JAiCO,SAASA,EAAkBC,EAA4B,IAC5D,OACEC,EAAC,SAAA,CAECC,wBAAyB,CAAEC,OAAQC,EAAyBJ,KAGlE,CCQAK,eAAsBC,EACpBC,EAAgC,IAIhC,MAAMC,QAAEA,SAAkBC,OAAO,gBAE3BC,SADcF,KAEjBG,SACAC,IAAKC,GAAM,GAAGA,EAAEC,QAAQD,EAAEE,SAC1BC,KAAK,MACR,OAAOC,EAAkBP,EAAQH,EACnC"}
1
+ {"version":3,"file":"server.js","sources":["../src/google-consent-mode.tsx","../src/server.ts"],"sourcesContent":["import { type ConsentModeOptions, googleConsentModeSnippet } from \"@cookieyes/scripts\";\n\n/**\n * Renders the Google Consent Mode **deny-by-default** as an inline `<script>`,\n * to be placed high in your root layout — before any Google tag and before the\n * SDK boots. This is what lets a returning visitor's saved choice (which the SDK\n * broadcasts as a Consent Mode `update`) land on top of a clean default, instead\n * of the visitor being stuck denied until they act again.\n *\n * The `<script>` is inline and synchronous, so it runs in document order before\n * the client bundle (and before `gtag.js`, which the `ga4()`/`googleAds()`\n * loaders inject). Pass it the same {@link ConsentModeOptions} as the loaders if\n * you need to change the defaults.\n *\n * ```tsx\n * // app/layout.tsx\n * import { GoogleConsentMode } from \"@cookieyes/nextjs/server\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <GoogleConsentMode />\n * {children}\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * Then load the tags on the client with a preset from `@cookieyes/scripts`:\n * `initCookieYes({ integrations: [ga4({ measurementId: \"G-XXXX\" })] })`.\n */\nexport function GoogleConsentMode(props: ConsentModeOptions = {}) {\n return (\n <script\n // biome-ignore lint/security/noDangerouslySetInnerHtml: an inline Consent Mode default is the standard, documented Google pattern.\n dangerouslySetInnerHTML={{ __html: googleConsentModeSnippet(props) }}\n />\n );\n}\n","import {\n type ConsentSnapshot,\n readServerConsent,\n type ServerConsentOptions,\n} from \"@cookieyes/core\";\n\nexport { GoogleConsentMode } from \"./google-consent-mode.js\";\nexport {\n CookieYesStyles,\n type CookieYesStylesProps,\n CRITICAL_CSS,\n CRITICAL_CSS_HASH,\n DEFAULT_STYLES_HREF,\n} from \"./styles.js\";\n\n/**\n * Read a returning visitor's stored consent from the incoming request, in a\n * Server Component, Route Handler or middleware.\n *\n * Pass the result to `<CookieYesProvider initialConsent={…}>` and the banner is\n * never sent to a visitor who has already chosen — instead of being sent to\n * everyone and removed on the client, which the visitor sees as the banner\n * appearing and then vanishing.\n *\n * ```tsx\n * // app/layout.tsx\n * import { CookieYesProvider } from \"@cookieyes/nextjs\";\n * import { getServerConsent } from \"@cookieyes/nextjs/server\";\n *\n * export default async function RootLayout({ children }) {\n * const initialConsent = await getServerConsent({ regulation: \"GDPR\" });\n * return (\n * <html lang=\"en\">\n * <body>\n * <CookieYesProvider regulation=\"GDPR\" initialConsent={initialConsent}>\n * {children}\n * </CookieYesProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * Returns `null` when there is no decision on record — a first-time visitor, a\n * cookie recording no choice yet, or one written against a different category\n * taxonomy — in which case the banner renders as usual.\n *\n * This module is server-only: it imports `next/headers`, so keep it out of client\n * components. It lives in `@cookieyes/nextjs/server` rather than the main entry\n * for exactly that reason — the main entry is `\"use client\"`.\n *\n * Reading cookies opts the route into dynamic rendering, as any `cookies()` call\n * does. A statically rendered route has no request to read, so there the banner\n * is server-rendered for everyone and hidden on the client as before.\n */\nexport async function getServerConsent(\n options: ServerConsentOptions = {},\n): Promise<ConsentSnapshot | null> {\n // Imported lazily so merely importing this module doesn't pull `next/headers`\n // into a build that never calls it.\n const { cookies } = await import(\"next/headers\");\n const store = await cookies();\n const header = store\n .getAll()\n .map((c) => `${c.name}=${c.value}`)\n .join(\"; \");\n return readServerConsent(header, options);\n}\n"],"names":["GoogleConsentMode","props","jsx","dangerouslySetInnerHTML","__html","googleConsentModeSnippet","async","getServerConsent","options","cookies","import","header","getAll","map","c","name","value","join","readServerConsent"],"mappings":"mRAiCO,SAASA,EAAkBC,EAA4B,IAC5D,OACEC,EAAC,SAAA,CAECC,wBAAyB,CAAEC,OAAQC,EAAyBJ,KAGlE,CCeAK,eAAsBC,EACpBC,EAAgC,IAIhC,MAAMC,QAAEA,SAAkBC,OAAO,gBAE3BC,SADcF,KAEjBG,SACAC,IAAKC,GAAM,GAAGA,EAAEC,QAAQD,EAAEE,SAC1BC,KAAK,MACR,OAAOC,EAAkBP,EAAQH,EACnC"}
@@ -0,0 +1,2 @@
1
+ "use strict";var e=require("react/jsx-runtime");const o=':root{--cy-primary: #1863dc;--cy-primary-hover: color-mix(in srgb,var(--cy-primary) 85%,black);--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-radius: 6px;--cy-font: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;--cy-focus: var(--cy-primary);--cy-on-primary: #ffffff;--cy-on-widget-bg: #ffffff}@media (prefers-color-scheme: dark){:root{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-outline,.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-always-active{color: #3fbf3f}}.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder{font-family: var(--cy-font);font-size: 14px;font-weight: 400;font-style: normal;line-height: 1.5;letter-spacing: normal;word-spacing: normal;text-align: left;text-transform: none;text-decoration: none;text-indent: 0;text-shadow: none;color: var(--cy-text);direction: ltr;white-space: normal;box-sizing: border-box;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::before,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::after{box-sizing: border-box}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) button,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) input,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) label,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) select,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) textarea{font: inherit;color: inherit;letter-spacing: inherit;text-transform: inherit;text-align: inherit;margin: 0}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) a{color: inherit;text-decoration: none;background: transparent}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) p,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h1,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h2,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h3,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h4,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ul,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ol,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) li{margin: 0;padding: 0;list-style: none}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) svg{display: inline-block;vertical-align: middle}.cy-banner-wrap{display: contents}.cy-banner{position: fixed;left: 40px;bottom: 40px;right: auto;z-index: 9999999;pointer-events: all;background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 -1px 10px 0 rgba(172,171,171,0.3);border: 1px solid var(--cy-border);max-width: 440px;width: min(440px,calc(100vw - 80px));padding: 24px 24px 12px;box-sizing: border-box;animation: cy-fade-in 0.2s ease-out both}.cy-banner[data-leaving]{animation: cy-fade-out 0.2s ease forwards}.cy-banner-wrap[data-cy-entered] .cy-banner:not([data-leaving]){animation: none}@keyframes cy-fade-in{from{opacity: 0}to{opacity: 1}}@keyframes cy-fade-out{from{opacity: 1}to{opacity: 0}}.cy-banner-text{margin-bottom: 0}.cy-banner-title{font-size: 18px;font-weight: 700;line-height: 24px;margin: 0 0 12px;color: var(--cy-text);word-break: break-word}.cy-banner-description{font-size: 14px;line-height: 24px;color: var(--cy-text);margin: 0;word-break: break-word}.cy-banner-description a{color: var(--cy-primary);text-decoration: underline;text-underline-offset: 2px}.cy-banner-actions{display: flex;align-items: center;justify-content: flex-start;gap: 8px;flex-wrap: wrap;margin-top: 16px}.cy-btn{flex: auto;max-width: 100%;cursor: pointer;font-family: var(--cy-font);font-size: 14px;font-weight: 500;border-radius: 2px;padding: 8px;line-height: 24px;transition: opacity 0.15s;text-decoration: none;text-align: center;overflow-wrap: break-word;border: none}.cy-btn:hover{opacity: 0.8}.cy-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-btn-primary{background: var(--cy-primary);color: var(--cy-on-primary);border: 2px solid var(--cy-primary)}.cy-btn-primary:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-btn-outline{background: transparent;color: var(--cy-primary);border: 2px solid var(--cy-primary)}.cy-btn-do-not-sell{flex: 1 0 100%;width: 100%;font-size: 14px;line-height: 24px;padding: 6px 0;font-weight: 500;border: none;cursor: pointer;font-family: var(--cy-font);color: var(--cy-primary);background: transparent;text-decoration: underline;text-underline-offset: 2px;text-align: left;word-break: break-word}.cy-btn-do-not-sell:hover{opacity: 0.75}.cy-banner-close{position: absolute;right: 9px;top: 5px;background: none;border: none;cursor: pointer;padding: 0;margin: 0;height: 24px;width: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;color: var(--cy-text)}.cy-banner-close:hover{opacity: 0.6}.cy-banner-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-banner-footer{padding: 20px 0 0;display: flex;justify-content: center;align-items: center}.cy-banner-footer--ccpa{border-top: 1px solid lightgray;margin: 12px -24px 0;padding: 8px 0 0}.cy-branding{display: inline-flex;align-items: center;gap: 5px;font-size: 12px;font-weight: 400;line-height: 20px;color: var(--cy-text);text-decoration: none;opacity: 0.7}.cy-branding:hover{opacity: 1}.cy-branding svg{line-height: 0;color: inherit}@media (prefers-reduced-motion: reduce){.cy-banner,.cy-banner[data-leaving],.cy-dialog-overlay,.cy-dialog,.cy-widget,.cy-reload-notice{animation: none}}@media (max-width: 440px){.cy-banner{left: 0;right: 0;bottom: 0;width: 100%;max-width: 100%;border-radius: 0}.cy-banner-actions{flex-direction: column;gap: 10px}.cy-banner-actions .cy-btn{width: 100%}.cy-banner-actions .cy-btn:nth-child(1){order: 2}.cy-banner-actions .cy-btn:nth-child(2){order: 3}.cy-banner-actions .cy-btn:nth-child(3){order: 1}.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-height: 480px){.cy-banner{max-height: 100vh;overflow-y: auto}.cy-banner-description{max-height: unset;overflow-y: unset}}\n',r="m5EDS1Mp6L1z",a="/cookieyes/styles.css",t="data-cy-full";exports.CRITICAL_CSS=o,exports.CRITICAL_CSS_HASH="'sha256-+jEHlfPxWea9vHCm7E6kbhSIJxDeAXStC6bUu8jxN8s='",exports.CookieYesStyles=function({href:n=a,nonce:i}={}){const c=`${n}${n.includes("?")?"&":"?"}v=${r}`,l={[t]:""};return e.jsxs(e.Fragment,{children:[e.jsx("style",{nonce:i,dangerouslySetInnerHTML:{__html:o}}),e.jsx("link",{rel:"stylesheet",href:c,media:"print",...l})]})},exports.DEFAULT_STYLES_HREF=a,exports.STYLES_CSS=':root{--cy-primary: #1863dc;--cy-primary-hover: color-mix(in srgb,var(--cy-primary) 85%,black);--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-radius: 6px;--cy-font: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;--cy-focus: var(--cy-primary);--cy-on-primary: #ffffff;--cy-on-widget-bg: #ffffff}@media (prefers-color-scheme: dark){:root{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-outline,.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-always-active{color: #3fbf3f}}[data-cy-scheme="light"]{--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-on-widget-bg: #ffffff}[data-cy-scheme="dark"]{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder{font-family: var(--cy-font);font-size: 14px;font-weight: 400;font-style: normal;line-height: 1.5;letter-spacing: normal;word-spacing: normal;text-align: left;text-transform: none;text-decoration: none;text-indent: 0;text-shadow: none;color: var(--cy-text);direction: ltr;white-space: normal;box-sizing: border-box;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::before,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::after{box-sizing: border-box}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) button,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) input,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) label,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) select,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) textarea{font: inherit;color: inherit;letter-spacing: inherit;text-transform: inherit;text-align: inherit;margin: 0}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) a{color: inherit;text-decoration: none;background: transparent}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) p,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h1,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h2,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h3,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h4,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ul,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ol,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) li{margin: 0;padding: 0;list-style: none}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) svg{display: inline-block;vertical-align: middle}.cy-banner-wrap{display: contents}.cy-banner{position: fixed;left: 40px;bottom: 40px;right: auto;z-index: 9999999;pointer-events: all;background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 -1px 10px 0 rgba(172,171,171,0.3);border: 1px solid var(--cy-border);max-width: 440px;width: min(440px,calc(100vw - 80px));padding: 24px 24px 12px;box-sizing: border-box;animation: cy-fade-in 0.2s ease-out both}.cy-banner[data-leaving]{animation: cy-fade-out 0.2s ease forwards}.cy-banner-wrap[data-cy-entered] .cy-banner:not([data-leaving]){animation: none}@keyframes cy-fade-in{from{opacity: 0}to{opacity: 1}}@keyframes cy-fade-out{from{opacity: 1}to{opacity: 0}}.cy-banner-text{margin-bottom: 0}.cy-banner-title{font-size: 18px;font-weight: 700;line-height: 24px;margin: 0 0 12px;color: var(--cy-text);word-break: break-word}.cy-banner-description{font-size: 14px;line-height: 24px;color: var(--cy-text);margin: 0;word-break: break-word}.cy-banner-description a{color: var(--cy-primary);text-decoration: underline;text-underline-offset: 2px}.cy-banner-actions{display: flex;align-items: center;justify-content: flex-start;gap: 8px;flex-wrap: wrap;margin-top: 16px}.cy-btn{flex: auto;max-width: 100%;cursor: pointer;font-family: var(--cy-font);font-size: 14px;font-weight: 500;border-radius: 2px;padding: 8px;line-height: 24px;transition: opacity 0.15s;text-decoration: none;text-align: center;overflow-wrap: break-word;border: none}.cy-btn:hover{opacity: 0.8}.cy-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-btn-primary{background: var(--cy-primary);color: var(--cy-on-primary);border: 2px solid var(--cy-primary)}.cy-btn-primary:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-btn-outline{background: transparent;color: var(--cy-primary);border: 2px solid var(--cy-primary)}.cy-btn-link{background: none;color: var(--cy-primary);padding: 8px 6px;font-size: 14px;font-weight: 500;text-decoration: underline;text-underline-offset: 2px;border: none}.cy-btn-link:hover{opacity: 0.75}.cy-btn-do-not-sell{flex: 1 0 100%;width: 100%;font-size: 14px;line-height: 24px;padding: 6px 0;font-weight: 500;border: none;cursor: pointer;font-family: var(--cy-font);color: var(--cy-primary);background: transparent;text-decoration: underline;text-underline-offset: 2px;text-align: left;word-break: break-word}.cy-btn-do-not-sell:hover{opacity: 0.75}.cy-banner-close{position: absolute;right: 9px;top: 5px;background: none;border: none;cursor: pointer;padding: 0;margin: 0;height: 24px;width: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;color: var(--cy-text)}.cy-banner-close:hover{opacity: 0.6}.cy-banner-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-show-desc-btn{font-size: 14px;font-family: var(--cy-font);color: var(--cy-primary);text-decoration: none;line-height: 24px;padding: 0;margin: 0;white-space: nowrap;cursor: pointer;background: transparent;border: none}.cy-show-desc-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-banner-footer{padding: 20px 0 0;display: flex;justify-content: center;align-items: center}.cy-banner-footer--ccpa{border-top: 1px solid lightgray;margin: 12px -24px 0;padding: 8px 0 0}.cy-branding{display: inline-flex;align-items: center;gap: 5px;font-size: 12px;font-weight: 400;line-height: 20px;color: var(--cy-text);text-decoration: none;opacity: 0.7}.cy-branding:hover{opacity: 1}.cy-branding svg{line-height: 0;color: inherit}.cy-dialog-overlay{position: fixed;inset: 0;background: rgba(0,0,0,0.4);z-index: 99999999;display: flex;align-items: center;justify-content: center;padding: 20px;box-sizing: border-box;animation: cy-overlay-in 0.3s ease both}@keyframes cy-overlay-in{from{opacity: 0}to{opacity: 1}}.cy-dialog{background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 32px 68px rgba(0,0,0,0.3);width: 100%;max-width: 845px;max-height: 79vh;overflow: hidden;display: flex;flex-direction: column;font-family: var(--cy-font);animation: cy-dialog-slide-up 1s ease both}@keyframes cy-dialog-slide-up{from{transform: translateY(100%)}to{transform: translateY(0)}}.cy-dialog-header{display: flex;align-items: center;justify-content: space-between;padding: 24px 24px 22px;border-bottom: 1px solid var(--cy-border);flex-shrink: 0}.cy-dialog-title{font-size: 18px;font-weight: 700;line-height: 24px;color: var(--cy-text)}.cy-dialog-close{background: none;border: none;cursor: pointer;color: var(--cy-text);padding: 0;margin: 0;width: 24px;height: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;flex-shrink: 0}.cy-dialog-close:hover{opacity: 0.6}.cy-dialog-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-dialog-close svg{width: 10px;height: 10px}.cy-dialog-body{padding: 0 24px;flex: 1;overflow-y: auto;overscroll-behavior: contain}.cy-dialog-content-intro{padding: 12px 0}.cy-dialog-desc{font-size: 14px;color: var(--cy-text);line-height: 24px;margin: 0}.cy-separator{border: none;border-bottom: 1px solid var(--cy-border);margin: 0}.cy-accordion-wrapper{margin-bottom: 10px}.cy-accordion{border-bottom: 1px solid var(--cy-border)}.cy-accordion:last-child{border-bottom: none}.cy-accordion-item{display: flex;margin-top: 10px}.cy-accordion-header-wrapper{flex: 1;min-width: 0}.cy-accordion-header{display: flex;justify-content: space-between;align-items: center;gap: 12px}.cy-accordion-btn{background: none;border: none;cursor: pointer;font-family: var(--cy-font);font-size: 16px;font-weight: 700;color: var(--cy-text);padding: 0;margin: 0;text-align: left;line-height: 24px}.cy-accordion-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-always-active{color: #008000;font-weight: 600;font-size: 14px;line-height: 24px;flex-shrink: 0;white-space: nowrap}.cy-accordion-header-des{margin: 10px 0 16px;font-size: 14px;color: var(--cy-text);line-height: 24px}.cy-accordion-header-des p{font-size: 14px;color: inherit;line-height: 24px;margin: 0;word-break: break-word}.cy-accordion-body{padding: 0 22px;margin-bottom: 16px}.cy-audit-table{background: #f4f4f4;border-radius: 6px}.cy-empty-cookies-text{font-size: 12px;line-height: 24px;color: var(--cy-text);margin: 0;padding: 10px;word-break: break-word}.cy-cookie-des-table{font-size: 12px;line-height: 24px;font-weight: 400;padding: 15px 10px;border-bottom: 1px solid #ebebeb;margin: 0;list-style: none}.cy-cookie-des-table:last-child{border-bottom: none}.cy-cookie-des-table li{list-style-type: none;display: flex;padding: 3px 0}.cy-cookie-des-table li:first-child{padding-top: 0}.cy-cookie-des-table li div:first-child{width: 100px;flex-shrink: 0;font-weight: 600;word-break: break-word;overflow-wrap: break-word}.cy-cookie-des-table li div:last-child{flex: 1;word-break: break-word;overflow-wrap: break-word;margin-left: 8px}.cy-btn-cancel{background: transparent;color: var(--cy-muted);border: 1px solid var(--cy-muted)}.cy-btn-cancel:hover{opacity: 0.8}.cy-btn-confirm{background: var(--cy-primary);color: var(--cy-on-primary);border: 1px solid var(--cy-primary)}.cy-btn-confirm:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-optout-dialog{max-height: fit-content}.cy-optout-footer{flex-shrink: 0;position: relative}.cy-optout-action-area{padding: 0 24px 22px;box-sizing: border-box}.cy-optout-btn-wrapper{display: flex;flex-wrap: wrap;gap: 8px;align-items: center;justify-content: center;padding-top: 22px}.cy-optout-btn-wrapper .cy-btn{flex: 1 1 auto}.cy-optout-powered-by{display: flex;justify-content: center;align-items: center;margin-top: 8px;padding-bottom: 12px}.cy-optout-checkbox-wrapper{display: flex;align-items: center;padding: 12px 0}.cy-optout-checkbox{appearance: none;-webkit-appearance: none;width: 20px;height: 18.5px;min-width: 20px;border: 1px solid #000;border-radius: 2px;background: #fff;cursor: pointer;flex-shrink: 0;position: relative;margin: 0;padding: 0}.cy-optout-checkbox:checked{background: var(--cy-primary);border-color: var(--cy-primary)}.cy-optout-checkbox:checked::after{content: "";position: absolute;left: 6px;bottom: 4px;width: 7px;height: 13px;border: solid #fff;border-width: 0 3px 3px 0;border-radius: 2px;transform: rotate(45deg)}.cy-optout-checkbox:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-optout-checkbox-label{font-size: 16px;font-weight: 700;line-height: 24px;color: var(--cy-text);margin-left: 12px;cursor: pointer;font-family: var(--cy-font)}.cy-optout-checkbox:disabled{cursor: not-allowed}.cy-optout-checkbox:disabled + .cy-optout-checkbox-label{cursor: not-allowed}.cy-optout-success{background: #e5f4ef;border-radius: 8px;padding: 8px 12px;box-sizing: border-box;outline: none;margin: 0 auto;width: 100%}.cy-optout-success-inner{display: flex;flex-direction: column;gap: 4px}.cy-optout-success-row{display: flex;align-items: flex-start}.cy-optout-success-icon{width: 20px;flex-shrink: 0;color: #00754e}.cy-optout-success-text{margin-inline-start: 8px;margin-top: 1px;font-size: 13px;font-weight: 400;color: #14142a;line-height: 20px}.cy-optout-success-subtext-wrapper{}.cy-optout-success-subtext{margin: 0;font-size: 12px;font-weight: 400;color: #4e4b66;line-height: 20px}.cy-toggle{position: relative;flex-shrink: 0;width: 44px;height: 24px;display: flex;cursor: pointer}.cy-toggle input{position: absolute;width: 44px;height: 24px;margin: 0;opacity: 0;top: 0;left: 0;z-index: 1;cursor: pointer}.cy-toggle-track{position: absolute;inset: 0;background: #8a8a8a;border-radius: 50px;transition: background 0.18s ease}.cy-toggle input:checked ~ .cy-toggle-track{background: var(--cy-primary)}.cy-toggle-thumb{position: absolute;top: 2px;left: 2px;width: 20px;height: 20px;background: #fff;border-radius: 50%;box-shadow: 0 1px 3px rgba(0,0,0,0.25);transition: transform 0.4s ease;pointer-events: none}.cy-toggle input:checked ~ .cy-toggle-track .cy-toggle-thumb{transform: translateX(20px)}.cy-toggle input:focus-visible ~ .cy-toggle-track{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-dialog-footer{padding: 22px 24px 12px;flex-shrink: 0;border-top: 1px solid var(--cy-border);display: flex;flex-direction: column;align-items: center;gap: 12px;position: relative}.cy-dialog-footer-shadow{display: block;width: 100%;height: 40px;background: linear-gradient(180deg,rgba(255,255,255,0) 0%,var(--cy-bg) 100%);position: absolute;bottom: calc(100% - 1px);left: 0;pointer-events: none}.cy-dialog-footer-actions{display: flex;flex-wrap: wrap;gap: 8px;width: 100%;justify-content: center}.cy-dialog-footer-actions .cy-btn{flex: auto}.cy-widget{position: fixed;bottom: 15px;left: 15px;z-index: 99999999;width: 45px;height: 45px;border-radius: 50%;background: var(--cy-widget-bg);color: var(--cy-on-widget-bg);border: none;cursor: pointer;display: flex;align-items: center;justify-content: center;animation: cy-widget-pop 0.4s cubic-bezier(0.34,1.56,0.64,1) both}.cy-widget:focus-visible{outline: 3px solid var(--cy-focus);outline-offset: 3px}.cy-widget::before{content: attr(data-tooltip);position: absolute;background: #4e4b66;color: #fff;left: calc(100% + 7px);font-size: 12px;line-height: 16px;width: max-content;padding: 4px 8px;border-radius: 4px;font-family: var(--cy-font);opacity: 0;pointer-events: none;white-space: nowrap}.cy-widget::after{content: "";position: absolute;border: 5px solid transparent;border-right-color: #4e4b66;left: calc(100% + 2px);opacity: 0;pointer-events: none}.cy-widget:hover::before,.cy-widget:hover::after{opacity: 1}@keyframes cy-widget-pop{from{opacity: 0;transform: scale(0.4)}to{opacity: 1;transform: scale(1)}}.cy-reload-notice{position: fixed;bottom: 20px;left: 50%;transform: translateX(-50%);z-index: 99999999;max-width: min(520px,calc(100vw - 40px));display: flex;flex-wrap: wrap;align-items: center;gap: 12px;padding: 14px 18px;background: var(--cy-bg);color: var(--cy-text);border: 1px solid var(--cy-border);border-radius: var(--cy-radius);box-shadow: 0 4px 20px rgba(0,0,0,0.18);animation: cy-reload-notice-in 0.3s ease both}@keyframes cy-reload-notice-in{from{opacity: 0;transform: translate(-50%,12px)}to{opacity: 1;transform: translate(-50%,0)}}.cy-reload-notice-text{flex: 1 1 220px;font-size: 14px;line-height: 20px}.cy-reload-notice-actions{display: flex;gap: 8px;flex-shrink: 0}.cy-reload-notice .cy-btn{flex: 0 0 auto;padding: 6px 12px}@media (prefers-reduced-motion: reduce){.cy-banner,.cy-banner[data-leaving],.cy-dialog-overlay,.cy-dialog,.cy-widget,.cy-reload-notice{animation: none}}.cy-frame-placeholder{background: var(--cy-bg);border: 1.5px dashed var(--cy-border);border-radius: calc(var(--cy-radius) * 0.6);display: flex;flex-direction: column;align-items: center;justify-content: center;gap: 12px;padding: 32px 24px;text-align: center;font-family: var(--cy-font);color: var(--cy-muted);font-size: 14px;min-height: 120px}@media (max-width: 440px){.cy-banner{left: 0;right: 0;bottom: 0;width: 100%;max-width: 100%;border-radius: 0}.cy-banner-actions{flex-direction: column;gap: 10px}.cy-banner-actions .cy-btn{width: 100%}.cy-banner-actions .cy-btn:nth-child(1){order: 2}.cy-banner-actions .cy-btn:nth-child(2){order: 3}.cy-banner-actions .cy-btn:nth-child(3){order: 1}.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-width: 845px){.cy-dialog-overlay{padding: 8px}}@media (max-width: 576px){.cy-dialog-overlay{padding: 0;align-items: stretch}.cy-dialog{max-width: 100%;border-radius: 0;max-height: 100vh;height: 100vh}.cy-dialog-footer-actions{flex-direction: column;gap: 10px}.cy-dialog-footer-actions .cy-btn{width: 100%}.cy-dialog-footer-actions .cy-btn:nth-child(1){order: 3}.cy-dialog-footer-actions .cy-btn:nth-child(2){order: 2}.cy-dialog-footer-actions .cy-btn:nth-child(3){order: 1}}@media (max-width: 425px){.cy-accordion-body{padding: 0 15px}.cy-toggle,.cy-toggle input{width: 38px;height: 21px}.cy-toggle-thumb{width: 17px;height: 17px}.cy-toggle input:checked ~ .cy-toggle-track .cy-toggle-thumb{transform: translateX(17px)}}@media (max-width: 352px){.cy-banner-title{font-size: 16px}.cy-banner-description,.cy-banner-description *,.cy-banner-actions .cy-btn,.cy-btn-do-not-sell{font-size: 12px}.cy-dialog-title{font-size: 16px}.cy-dialog-header{padding: 16px 24px}.cy-dialog-desc,.cy-dialog-desc *,.cy-accordion-header-des,.cy-accordion-header-des *,.cy-show-desc-btn,.cy-banner-description a{font-size: 12px}.cy-accordion-btn{font-size: 14px}.cy-optout-checkbox-label{font-size: 14px}.cy-optout-checkbox{width: 16px;min-width: 16px;height: 16px}.cy-optout-checkbox:checked::after{left: 5px;bottom: 4px;width: 3px;height: 9px}}@media (max-height: 480px){.cy-banner{max-height: 100vh;overflow-y: auto}.cy-banner-description{max-height: unset;overflow-y: unset}}@media (min-width: 576px) and (max-height: 660px){.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-height: 576px){.cy-dialog{height: 100vh;overflow: auto}.cy-dialog-body{overflow: unset}}.cy-banner-description img,.cy-dialog-desc img,.cy-accordion-header-des img{min-height: 25px;min-width: 25px}.cy-banner-wrap[data-cy-scheme="dark"] .cy-btn-outline,.cy-dialog-overlay[data-cy-scheme="dark"] .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap[data-cy-scheme="dark"] .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay[data-cy-scheme="dark"] .cy-always-active{color: #3fbf3f}\n',exports.STYLES_CSS_VERSION=r;
2
+ //# sourceMappingURL=styles-CVmKDHmX.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles-CVmKDHmX.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import{jsxs as e,Fragment as o,jsx as r}from"react/jsx-runtime";const a=':root{--cy-primary: #1863dc;--cy-primary-hover: color-mix(in srgb,var(--cy-primary) 85%,black);--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-radius: 6px;--cy-font: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;--cy-focus: var(--cy-primary);--cy-on-primary: #ffffff;--cy-on-widget-bg: #ffffff}@media (prefers-color-scheme: dark){:root{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-outline,.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-always-active{color: #3fbf3f}}.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder{font-family: var(--cy-font);font-size: 14px;font-weight: 400;font-style: normal;line-height: 1.5;letter-spacing: normal;word-spacing: normal;text-align: left;text-transform: none;text-decoration: none;text-indent: 0;text-shadow: none;color: var(--cy-text);direction: ltr;white-space: normal;box-sizing: border-box;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::before,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::after{box-sizing: border-box}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) button,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) input,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) label,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) select,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) textarea{font: inherit;color: inherit;letter-spacing: inherit;text-transform: inherit;text-align: inherit;margin: 0}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) a{color: inherit;text-decoration: none;background: transparent}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) p,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h1,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h2,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h3,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h4,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ul,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ol,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) li{margin: 0;padding: 0;list-style: none}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) svg{display: inline-block;vertical-align: middle}.cy-banner-wrap{display: contents}.cy-banner{position: fixed;left: 40px;bottom: 40px;right: auto;z-index: 9999999;pointer-events: all;background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 -1px 10px 0 rgba(172,171,171,0.3);border: 1px solid var(--cy-border);max-width: 440px;width: min(440px,calc(100vw - 80px));padding: 24px 24px 12px;box-sizing: border-box;animation: cy-fade-in 0.2s ease-out both}.cy-banner[data-leaving]{animation: cy-fade-out 0.2s ease forwards}.cy-banner-wrap[data-cy-entered] .cy-banner:not([data-leaving]){animation: none}@keyframes cy-fade-in{from{opacity: 0}to{opacity: 1}}@keyframes cy-fade-out{from{opacity: 1}to{opacity: 0}}.cy-banner-text{margin-bottom: 0}.cy-banner-title{font-size: 18px;font-weight: 700;line-height: 24px;margin: 0 0 12px;color: var(--cy-text);word-break: break-word}.cy-banner-description{font-size: 14px;line-height: 24px;color: var(--cy-text);margin: 0;word-break: break-word}.cy-banner-description a{color: var(--cy-primary);text-decoration: underline;text-underline-offset: 2px}.cy-banner-actions{display: flex;align-items: center;justify-content: flex-start;gap: 8px;flex-wrap: wrap;margin-top: 16px}.cy-btn{flex: auto;max-width: 100%;cursor: pointer;font-family: var(--cy-font);font-size: 14px;font-weight: 500;border-radius: 2px;padding: 8px;line-height: 24px;transition: opacity 0.15s;text-decoration: none;text-align: center;overflow-wrap: break-word;border: none}.cy-btn:hover{opacity: 0.8}.cy-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-btn-primary{background: var(--cy-primary);color: var(--cy-on-primary);border: 2px solid var(--cy-primary)}.cy-btn-primary:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-btn-outline{background: transparent;color: var(--cy-primary);border: 2px solid var(--cy-primary)}.cy-btn-do-not-sell{flex: 1 0 100%;width: 100%;font-size: 14px;line-height: 24px;padding: 6px 0;font-weight: 500;border: none;cursor: pointer;font-family: var(--cy-font);color: var(--cy-primary);background: transparent;text-decoration: underline;text-underline-offset: 2px;text-align: left;word-break: break-word}.cy-btn-do-not-sell:hover{opacity: 0.75}.cy-banner-close{position: absolute;right: 9px;top: 5px;background: none;border: none;cursor: pointer;padding: 0;margin: 0;height: 24px;width: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;color: var(--cy-text)}.cy-banner-close:hover{opacity: 0.6}.cy-banner-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-banner-footer{padding: 20px 0 0;display: flex;justify-content: center;align-items: center}.cy-banner-footer--ccpa{border-top: 1px solid lightgray;margin: 12px -24px 0;padding: 8px 0 0}.cy-branding{display: inline-flex;align-items: center;gap: 5px;font-size: 12px;font-weight: 400;line-height: 20px;color: var(--cy-text);text-decoration: none;opacity: 0.7}.cy-branding:hover{opacity: 1}.cy-branding svg{line-height: 0;color: inherit}@media (prefers-reduced-motion: reduce){.cy-banner,.cy-banner[data-leaving],.cy-dialog-overlay,.cy-dialog,.cy-widget,.cy-reload-notice{animation: none}}@media (max-width: 440px){.cy-banner{left: 0;right: 0;bottom: 0;width: 100%;max-width: 100%;border-radius: 0}.cy-banner-actions{flex-direction: column;gap: 10px}.cy-banner-actions .cy-btn{width: 100%}.cy-banner-actions .cy-btn:nth-child(1){order: 2}.cy-banner-actions .cy-btn:nth-child(2){order: 3}.cy-banner-actions .cy-btn:nth-child(3){order: 1}.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-height: 480px){.cy-banner{max-height: 100vh;overflow-y: auto}.cy-banner-description{max-height: unset;overflow-y: unset}}\n',t="'sha256-+jEHlfPxWea9vHCm7E6kbhSIJxDeAXStC6bUu8jxN8s='",n=':root{--cy-primary: #1863dc;--cy-primary-hover: color-mix(in srgb,var(--cy-primary) 85%,black);--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-radius: 6px;--cy-font: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;--cy-focus: var(--cy-primary);--cy-on-primary: #ffffff;--cy-on-widget-bg: #ffffff}@media (prefers-color-scheme: dark){:root{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-outline,.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-always-active{color: #3fbf3f}}[data-cy-scheme="light"]{--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-on-widget-bg: #ffffff}[data-cy-scheme="dark"]{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder{font-family: var(--cy-font);font-size: 14px;font-weight: 400;font-style: normal;line-height: 1.5;letter-spacing: normal;word-spacing: normal;text-align: left;text-transform: none;text-decoration: none;text-indent: 0;text-shadow: none;color: var(--cy-text);direction: ltr;white-space: normal;box-sizing: border-box;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::before,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::after{box-sizing: border-box}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) button,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) input,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) label,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) select,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) textarea{font: inherit;color: inherit;letter-spacing: inherit;text-transform: inherit;text-align: inherit;margin: 0}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) a{color: inherit;text-decoration: none;background: transparent}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) p,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h1,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h2,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h3,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h4,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ul,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ol,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) li{margin: 0;padding: 0;list-style: none}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) svg{display: inline-block;vertical-align: middle}.cy-banner-wrap{display: contents}.cy-banner{position: fixed;left: 40px;bottom: 40px;right: auto;z-index: 9999999;pointer-events: all;background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 -1px 10px 0 rgba(172,171,171,0.3);border: 1px solid var(--cy-border);max-width: 440px;width: min(440px,calc(100vw - 80px));padding: 24px 24px 12px;box-sizing: border-box;animation: cy-fade-in 0.2s ease-out both}.cy-banner[data-leaving]{animation: cy-fade-out 0.2s ease forwards}.cy-banner-wrap[data-cy-entered] .cy-banner:not([data-leaving]){animation: none}@keyframes cy-fade-in{from{opacity: 0}to{opacity: 1}}@keyframes cy-fade-out{from{opacity: 1}to{opacity: 0}}.cy-banner-text{margin-bottom: 0}.cy-banner-title{font-size: 18px;font-weight: 700;line-height: 24px;margin: 0 0 12px;color: var(--cy-text);word-break: break-word}.cy-banner-description{font-size: 14px;line-height: 24px;color: var(--cy-text);margin: 0;word-break: break-word}.cy-banner-description a{color: var(--cy-primary);text-decoration: underline;text-underline-offset: 2px}.cy-banner-actions{display: flex;align-items: center;justify-content: flex-start;gap: 8px;flex-wrap: wrap;margin-top: 16px}.cy-btn{flex: auto;max-width: 100%;cursor: pointer;font-family: var(--cy-font);font-size: 14px;font-weight: 500;border-radius: 2px;padding: 8px;line-height: 24px;transition: opacity 0.15s;text-decoration: none;text-align: center;overflow-wrap: break-word;border: none}.cy-btn:hover{opacity: 0.8}.cy-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-btn-primary{background: var(--cy-primary);color: var(--cy-on-primary);border: 2px solid var(--cy-primary)}.cy-btn-primary:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-btn-outline{background: transparent;color: var(--cy-primary);border: 2px solid var(--cy-primary)}.cy-btn-link{background: none;color: var(--cy-primary);padding: 8px 6px;font-size: 14px;font-weight: 500;text-decoration: underline;text-underline-offset: 2px;border: none}.cy-btn-link:hover{opacity: 0.75}.cy-btn-do-not-sell{flex: 1 0 100%;width: 100%;font-size: 14px;line-height: 24px;padding: 6px 0;font-weight: 500;border: none;cursor: pointer;font-family: var(--cy-font);color: var(--cy-primary);background: transparent;text-decoration: underline;text-underline-offset: 2px;text-align: left;word-break: break-word}.cy-btn-do-not-sell:hover{opacity: 0.75}.cy-banner-close{position: absolute;right: 9px;top: 5px;background: none;border: none;cursor: pointer;padding: 0;margin: 0;height: 24px;width: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;color: var(--cy-text)}.cy-banner-close:hover{opacity: 0.6}.cy-banner-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-show-desc-btn{font-size: 14px;font-family: var(--cy-font);color: var(--cy-primary);text-decoration: none;line-height: 24px;padding: 0;margin: 0;white-space: nowrap;cursor: pointer;background: transparent;border: none}.cy-show-desc-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-banner-footer{padding: 20px 0 0;display: flex;justify-content: center;align-items: center}.cy-banner-footer--ccpa{border-top: 1px solid lightgray;margin: 12px -24px 0;padding: 8px 0 0}.cy-branding{display: inline-flex;align-items: center;gap: 5px;font-size: 12px;font-weight: 400;line-height: 20px;color: var(--cy-text);text-decoration: none;opacity: 0.7}.cy-branding:hover{opacity: 1}.cy-branding svg{line-height: 0;color: inherit}.cy-dialog-overlay{position: fixed;inset: 0;background: rgba(0,0,0,0.4);z-index: 99999999;display: flex;align-items: center;justify-content: center;padding: 20px;box-sizing: border-box;animation: cy-overlay-in 0.3s ease both}@keyframes cy-overlay-in{from{opacity: 0}to{opacity: 1}}.cy-dialog{background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 32px 68px rgba(0,0,0,0.3);width: 100%;max-width: 845px;max-height: 79vh;overflow: hidden;display: flex;flex-direction: column;font-family: var(--cy-font);animation: cy-dialog-slide-up 1s ease both}@keyframes cy-dialog-slide-up{from{transform: translateY(100%)}to{transform: translateY(0)}}.cy-dialog-header{display: flex;align-items: center;justify-content: space-between;padding: 24px 24px 22px;border-bottom: 1px solid var(--cy-border);flex-shrink: 0}.cy-dialog-title{font-size: 18px;font-weight: 700;line-height: 24px;color: var(--cy-text)}.cy-dialog-close{background: none;border: none;cursor: pointer;color: var(--cy-text);padding: 0;margin: 0;width: 24px;height: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;flex-shrink: 0}.cy-dialog-close:hover{opacity: 0.6}.cy-dialog-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-dialog-close svg{width: 10px;height: 10px}.cy-dialog-body{padding: 0 24px;flex: 1;overflow-y: auto;overscroll-behavior: contain}.cy-dialog-content-intro{padding: 12px 0}.cy-dialog-desc{font-size: 14px;color: var(--cy-text);line-height: 24px;margin: 0}.cy-separator{border: none;border-bottom: 1px solid var(--cy-border);margin: 0}.cy-accordion-wrapper{margin-bottom: 10px}.cy-accordion{border-bottom: 1px solid var(--cy-border)}.cy-accordion:last-child{border-bottom: none}.cy-accordion-item{display: flex;margin-top: 10px}.cy-accordion-header-wrapper{flex: 1;min-width: 0}.cy-accordion-header{display: flex;justify-content: space-between;align-items: center;gap: 12px}.cy-accordion-btn{background: none;border: none;cursor: pointer;font-family: var(--cy-font);font-size: 16px;font-weight: 700;color: var(--cy-text);padding: 0;margin: 0;text-align: left;line-height: 24px}.cy-accordion-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-always-active{color: #008000;font-weight: 600;font-size: 14px;line-height: 24px;flex-shrink: 0;white-space: nowrap}.cy-accordion-header-des{margin: 10px 0 16px;font-size: 14px;color: var(--cy-text);line-height: 24px}.cy-accordion-header-des p{font-size: 14px;color: inherit;line-height: 24px;margin: 0;word-break: break-word}.cy-accordion-body{padding: 0 22px;margin-bottom: 16px}.cy-audit-table{background: #f4f4f4;border-radius: 6px}.cy-empty-cookies-text{font-size: 12px;line-height: 24px;color: var(--cy-text);margin: 0;padding: 10px;word-break: break-word}.cy-cookie-des-table{font-size: 12px;line-height: 24px;font-weight: 400;padding: 15px 10px;border-bottom: 1px solid #ebebeb;margin: 0;list-style: none}.cy-cookie-des-table:last-child{border-bottom: none}.cy-cookie-des-table li{list-style-type: none;display: flex;padding: 3px 0}.cy-cookie-des-table li:first-child{padding-top: 0}.cy-cookie-des-table li div:first-child{width: 100px;flex-shrink: 0;font-weight: 600;word-break: break-word;overflow-wrap: break-word}.cy-cookie-des-table li div:last-child{flex: 1;word-break: break-word;overflow-wrap: break-word;margin-left: 8px}.cy-btn-cancel{background: transparent;color: var(--cy-muted);border: 1px solid var(--cy-muted)}.cy-btn-cancel:hover{opacity: 0.8}.cy-btn-confirm{background: var(--cy-primary);color: var(--cy-on-primary);border: 1px solid var(--cy-primary)}.cy-btn-confirm:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-optout-dialog{max-height: fit-content}.cy-optout-footer{flex-shrink: 0;position: relative}.cy-optout-action-area{padding: 0 24px 22px;box-sizing: border-box}.cy-optout-btn-wrapper{display: flex;flex-wrap: wrap;gap: 8px;align-items: center;justify-content: center;padding-top: 22px}.cy-optout-btn-wrapper .cy-btn{flex: 1 1 auto}.cy-optout-powered-by{display: flex;justify-content: center;align-items: center;margin-top: 8px;padding-bottom: 12px}.cy-optout-checkbox-wrapper{display: flex;align-items: center;padding: 12px 0}.cy-optout-checkbox{appearance: none;-webkit-appearance: none;width: 20px;height: 18.5px;min-width: 20px;border: 1px solid #000;border-radius: 2px;background: #fff;cursor: pointer;flex-shrink: 0;position: relative;margin: 0;padding: 0}.cy-optout-checkbox:checked{background: var(--cy-primary);border-color: var(--cy-primary)}.cy-optout-checkbox:checked::after{content: "";position: absolute;left: 6px;bottom: 4px;width: 7px;height: 13px;border: solid #fff;border-width: 0 3px 3px 0;border-radius: 2px;transform: rotate(45deg)}.cy-optout-checkbox:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-optout-checkbox-label{font-size: 16px;font-weight: 700;line-height: 24px;color: var(--cy-text);margin-left: 12px;cursor: pointer;font-family: var(--cy-font)}.cy-optout-checkbox:disabled{cursor: not-allowed}.cy-optout-checkbox:disabled + .cy-optout-checkbox-label{cursor: not-allowed}.cy-optout-success{background: #e5f4ef;border-radius: 8px;padding: 8px 12px;box-sizing: border-box;outline: none;margin: 0 auto;width: 100%}.cy-optout-success-inner{display: flex;flex-direction: column;gap: 4px}.cy-optout-success-row{display: flex;align-items: flex-start}.cy-optout-success-icon{width: 20px;flex-shrink: 0;color: #00754e}.cy-optout-success-text{margin-inline-start: 8px;margin-top: 1px;font-size: 13px;font-weight: 400;color: #14142a;line-height: 20px}.cy-optout-success-subtext-wrapper{}.cy-optout-success-subtext{margin: 0;font-size: 12px;font-weight: 400;color: #4e4b66;line-height: 20px}.cy-toggle{position: relative;flex-shrink: 0;width: 44px;height: 24px;display: flex;cursor: pointer}.cy-toggle input{position: absolute;width: 44px;height: 24px;margin: 0;opacity: 0;top: 0;left: 0;z-index: 1;cursor: pointer}.cy-toggle-track{position: absolute;inset: 0;background: #8a8a8a;border-radius: 50px;transition: background 0.18s ease}.cy-toggle input:checked ~ .cy-toggle-track{background: var(--cy-primary)}.cy-toggle-thumb{position: absolute;top: 2px;left: 2px;width: 20px;height: 20px;background: #fff;border-radius: 50%;box-shadow: 0 1px 3px rgba(0,0,0,0.25);transition: transform 0.4s ease;pointer-events: none}.cy-toggle input:checked ~ .cy-toggle-track .cy-toggle-thumb{transform: translateX(20px)}.cy-toggle input:focus-visible ~ .cy-toggle-track{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-dialog-footer{padding: 22px 24px 12px;flex-shrink: 0;border-top: 1px solid var(--cy-border);display: flex;flex-direction: column;align-items: center;gap: 12px;position: relative}.cy-dialog-footer-shadow{display: block;width: 100%;height: 40px;background: linear-gradient(180deg,rgba(255,255,255,0) 0%,var(--cy-bg) 100%);position: absolute;bottom: calc(100% - 1px);left: 0;pointer-events: none}.cy-dialog-footer-actions{display: flex;flex-wrap: wrap;gap: 8px;width: 100%;justify-content: center}.cy-dialog-footer-actions .cy-btn{flex: auto}.cy-widget{position: fixed;bottom: 15px;left: 15px;z-index: 99999999;width: 45px;height: 45px;border-radius: 50%;background: var(--cy-widget-bg);color: var(--cy-on-widget-bg);border: none;cursor: pointer;display: flex;align-items: center;justify-content: center;animation: cy-widget-pop 0.4s cubic-bezier(0.34,1.56,0.64,1) both}.cy-widget:focus-visible{outline: 3px solid var(--cy-focus);outline-offset: 3px}.cy-widget::before{content: attr(data-tooltip);position: absolute;background: #4e4b66;color: #fff;left: calc(100% + 7px);font-size: 12px;line-height: 16px;width: max-content;padding: 4px 8px;border-radius: 4px;font-family: var(--cy-font);opacity: 0;pointer-events: none;white-space: nowrap}.cy-widget::after{content: "";position: absolute;border: 5px solid transparent;border-right-color: #4e4b66;left: calc(100% + 2px);opacity: 0;pointer-events: none}.cy-widget:hover::before,.cy-widget:hover::after{opacity: 1}@keyframes cy-widget-pop{from{opacity: 0;transform: scale(0.4)}to{opacity: 1;transform: scale(1)}}.cy-reload-notice{position: fixed;bottom: 20px;left: 50%;transform: translateX(-50%);z-index: 99999999;max-width: min(520px,calc(100vw - 40px));display: flex;flex-wrap: wrap;align-items: center;gap: 12px;padding: 14px 18px;background: var(--cy-bg);color: var(--cy-text);border: 1px solid var(--cy-border);border-radius: var(--cy-radius);box-shadow: 0 4px 20px rgba(0,0,0,0.18);animation: cy-reload-notice-in 0.3s ease both}@keyframes cy-reload-notice-in{from{opacity: 0;transform: translate(-50%,12px)}to{opacity: 1;transform: translate(-50%,0)}}.cy-reload-notice-text{flex: 1 1 220px;font-size: 14px;line-height: 20px}.cy-reload-notice-actions{display: flex;gap: 8px;flex-shrink: 0}.cy-reload-notice .cy-btn{flex: 0 0 auto;padding: 6px 12px}@media (prefers-reduced-motion: reduce){.cy-banner,.cy-banner[data-leaving],.cy-dialog-overlay,.cy-dialog,.cy-widget,.cy-reload-notice{animation: none}}.cy-frame-placeholder{background: var(--cy-bg);border: 1.5px dashed var(--cy-border);border-radius: calc(var(--cy-radius) * 0.6);display: flex;flex-direction: column;align-items: center;justify-content: center;gap: 12px;padding: 32px 24px;text-align: center;font-family: var(--cy-font);color: var(--cy-muted);font-size: 14px;min-height: 120px}@media (max-width: 440px){.cy-banner{left: 0;right: 0;bottom: 0;width: 100%;max-width: 100%;border-radius: 0}.cy-banner-actions{flex-direction: column;gap: 10px}.cy-banner-actions .cy-btn{width: 100%}.cy-banner-actions .cy-btn:nth-child(1){order: 2}.cy-banner-actions .cy-btn:nth-child(2){order: 3}.cy-banner-actions .cy-btn:nth-child(3){order: 1}.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-width: 845px){.cy-dialog-overlay{padding: 8px}}@media (max-width: 576px){.cy-dialog-overlay{padding: 0;align-items: stretch}.cy-dialog{max-width: 100%;border-radius: 0;max-height: 100vh;height: 100vh}.cy-dialog-footer-actions{flex-direction: column;gap: 10px}.cy-dialog-footer-actions .cy-btn{width: 100%}.cy-dialog-footer-actions .cy-btn:nth-child(1){order: 3}.cy-dialog-footer-actions .cy-btn:nth-child(2){order: 2}.cy-dialog-footer-actions .cy-btn:nth-child(3){order: 1}}@media (max-width: 425px){.cy-accordion-body{padding: 0 15px}.cy-toggle,.cy-toggle input{width: 38px;height: 21px}.cy-toggle-thumb{width: 17px;height: 17px}.cy-toggle input:checked ~ .cy-toggle-track .cy-toggle-thumb{transform: translateX(17px)}}@media (max-width: 352px){.cy-banner-title{font-size: 16px}.cy-banner-description,.cy-banner-description *,.cy-banner-actions .cy-btn,.cy-btn-do-not-sell{font-size: 12px}.cy-dialog-title{font-size: 16px}.cy-dialog-header{padding: 16px 24px}.cy-dialog-desc,.cy-dialog-desc *,.cy-accordion-header-des,.cy-accordion-header-des *,.cy-show-desc-btn,.cy-banner-description a{font-size: 12px}.cy-accordion-btn{font-size: 14px}.cy-optout-checkbox-label{font-size: 14px}.cy-optout-checkbox{width: 16px;min-width: 16px;height: 16px}.cy-optout-checkbox:checked::after{left: 5px;bottom: 4px;width: 3px;height: 9px}}@media (max-height: 480px){.cy-banner{max-height: 100vh;overflow-y: auto}.cy-banner-description{max-height: unset;overflow-y: unset}}@media (min-width: 576px) and (max-height: 660px){.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-height: 576px){.cy-dialog{height: 100vh;overflow: auto}.cy-dialog-body{overflow: unset}}.cy-banner-description img,.cy-dialog-desc img,.cy-accordion-header-des img{min-height: 25px;min-width: 25px}.cy-banner-wrap[data-cy-scheme="dark"] .cy-btn-outline,.cy-dialog-overlay[data-cy-scheme="dark"] .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap[data-cy-scheme="dark"] .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay[data-cy-scheme="dark"] .cy-always-active{color: #3fbf3f}\n',i="m5EDS1Mp6L1z",c="/cookieyes/styles.css",l="data-cy-full";function y({href:t=c,nonce:n}={}){const y=`${t}${t.includes("?")?"&":"?"}v=${i}`,d={[l]:""};return e(o,{children:[r("style",{nonce:n,dangerouslySetInnerHTML:{__html:a}}),r("link",{rel:"stylesheet",href:y,media:"print",...d})]})}export{a as C,c as D,n as S,i as a,t as b,y as c};
2
+ //# sourceMappingURL=styles-DjICYGmj.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles-DjICYGmj.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use strict";var e=require("./styles-CVmKDHmX.cjs");require("react/jsx-runtime"),exports.GET=async function(t){const n={"Content-Type":"text/css; charset=utf-8","Cache-Control":"public, max-age=31536000, immutable",ETag:`"${e.STYLES_CSS_VERSION}"`,Vary:"Accept-Encoding"},s=function(e){if(!e)return null;const t=e.split(",").map(e=>e.trim().split(";")[0]?.toLowerCase()).filter(e=>Boolean(e));return t.includes("gzip")?"gzip":t.includes("deflate")?"deflate":null}(t?.headers.get("accept-encoding"));if(null===s||"undefined"==typeof CompressionStream)return new Response(e.STYLES_CSS,{status:200,headers:n});const r=new Blob([e.STYLES_CSS]).stream().pipeThrough(new CompressionStream(s));return n["Content-Encoding"]=s,new Response(r,{status:200,headers:n})};
2
+ //# sourceMappingURL=styles-route.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles-route.cjs","sources":["../src/styles-route.ts"],"sourcesContent":["import { STYLES_CSS, STYLES_CSS_VERSION } from \"./styles.js\";\n\n/**\n * A Route Handler that serves the SDK's full stylesheet, so an app using\n * `<CookieYesStyles />` need not copy the file into `public/` or add a build\n * step. Re-export it from the path `<CookieYesStyles href>` points at:\n *\n * ```ts\n * // app/cookieyes/styles.css/route.ts\n * export { GET } from \"@cookieyes/nextjs/styles-route\";\n * ```\n *\n * The response is cached as immutable for a year. That is safe because\n * `<CookieYesStyles />` appends `?v=<content hash>` to the URL, so a new SDK\n * version — and therefore a new stylesheet — is a new URL, and the old entry\n * is simply never requested again. The `ETag` is the same hash, for clients\n * that revalidate anyway.\n *\n * **It compresses its own body.** A self-hosted `next start` does not gzip a\n * Route Handler's `Response` the way it does a static chunk, and measured on\n * the consentbench harness that turned a 3.7 KB stylesheet into an 18 KB\n * transfer — wiping out most of the point. So the handler negotiates\n * `Accept-Encoding` itself, using `CompressionStream`, which exists on Node 18+\n * and every Edge runtime. Behind a CDN this is redundant and harmless; the CDN\n * sees an already-compressed body with the right `Vary` and caches it as such.\n *\n * Because the body varies by request header, the route is dynamic rather than\n * prerendered. That is fine: it is a few microseconds of work, and every\n * client and every cache in between keeps the result for a year.\n *\n * The CSS itself is a build-time constant rather than a file read: it works\n * under every runtime and every package manager's `node_modules` layout, and it\n * is byte-identical to `@cookieyes/react/styles.css` by construction — a test\n * asserts it.\n */\nexport async function GET(request?: Request): Promise<Response> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"text/css; charset=utf-8\",\n \"Cache-Control\": \"public, max-age=31536000, immutable\",\n ETag: `\"${STYLES_CSS_VERSION}\"`,\n Vary: \"Accept-Encoding\",\n };\n\n const encoding = pickEncoding(request?.headers.get(\"accept-encoding\"));\n if (encoding === null || typeof CompressionStream === \"undefined\") {\n return new Response(STYLES_CSS, { status: 200, headers });\n }\n\n const body = new Blob([STYLES_CSS]).stream().pipeThrough(new CompressionStream(encoding));\n headers[\"Content-Encoding\"] = encoding;\n return new Response(body, { status: 200, headers });\n}\n\n/**\n * The strongest encoding the client accepts that `CompressionStream` supports.\n * Brotli is not in the `CompressionStream` spec, so `gzip` is the ceiling;\n * `deflate` for the rare client that offers only that. `null` means identity.\n */\nfunction pickEncoding(acceptEncoding: string | null | undefined): \"gzip\" | \"deflate\" | null {\n if (!acceptEncoding) return null;\n const offered = acceptEncoding\n .split(\",\")\n .map((e) => e.trim().split(\";\")[0]?.toLowerCase())\n .filter((e): e is string => Boolean(e));\n if (offered.includes(\"gzip\")) return \"gzip\";\n if (offered.includes(\"deflate\")) return \"deflate\";\n return null;\n}\n"],"names":["async","request","headers","ETag","STYLES_CSS_VERSION","Vary","encoding","acceptEncoding","offered","split","map","e","trim","toLowerCase","filter","Boolean","includes","pickEncoding","get","CompressionStream","Response","STYLES_CSS","status","body","Blob","stream","pipeThrough"],"mappings":"6FAmCAA,eAA0BC,GACxB,MAAMC,EAAkC,CACtC,eAAgB,0BAChB,gBAAiB,sCACjBC,KAAM,IAAIC,EAAAA,sBACVC,KAAM,mBAGFC,EAeR,SAAsBC,GACpB,IAAKA,EAAgB,OAAO,KAC5B,MAAMC,EAAUD,EACbE,MAAM,KACNC,IAAKC,GAAMA,EAAEC,OAAOH,MAAM,KAAK,IAAII,eACnCC,OAAQH,GAAmBI,QAAQJ,IACtC,OAAIH,EAAQQ,SAAS,QAAgB,OACjCR,EAAQQ,SAAS,WAAmB,UACjC,IACT,CAxBmBC,CAAahB,GAASC,QAAQgB,IAAI,oBACnD,GAAiB,OAAbZ,GAAkD,oBAAtBa,kBAC9B,OAAO,IAAIC,SAASC,EAAAA,WAAY,CAAEC,OAAQ,IAAKpB,YAGjD,MAAMqB,EAAO,IAAIC,KAAK,CAACH,eAAaI,SAASC,YAAY,IAAIP,kBAAkBb,IAE/E,OADAJ,EAAQ,oBAAsBI,EACvB,IAAIc,SAASG,EAAM,CAAED,OAAQ,IAAKpB,WAC3C"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * A Route Handler that serves the SDK's full stylesheet, so an app using
3
+ * `<CookieYesStyles />` need not copy the file into `public/` or add a build
4
+ * step. Re-export it from the path `<CookieYesStyles href>` points at:
5
+ *
6
+ * ```ts
7
+ * // app/cookieyes/styles.css/route.ts
8
+ * export { GET } from "@cookieyes/nextjs/styles-route";
9
+ * ```
10
+ *
11
+ * The response is cached as immutable for a year. That is safe because
12
+ * `<CookieYesStyles />` appends `?v=<content hash>` to the URL, so a new SDK
13
+ * version — and therefore a new stylesheet — is a new URL, and the old entry
14
+ * is simply never requested again. The `ETag` is the same hash, for clients
15
+ * that revalidate anyway.
16
+ *
17
+ * **It compresses its own body.** A self-hosted `next start` does not gzip a
18
+ * Route Handler's `Response` the way it does a static chunk, and measured on
19
+ * the consentbench harness that turned a 3.7 KB stylesheet into an 18 KB
20
+ * transfer — wiping out most of the point. So the handler negotiates
21
+ * `Accept-Encoding` itself, using `CompressionStream`, which exists on Node 18+
22
+ * and every Edge runtime. Behind a CDN this is redundant and harmless; the CDN
23
+ * sees an already-compressed body with the right `Vary` and caches it as such.
24
+ *
25
+ * Because the body varies by request header, the route is dynamic rather than
26
+ * prerendered. That is fine: it is a few microseconds of work, and every
27
+ * client and every cache in between keeps the result for a year.
28
+ *
29
+ * The CSS itself is a build-time constant rather than a file read: it works
30
+ * under every runtime and every package manager's `node_modules` layout, and it
31
+ * is byte-identical to `@cookieyes/react/styles.css` by construction — a test
32
+ * asserts it.
33
+ */
34
+ declare function GET(request?: Request): Promise<Response>;
35
+
36
+ export { GET };
@@ -0,0 +1,2 @@
1
+ import{S as e,a as t}from"./styles-DjICYGmj.js";import"react/jsx-runtime";async function n(n){const s={"Content-Type":"text/css; charset=utf-8","Cache-Control":"public, max-age=31536000, immutable",ETag:`"${t}"`,Vary:"Accept-Encoding"},o=function(e){if(!e)return null;const t=e.split(",").map(e=>e.trim().split(";")[0]?.toLowerCase()).filter(e=>Boolean(e));return t.includes("gzip")?"gzip":t.includes("deflate")?"deflate":null}(n?.headers.get("accept-encoding"));if(null===o||"undefined"==typeof CompressionStream)return new Response(e,{status:200,headers:s});const r=new Blob([e]).stream().pipeThrough(new CompressionStream(o));return s["Content-Encoding"]=o,new Response(r,{status:200,headers:s})}export{n as GET};
2
+ //# sourceMappingURL=styles-route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles-route.js","sources":["../src/styles-route.ts"],"sourcesContent":["import { STYLES_CSS, STYLES_CSS_VERSION } from \"./styles.js\";\n\n/**\n * A Route Handler that serves the SDK's full stylesheet, so an app using\n * `<CookieYesStyles />` need not copy the file into `public/` or add a build\n * step. Re-export it from the path `<CookieYesStyles href>` points at:\n *\n * ```ts\n * // app/cookieyes/styles.css/route.ts\n * export { GET } from \"@cookieyes/nextjs/styles-route\";\n * ```\n *\n * The response is cached as immutable for a year. That is safe because\n * `<CookieYesStyles />` appends `?v=<content hash>` to the URL, so a new SDK\n * version — and therefore a new stylesheet — is a new URL, and the old entry\n * is simply never requested again. The `ETag` is the same hash, for clients\n * that revalidate anyway.\n *\n * **It compresses its own body.** A self-hosted `next start` does not gzip a\n * Route Handler's `Response` the way it does a static chunk, and measured on\n * the consentbench harness that turned a 3.7 KB stylesheet into an 18 KB\n * transfer — wiping out most of the point. So the handler negotiates\n * `Accept-Encoding` itself, using `CompressionStream`, which exists on Node 18+\n * and every Edge runtime. Behind a CDN this is redundant and harmless; the CDN\n * sees an already-compressed body with the right `Vary` and caches it as such.\n *\n * Because the body varies by request header, the route is dynamic rather than\n * prerendered. That is fine: it is a few microseconds of work, and every\n * client and every cache in between keeps the result for a year.\n *\n * The CSS itself is a build-time constant rather than a file read: it works\n * under every runtime and every package manager's `node_modules` layout, and it\n * is byte-identical to `@cookieyes/react/styles.css` by construction — a test\n * asserts it.\n */\nexport async function GET(request?: Request): Promise<Response> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"text/css; charset=utf-8\",\n \"Cache-Control\": \"public, max-age=31536000, immutable\",\n ETag: `\"${STYLES_CSS_VERSION}\"`,\n Vary: \"Accept-Encoding\",\n };\n\n const encoding = pickEncoding(request?.headers.get(\"accept-encoding\"));\n if (encoding === null || typeof CompressionStream === \"undefined\") {\n return new Response(STYLES_CSS, { status: 200, headers });\n }\n\n const body = new Blob([STYLES_CSS]).stream().pipeThrough(new CompressionStream(encoding));\n headers[\"Content-Encoding\"] = encoding;\n return new Response(body, { status: 200, headers });\n}\n\n/**\n * The strongest encoding the client accepts that `CompressionStream` supports.\n * Brotli is not in the `CompressionStream` spec, so `gzip` is the ceiling;\n * `deflate` for the rare client that offers only that. `null` means identity.\n */\nfunction pickEncoding(acceptEncoding: string | null | undefined): \"gzip\" | \"deflate\" | null {\n if (!acceptEncoding) return null;\n const offered = acceptEncoding\n .split(\",\")\n .map((e) => e.trim().split(\";\")[0]?.toLowerCase())\n .filter((e): e is string => Boolean(e));\n if (offered.includes(\"gzip\")) return \"gzip\";\n if (offered.includes(\"deflate\")) return \"deflate\";\n return null;\n}\n"],"names":["async","GET","request","headers","ETag","STYLES_CSS_VERSION","Vary","encoding","acceptEncoding","offered","split","map","e","trim","toLowerCase","filter","Boolean","includes","pickEncoding","get","CompressionStream","Response","STYLES_CSS","status","body","Blob","stream","pipeThrough"],"mappings":"0EAmCAA,eAAsBC,EAAIC,GACxB,MAAMC,EAAkC,CACtC,eAAgB,0BAChB,gBAAiB,sCACjBC,KAAM,IAAIC,KACVC,KAAM,mBAGFC,EAeR,SAAsBC,GACpB,IAAKA,EAAgB,OAAO,KAC5B,MAAMC,EAAUD,EACbE,MAAM,KACNC,IAAKC,GAAMA,EAAEC,OAAOH,MAAM,KAAK,IAAII,eACnCC,OAAQH,GAAmBI,QAAQJ,IACtC,OAAIH,EAAQQ,SAAS,QAAgB,OACjCR,EAAQQ,SAAS,WAAmB,UACjC,IACT,CAxBmBC,CAAahB,GAASC,QAAQgB,IAAI,oBACnD,GAAiB,OAAbZ,GAAkD,oBAAtBa,kBAC9B,OAAO,IAAIC,SAASC,EAAY,CAAEC,OAAQ,IAAKpB,YAGjD,MAAMqB,EAAO,IAAIC,KAAK,CAACH,IAAaI,SAASC,YAAY,IAAIP,kBAAkBb,IAE/E,OADAJ,EAAQ,oBAAsBI,EACvB,IAAIc,SAASG,EAAM,CAAED,OAAQ,IAAKpB,WAC3C"}
@@ -0,0 +1 @@
1
+ :root{--cy-primary: #1863dc;--cy-primary-hover: color-mix(in srgb,var(--cy-primary) 85%,black);--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-radius: 6px;--cy-font: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;--cy-focus: var(--cy-primary);--cy-on-primary: #ffffff;--cy-on-widget-bg: #ffffff}@media (prefers-color-scheme: dark){:root{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-outline,.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap:not([data-cy-scheme="light"]) .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay:not([data-cy-scheme="light"]) .cy-always-active{color: #3fbf3f}}[data-cy-scheme="light"]{--cy-bg: #ffffff;--cy-text: #212121;--cy-muted: #6b7280;--cy-border: #f4f4f4;--cy-widget-bg: #0056a7;--cy-on-widget-bg: #ffffff}[data-cy-scheme="dark"]{--cy-bg: #161b27;--cy-text: #f3f4f6;--cy-muted: #9ca3af;--cy-border: #2d3748;--cy-widget-bg: #1f6fd1;--cy-on-widget-bg: #ffffff}.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder{font-family: var(--cy-font);font-size: 14px;font-weight: 400;font-style: normal;line-height: 1.5;letter-spacing: normal;word-spacing: normal;text-align: left;text-transform: none;text-decoration: none;text-indent: 0;text-shadow: none;color: var(--cy-text);direction: ltr;white-space: normal;box-sizing: border-box;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::before,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-widget,.cy-reload-notice,.cy-frame-placeholder) *::after{box-sizing: border-box}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) button,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) input,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) label,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) select,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) textarea{font: inherit;color: inherit;letter-spacing: inherit;text-transform: inherit;text-align: inherit;margin: 0}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) a{color: inherit;text-decoration: none;background: transparent}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) p,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h1,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h2,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h3,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) h4,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ul,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) ol,:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) li{margin: 0;padding: 0;list-style: none}:where(.cy-banner-wrap,.cy-dialog-overlay,.cy-frame-placeholder) svg{display: inline-block;vertical-align: middle}.cy-banner-wrap{display: contents}.cy-banner{position: fixed;left: 40px;bottom: 40px;right: auto;z-index: 9999999;pointer-events: all;background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 -1px 10px 0 rgba(172,171,171,0.3);border: 1px solid var(--cy-border);max-width: 440px;width: min(440px,calc(100vw - 80px));padding: 24px 24px 12px;box-sizing: border-box;animation: cy-fade-in 0.2s ease-out both}.cy-banner[data-leaving]{animation: cy-fade-out 0.2s ease forwards}.cy-banner-wrap[data-cy-entered] .cy-banner:not([data-leaving]){animation: none}@keyframes cy-fade-in{from{opacity: 0}to{opacity: 1}}@keyframes cy-fade-out{from{opacity: 1}to{opacity: 0}}.cy-banner-text{margin-bottom: 0}.cy-banner-title{font-size: 18px;font-weight: 700;line-height: 24px;margin: 0 0 12px;color: var(--cy-text);word-break: break-word}.cy-banner-description{font-size: 14px;line-height: 24px;color: var(--cy-text);margin: 0;word-break: break-word}.cy-banner-description a{color: var(--cy-primary);text-decoration: underline;text-underline-offset: 2px}.cy-banner-actions{display: flex;align-items: center;justify-content: flex-start;gap: 8px;flex-wrap: wrap;margin-top: 16px}.cy-btn{flex: auto;max-width: 100%;cursor: pointer;font-family: var(--cy-font);font-size: 14px;font-weight: 500;border-radius: 2px;padding: 8px;line-height: 24px;transition: opacity 0.15s;text-decoration: none;text-align: center;overflow-wrap: break-word;border: none}.cy-btn:hover{opacity: 0.8}.cy-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-btn-primary{background: var(--cy-primary);color: var(--cy-on-primary);border: 2px solid var(--cy-primary)}.cy-btn-primary:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-btn-outline{background: transparent;color: var(--cy-primary);border: 2px solid var(--cy-primary)}.cy-btn-link{background: none;color: var(--cy-primary);padding: 8px 6px;font-size: 14px;font-weight: 500;text-decoration: underline;text-underline-offset: 2px;border: none}.cy-btn-link:hover{opacity: 0.75}.cy-btn-do-not-sell{flex: 1 0 100%;width: 100%;font-size: 14px;line-height: 24px;padding: 6px 0;font-weight: 500;border: none;cursor: pointer;font-family: var(--cy-font);color: var(--cy-primary);background: transparent;text-decoration: underline;text-underline-offset: 2px;text-align: left;word-break: break-word}.cy-btn-do-not-sell:hover{opacity: 0.75}.cy-banner-close{position: absolute;right: 9px;top: 5px;background: none;border: none;cursor: pointer;padding: 0;margin: 0;height: 24px;width: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;color: var(--cy-text)}.cy-banner-close:hover{opacity: 0.6}.cy-banner-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-show-desc-btn{font-size: 14px;font-family: var(--cy-font);color: var(--cy-primary);text-decoration: none;line-height: 24px;padding: 0;margin: 0;white-space: nowrap;cursor: pointer;background: transparent;border: none}.cy-show-desc-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-banner-footer{padding: 20px 0 0;display: flex;justify-content: center;align-items: center}.cy-banner-footer--ccpa{border-top: 1px solid lightgray;margin: 12px -24px 0;padding: 8px 0 0}.cy-branding{display: inline-flex;align-items: center;gap: 5px;font-size: 12px;font-weight: 400;line-height: 20px;color: var(--cy-text);text-decoration: none;opacity: 0.7}.cy-branding:hover{opacity: 1}.cy-branding svg{line-height: 0;color: inherit}.cy-dialog-overlay{position: fixed;inset: 0;background: rgba(0,0,0,0.4);z-index: 99999999;display: flex;align-items: center;justify-content: center;padding: 20px;box-sizing: border-box;animation: cy-overlay-in 0.3s ease both}@keyframes cy-overlay-in{from{opacity: 0}to{opacity: 1}}.cy-dialog{background: var(--cy-bg);color: var(--cy-text);border-radius: var(--cy-radius);box-shadow: 0 32px 68px rgba(0,0,0,0.3);width: 100%;max-width: 845px;max-height: 79vh;overflow: hidden;display: flex;flex-direction: column;font-family: var(--cy-font);animation: cy-dialog-slide-up 1s ease both}@keyframes cy-dialog-slide-up{from{transform: translateY(100%)}to{transform: translateY(0)}}.cy-dialog-header{display: flex;align-items: center;justify-content: space-between;padding: 24px 24px 22px;border-bottom: 1px solid var(--cy-border);flex-shrink: 0}.cy-dialog-title{font-size: 18px;font-weight: 700;line-height: 24px;color: var(--cy-text)}.cy-dialog-close{background: none;border: none;cursor: pointer;color: var(--cy-text);padding: 0;margin: 0;width: 24px;height: 24px;display: flex;align-items: center;justify-content: center;line-height: 0;flex-shrink: 0}.cy-dialog-close:hover{opacity: 0.6}.cy-dialog-close:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-dialog-close svg{width: 10px;height: 10px}.cy-dialog-body{padding: 0 24px;flex: 1;overflow-y: auto;overscroll-behavior: contain}.cy-dialog-content-intro{padding: 12px 0}.cy-dialog-desc{font-size: 14px;color: var(--cy-text);line-height: 24px;margin: 0}.cy-separator{border: none;border-bottom: 1px solid var(--cy-border);margin: 0}.cy-accordion-wrapper{margin-bottom: 10px}.cy-accordion{border-bottom: 1px solid var(--cy-border)}.cy-accordion:last-child{border-bottom: none}.cy-accordion-item{display: flex;margin-top: 10px}.cy-accordion-header-wrapper{flex: 1;min-width: 0}.cy-accordion-header{display: flex;justify-content: space-between;align-items: center;gap: 12px}.cy-accordion-btn{background: none;border: none;cursor: pointer;font-family: var(--cy-font);font-size: 16px;font-weight: 700;color: var(--cy-text);padding: 0;margin: 0;text-align: left;line-height: 24px}.cy-accordion-btn:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-always-active{color: #008000;font-weight: 600;font-size: 14px;line-height: 24px;flex-shrink: 0;white-space: nowrap}.cy-accordion-header-des{margin: 10px 0 16px;font-size: 14px;color: var(--cy-text);line-height: 24px}.cy-accordion-header-des p{font-size: 14px;color: inherit;line-height: 24px;margin: 0;word-break: break-word}.cy-accordion-body{padding: 0 22px;margin-bottom: 16px}.cy-audit-table{background: #f4f4f4;border-radius: 6px}.cy-empty-cookies-text{font-size: 12px;line-height: 24px;color: var(--cy-text);margin: 0;padding: 10px;word-break: break-word}.cy-cookie-des-table{font-size: 12px;line-height: 24px;font-weight: 400;padding: 15px 10px;border-bottom: 1px solid #ebebeb;margin: 0;list-style: none}.cy-cookie-des-table:last-child{border-bottom: none}.cy-cookie-des-table li{list-style-type: none;display: flex;padding: 3px 0}.cy-cookie-des-table li:first-child{padding-top: 0}.cy-cookie-des-table li div:first-child{width: 100px;flex-shrink: 0;font-weight: 600;word-break: break-word;overflow-wrap: break-word}.cy-cookie-des-table li div:last-child{flex: 1;word-break: break-word;overflow-wrap: break-word;margin-left: 8px}.cy-btn-cancel{background: transparent;color: var(--cy-muted);border: 1px solid var(--cy-muted)}.cy-btn-cancel:hover{opacity: 0.8}.cy-btn-confirm{background: var(--cy-primary);color: var(--cy-on-primary);border: 1px solid var(--cy-primary)}.cy-btn-confirm:hover{opacity: 1;background: var(--cy-primary-hover);border-color: var(--cy-primary-hover)}.cy-optout-dialog{max-height: fit-content}.cy-optout-footer{flex-shrink: 0;position: relative}.cy-optout-action-area{padding: 0 24px 22px;box-sizing: border-box}.cy-optout-btn-wrapper{display: flex;flex-wrap: wrap;gap: 8px;align-items: center;justify-content: center;padding-top: 22px}.cy-optout-btn-wrapper .cy-btn{flex: 1 1 auto}.cy-optout-powered-by{display: flex;justify-content: center;align-items: center;margin-top: 8px;padding-bottom: 12px}.cy-optout-checkbox-wrapper{display: flex;align-items: center;padding: 12px 0}.cy-optout-checkbox{appearance: none;-webkit-appearance: none;width: 20px;height: 18.5px;min-width: 20px;border: 1px solid #000;border-radius: 2px;background: #fff;cursor: pointer;flex-shrink: 0;position: relative;margin: 0;padding: 0}.cy-optout-checkbox:checked{background: var(--cy-primary);border-color: var(--cy-primary)}.cy-optout-checkbox:checked::after{content: "";position: absolute;left: 6px;bottom: 4px;width: 7px;height: 13px;border: solid #fff;border-width: 0 3px 3px 0;border-radius: 2px;transform: rotate(45deg)}.cy-optout-checkbox:focus-visible{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-optout-checkbox-label{font-size: 16px;font-weight: 700;line-height: 24px;color: var(--cy-text);margin-left: 12px;cursor: pointer;font-family: var(--cy-font)}.cy-optout-checkbox:disabled{cursor: not-allowed}.cy-optout-checkbox:disabled + .cy-optout-checkbox-label{cursor: not-allowed}.cy-optout-success{background: #e5f4ef;border-radius: 8px;padding: 8px 12px;box-sizing: border-box;outline: none;margin: 0 auto;width: 100%}.cy-optout-success-inner{display: flex;flex-direction: column;gap: 4px}.cy-optout-success-row{display: flex;align-items: flex-start}.cy-optout-success-icon{width: 20px;flex-shrink: 0;color: #00754e}.cy-optout-success-text{margin-inline-start: 8px;margin-top: 1px;font-size: 13px;font-weight: 400;color: #14142a;line-height: 20px}.cy-optout-success-subtext-wrapper{}.cy-optout-success-subtext{margin: 0;font-size: 12px;font-weight: 400;color: #4e4b66;line-height: 20px}.cy-toggle{position: relative;flex-shrink: 0;width: 44px;height: 24px;display: flex;cursor: pointer}.cy-toggle input{position: absolute;width: 44px;height: 24px;margin: 0;opacity: 0;top: 0;left: 0;z-index: 1;cursor: pointer}.cy-toggle-track{position: absolute;inset: 0;background: #8a8a8a;border-radius: 50px;transition: background 0.18s ease}.cy-toggle input:checked ~ .cy-toggle-track{background: var(--cy-primary)}.cy-toggle-thumb{position: absolute;top: 2px;left: 2px;width: 20px;height: 20px;background: #fff;border-radius: 50%;box-shadow: 0 1px 3px rgba(0,0,0,0.25);transition: transform 0.4s ease;pointer-events: none}.cy-toggle input:checked ~ .cy-toggle-track .cy-toggle-thumb{transform: translateX(20px)}.cy-toggle input:focus-visible ~ .cy-toggle-track{outline: 2px solid var(--cy-focus);outline-offset: 2px}.cy-dialog-footer{padding: 22px 24px 12px;flex-shrink: 0;border-top: 1px solid var(--cy-border);display: flex;flex-direction: column;align-items: center;gap: 12px;position: relative}.cy-dialog-footer-shadow{display: block;width: 100%;height: 40px;background: linear-gradient(180deg,rgba(255,255,255,0) 0%,var(--cy-bg) 100%);position: absolute;bottom: calc(100% - 1px);left: 0;pointer-events: none}.cy-dialog-footer-actions{display: flex;flex-wrap: wrap;gap: 8px;width: 100%;justify-content: center}.cy-dialog-footer-actions .cy-btn{flex: auto}.cy-widget{position: fixed;bottom: 15px;left: 15px;z-index: 99999999;width: 45px;height: 45px;border-radius: 50%;background: var(--cy-widget-bg);color: var(--cy-on-widget-bg);border: none;cursor: pointer;display: flex;align-items: center;justify-content: center;animation: cy-widget-pop 0.4s cubic-bezier(0.34,1.56,0.64,1) both}.cy-widget:focus-visible{outline: 3px solid var(--cy-focus);outline-offset: 3px}.cy-widget::before{content: attr(data-tooltip);position: absolute;background: #4e4b66;color: #fff;left: calc(100% + 7px);font-size: 12px;line-height: 16px;width: max-content;padding: 4px 8px;border-radius: 4px;font-family: var(--cy-font);opacity: 0;pointer-events: none;white-space: nowrap}.cy-widget::after{content: "";position: absolute;border: 5px solid transparent;border-right-color: #4e4b66;left: calc(100% + 2px);opacity: 0;pointer-events: none}.cy-widget:hover::before,.cy-widget:hover::after{opacity: 1}@keyframes cy-widget-pop{from{opacity: 0;transform: scale(0.4)}to{opacity: 1;transform: scale(1)}}.cy-reload-notice{position: fixed;bottom: 20px;left: 50%;transform: translateX(-50%);z-index: 99999999;max-width: min(520px,calc(100vw - 40px));display: flex;flex-wrap: wrap;align-items: center;gap: 12px;padding: 14px 18px;background: var(--cy-bg);color: var(--cy-text);border: 1px solid var(--cy-border);border-radius: var(--cy-radius);box-shadow: 0 4px 20px rgba(0,0,0,0.18);animation: cy-reload-notice-in 0.3s ease both}@keyframes cy-reload-notice-in{from{opacity: 0;transform: translate(-50%,12px)}to{opacity: 1;transform: translate(-50%,0)}}.cy-reload-notice-text{flex: 1 1 220px;font-size: 14px;line-height: 20px}.cy-reload-notice-actions{display: flex;gap: 8px;flex-shrink: 0}.cy-reload-notice .cy-btn{flex: 0 0 auto;padding: 6px 12px}@media (prefers-reduced-motion: reduce){.cy-banner,.cy-banner[data-leaving],.cy-dialog-overlay,.cy-dialog,.cy-widget,.cy-reload-notice{animation: none}}.cy-frame-placeholder{background: var(--cy-bg);border: 1.5px dashed var(--cy-border);border-radius: calc(var(--cy-radius) * 0.6);display: flex;flex-direction: column;align-items: center;justify-content: center;gap: 12px;padding: 32px 24px;text-align: center;font-family: var(--cy-font);color: var(--cy-muted);font-size: 14px;min-height: 120px}@media (max-width: 440px){.cy-banner{left: 0;right: 0;bottom: 0;width: 100%;max-width: 100%;border-radius: 0}.cy-banner-actions{flex-direction: column;gap: 10px}.cy-banner-actions .cy-btn{width: 100%}.cy-banner-actions .cy-btn:nth-child(1){order: 2}.cy-banner-actions .cy-btn:nth-child(2){order: 3}.cy-banner-actions .cy-btn:nth-child(3){order: 1}.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-width: 845px){.cy-dialog-overlay{padding: 8px}}@media (max-width: 576px){.cy-dialog-overlay{padding: 0;align-items: stretch}.cy-dialog{max-width: 100%;border-radius: 0;max-height: 100vh;height: 100vh}.cy-dialog-footer-actions{flex-direction: column;gap: 10px}.cy-dialog-footer-actions .cy-btn{width: 100%}.cy-dialog-footer-actions .cy-btn:nth-child(1){order: 3}.cy-dialog-footer-actions .cy-btn:nth-child(2){order: 2}.cy-dialog-footer-actions .cy-btn:nth-child(3){order: 1}}@media (max-width: 425px){.cy-accordion-body{padding: 0 15px}.cy-toggle,.cy-toggle input{width: 38px;height: 21px}.cy-toggle-thumb{width: 17px;height: 17px}.cy-toggle input:checked ~ .cy-toggle-track .cy-toggle-thumb{transform: translateX(17px)}}@media (max-width: 352px){.cy-banner-title{font-size: 16px}.cy-banner-description,.cy-banner-description *,.cy-banner-actions .cy-btn,.cy-btn-do-not-sell{font-size: 12px}.cy-dialog-title{font-size: 16px}.cy-dialog-header{padding: 16px 24px}.cy-dialog-desc,.cy-dialog-desc *,.cy-accordion-header-des,.cy-accordion-header-des *,.cy-show-desc-btn,.cy-banner-description a{font-size: 12px}.cy-accordion-btn{font-size: 14px}.cy-optout-checkbox-label{font-size: 14px}.cy-optout-checkbox{width: 16px;min-width: 16px;height: 16px}.cy-optout-checkbox:checked::after{left: 5px;bottom: 4px;width: 3px;height: 9px}}@media (max-height: 480px){.cy-banner{max-height: 100vh;overflow-y: auto}.cy-banner-description{max-height: unset;overflow-y: unset}}@media (min-width: 576px) and (max-height: 660px){.cy-banner-description{max-height: 40vh;overflow-y: auto}}@media (max-height: 576px){.cy-dialog{height: 100vh;overflow: auto}.cy-dialog-body{overflow: unset}}.cy-banner-description img,.cy-dialog-desc img,.cy-accordion-header-des img{min-height: 25px;min-width: 25px}.cy-banner-wrap[data-cy-scheme="dark"] .cy-btn-outline,.cy-dialog-overlay[data-cy-scheme="dark"] .cy-btn-outline{color: var(--cy-text);border-color: var(--cy-text)}.cy-banner-wrap[data-cy-scheme="dark"] .cy-btn-do-not-sell{color: color-mix(in srgb,var(--cy-primary) 55%,#ffffff)}.cy-dialog-overlay[data-cy-scheme="dark"] .cy-always-active{color: #3fbf3f}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cookieyes/nextjs",
3
- "version": "0.5.4",
3
+ "version": "0.6.1",
4
4
  "description": "Next.js App Router adapter for the CookieYes consent SDK",
5
5
  "keywords": [
6
6
  "cookie consent",
@@ -26,7 +26,9 @@
26
26
  },
27
27
  "license": "MIT",
28
28
  "author": "CookieYes (https://www.cookieyes.com)",
29
- "sideEffects": false,
29
+ "sideEffects": [
30
+ "**/*.css"
31
+ ],
30
32
  "type": "module",
31
33
  "exports": {
32
34
  ".": {
@@ -38,7 +40,14 @@
38
40
  "types": "./dist/server.d.ts",
39
41
  "import": "./dist/server.js",
40
42
  "require": "./dist/server.cjs"
41
- }
43
+ },
44
+ "./styles-route": {
45
+ "types": "./dist/styles-route.d.ts",
46
+ "import": "./dist/styles-route.js",
47
+ "require": "./dist/styles-route.cjs"
48
+ },
49
+ "./styles.css": "./dist/styles.css",
50
+ "./critical.css": "./dist/critical.css"
42
51
  },
43
52
  "main": "./dist/index.cjs",
44
53
  "module": "./dist/index.js",
@@ -61,9 +70,9 @@
61
70
  "react-dom": ">=18.0.0"
62
71
  },
63
72
  "dependencies": {
64
- "@cookieyes/core": "0.6.0",
65
- "@cookieyes/scripts": "0.2.1",
66
- "@cookieyes/react": "0.7.0"
73
+ "@cookieyes/core": "0.7.0",
74
+ "@cookieyes/react": "0.9.0",
75
+ "@cookieyes/scripts": "0.2.2"
67
76
  },
68
77
  "devDependencies": {
69
78
  "@types/node": "^26.1.1",
@@ -77,7 +86,7 @@
77
86
  "vitest": "^4.1.10"
78
87
  },
79
88
  "scripts": {
80
- "build": "rm -rf dist && rollup -c",
89
+ "build": "rm -rf dist && rollup -c && node scripts/emit-css-proxies.mjs",
81
90
  "dev": "rollup -c -w",
82
91
  "typecheck": "tsc --noEmit",
83
92
  "test": "vitest run --coverage",