From 3303c500465bcd1e00de50cfe50ace0911979453 Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Mon, 18 May 2026 17:29:15 +0800 Subject: [PATCH 01/10] [CLOV-1412][bpk-stylesheets] Ship token CSS variables in base.css Import the three token-sync CSS files (primitives, light theme, dark theme) into the base stylesheet so all consumers of @skyscanner/backpack-web/bpk-stylesheets get the design-token CSS custom properties at runtime. - index.scss: @use the three generated files; Sass compressed mode drops their license headers, so base.css keeps a single header - README: document dark mode (set data-theme="dark" on ) and flag the variables as internal-use-only; fix two stale base.js references in the Contributing section - base.css: regenerated; dark theme cascades via :root[data-theme=dark] Note: this is the first @use 'foo.css' (Sass importing plain CSS) in the repo. Existing @use callsites all reference SCSS. Supported since Dart Sass 1.23; repo is on 1.90. Co-Authored-By: Claude Opus 4.7 --- packages/bpk-stylesheets/README.md | 23 +++++++++++++++++++++-- packages/bpk-stylesheets/base.css | 2 +- packages/bpk-stylesheets/index.scss | 3 +++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/bpk-stylesheets/README.md b/packages/bpk-stylesheets/README.md index 79226d36fc..4b78492794 100644 --- a/packages/bpk-stylesheets/README.md +++ b/packages/bpk-stylesheets/README.md @@ -52,6 +52,25 @@ For Editorial text, the Larken font will also need to be imported: import '@skyscanner/backpack-web/bpk-stylesheets/larken.css'; ``` +## Design tokens (CSS variables) + +`base.css` ships the design token CSS variables generated by [`token-sync`](../../token-sync/). They are emitted as: + +- `:root { … }` — Light theme semantic tokens + Spacing/Radius primitives (the default) +- `:root[data-theme="dark"] { … }` — Dark theme overrides + +To enable dark mode, set `data-theme="dark"` on ``: + +```html + +``` + +### Internal use only — not a stable public API + +The CSS variables shipped here (`--bpk-private-…`, plus the current spacing / radius / canvas / etc. variables) are for **Backpack-internal use**. They are not part of the stable public API: names, shapes, and values can change without a major version bump. **Do not reference or override them directly in product code.** + +The consumer-facing token API is intentionally decoupled from these CSS variables — it runs through SCSS functions and a documented token subset. This separation keeps the loading mechanism (the CSS variables shipped in `base.css`) independent from the public contract: we can evolve the runtime variables freely (for theming, refactors, renames) without breaking what product code depends on, while a single import keeps the consumer experience simple. + ### Font-related Repositories Overview Font updates involve coordination between three repositories: @@ -133,6 +152,6 @@ Defined in `font.scss`, `larken.scss` ## Contributing -Don't forget to rebuild and commit `base.js` after you make changes to this package. +Don't forget to rebuild and commit `base.css` after you make changes to this package. -To build the `base.js` file run `npm run build:stylesheets` in the root folder. +To build the `base.css` file run `npm run build:stylesheets` in the root folder. diff --git a/packages/bpk-stylesheets/base.css b/packages/bpk-stylesheets/base.css index 44947343cf..8eda29f88d 100644 --- a/packages/bpk-stylesheets/base.css +++ b/packages/bpk-stylesheets/base.css @@ -16,4 +16,4 @@ * See the License for the specific language governing permissions and * limitations under the License. * - *//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:rgba(0,0,0,0);-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}html{font-size:100%;box-sizing:border-box}*{box-sizing:inherit}*::before,*::after{box-sizing:inherit}body{color:#161616;font-family:var(--bpk-base-font-stack, "Skyscanner Relative", -apple-system, BlinkMacSystemFont, "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif);font-size:1rem;line-height:1.3rem}body.scaffold-font-size{font-size:13px}body.enable-font-smoothing{-webkit-font-smoothing:antialiased}:focus-visible,button:focus-visible,[type=button]:focus-visible,[type=reset]:focus-visible,[type=submit]:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.hidden,.hide{display:none !important}.visuallyhidden,.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;white-space:nowrap;overflow:hidden;clip:rect(0 0 0 0)}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus,.visually-hidden.focusable:active,.visually-hidden.focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.invisible{visibility:hidden}.clearfix::before,.clearfix::after{content:"";display:table}.clearfix::after{clear:both} + *//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:rgba(0,0,0,0);-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}:root{--bpk-radius-none: 0;--bpk-radius-full: 6.25rem;--bpk-radius-lg: 1.5rem;--bpk-radius-md: 0.75rem;--bpk-radius-nav-tabs: 1.125rem;--bpk-radius-sm: 0.5rem;--bpk-radius-xs: 0.25rem;--bpk-spacing-base: 1rem;--bpk-spacing-lg: 1.5rem;--bpk-spacing-md: 0.5rem;--bpk-spacing-none: 0;--bpk-spacing-sm: 0.25rem;--bpk-spacing-xl: 2rem;--bpk-spacing-xs: 0.125rem;--bpk-spacing-xxl: 2.5rem;--bpk-spacing-xxs: 0.0625rem;--bpk-spacing-xxxl: 4rem;--bpk-spacing-xxxxl: 6rem}:root{--bpk-canvas-contrast: #eff3f8;--bpk-canvas-default: #ffffff;--bpk-private-badge-colour-bg-default: #eff3f8;--bpk-private-badge-colour-bg-inverse: #ffffff;--bpk-private-badge-colour-bg-outline: rgba(255, 255, 255, 0);--bpk-private-badge-colour-bg-subtle: #eff3f8;--bpk-private-badge-colour-stroke-outline: #ffffff;--bpk-private-badge-dimension-padding-horizontal-default: 0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle: 0.5rem;--bpk-private-badge-typography-tmp-badge-label: 0.875rem;--bpk-private-badge-typography-tmp-badge-line-height: 0;--bpk-private-button-colour-bg-destructive: #e0e4e9;--bpk-private-button-colour-bg-destructive-pressed: #e70866;--bpk-private-button-colour-bg-disabled: #e0e4e9;--bpk-private-button-colour-bg-feature-pressed: #024daf;--bpk-private-button-colour-bg-featured: #0062e3;--bpk-private-button-colour-bg-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-footer-pressed: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-primary: #05203c;--bpk-private-button-colour-bg-primary-on-dark: #ffffff;--bpk-private-button-colour-bg-primary-on-dark-pressed: #c1c7cf;--bpk-private-button-colour-bg-primary-on-light: #ffffff;--bpk-private-button-colour-bg-primary-on-light-pressed: #154679;--bpk-private-button-colour-bg-secondary: #e0e4e9;--bpk-private-button-colour-bg-secondary-pressed: #c1c7cf;--bpk-private-button-colour-bg-secondary-on-contrast: #e0e4e9;--bpk-private-button-colour-bg-secondary-on-contrast-pressed: #c1c7cf;--bpk-private-button-colour-bg-secondary-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-button-colour-bg-secondary-on-dark-disabled: #0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed: #04182d;--bpk-private-button-colour-text-disruptive: #e70866;--bpk-private-button-colour-text-feature: #ffffff;--bpk-private-button-colour-text-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-text-link-on-dark: #ffffff;--bpk-private-button-colour-text-secondary: #161616;--bpk-private-button-dimension-radius: 0.5rem;--bpk-private-button-dimension-min-height-default: 2.25rem;--bpk-private-button-dimension-min-height-large: 3rem;--bpk-private-button-dimension-min-weight-large: 3rem;--bpk-private-button-dimension-padding-horizontal-default: 1rem;--bpk-private-button-dimension-padding-horizontal-large: 1rem;--bpk-private-button-typography-tmp-default-label: 1rem;--bpk-private-card-button-contained-fill: rgba(255, 255, 255, 0.8);--bpk-private-carousel-trigger-bg-default: rgba(255, 255, 255, 0.5);--bpk-private-carousel-trigger-bg-default-hover: rgba(255, 255, 255, 0.8);--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image: #eff3f8;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image: #ffffff;--bpk-private-chip-group-filter-colour-bg-icon-on-default: #05203c;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark: #ffffff;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image: #05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default: #05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark: #ffffff;--bpk-private-chip-group-filter-colour-stroke-icon-off-default: #c1c7cf;--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark: rgba(255, 255, 255, 0.5);--bpk-private-chip-group-filter-dimensions-min-height: 2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover: #05203c;--bpk-private-chip-colour-bg-default-on: #05203c;--bpk-private-chip-colour-bg-disabled: #e0e4e9;--bpk-private-chip-colour-bg-on-contrast-hover: #ffffff;--bpk-private-chip-colour-bg-on-contrast-on: #05203c;--bpk-private-chip-colour-bg-on-dark-dismissible-hover: #ffffff;--bpk-private-chip-colour-bg-on-dark-hover: #ffffff;--bpk-private-chip-colour-bg-on-dark-off: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-on: #ffffff;--bpk-private-chip-colour-bg-on-image-dismissible-hover: #05203c;--bpk-private-chip-colour-bg-on-image-on: #eff3f8;--bpk-private-chip-colour-border-default-dismissible-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-border-default-hover: #05203c;--bpk-private-chip-colour-border-default-off: #c1c7cf;--bpk-private-chip-colour-border-on-contrast-off: #ffffff;--bpk-private-chip-colour-border-on-contrast-on: #05203c;--bpk-private-chip-colour-border-on-dark-disimissible-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-off: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new: rgba(255, 255, 255, 0);--bpk-private-chip-colour-text-default-dismissible-hover: #ffffff;--bpk-private-chip-colour-text-dismissible-on-icon: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-text-on: #ffffff;--bpk-private-chip-colour-text-on-image: #ffffff;--bpk-private-chip-colour-text-on-image-dismissible-icon: #626971;--bpk-private-chip-colour-text-on-dark: #161616;--bpk-private-chip-colour-text-on-dark-dismisisble-hover: #161616;--bpk-private-chip-colour-text-on-dark-dismisisble-icon: #626971;--bpk-private-chip-dimension-min-height-width: 2rem;--bpk-private-chip-dimension-radius: 0.5rem;--bpk-private-date-selector-cheapest-month-highlight: #154679;--bpk-private-date-selector-flexible-date-card: #eff3f8;--bpk-private-dimension-padding-veritcal: 0;--bpk-private-info-banner-default: #eff3f8;--bpk-private-info-banner-on-contrast: #ffffff;--bpk-private-map-cluster-pin: #05203c;--bpk-private-map-cluster-pin-previous-selection: #94c3ff;--bpk-private-map-marker-viewed: rgba(255, 255, 255, 0.8);--bpk-private-map-poi-pin: #8e47ba;--bpk-private-map-previous-selection: #cfe4ff;--bpk-private-navigation-tabs-hover: #154679;--bpk-private-navigation-tabs-outline: rgba(255, 255, 255, 0.2);--bpk-private-navigation-tabs-selected: #024daf;--bpk-private-rating-bar-default: #e0e4e9;--bpk-private-rating-bar-on-contrast: #ffffff;--bpk-private-segmented-control-canvas-default: #eff3f8;--bpk-private-segmented-control-surface-contrast: rgba(255, 255, 255, 0.1);--bpk-private-segmented-control-surface-contrast-on: #024daf;--bpk-private-shadow-large-blur: 0.875rem;--bpk-private-shadow-large-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-large-position-x: 0;--bpk-private-shadow-large-position-y: 0.25rem;--bpk-private-shadow-large-spread: 0;--bpk-private-shadow-small-blur: 0.1875rem;--bpk-private-shadow-small-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-small-position-x: 0;--bpk-private-shadow-small-position-y: 0.0625rem;--bpk-private-shadow-small-spread: 0;--bpk-private-shadow-xl-blur: 3.125rem;--bpk-private-shadow-xl-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-xl-position-x: 0;--bpk-private-shadow-xl-position-y: 0.75rem;--bpk-private-shadow-xl-spread: 0;--bpk-private-skeleton-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-speech-bubble-colour-bg-contrast: #eff3f8;--bpk-private-speech-bubble-colour-bg-default: #ffffff;--bpk-private-trip-advisor: #00aa6c;--bpk-core-accent: #0062e3;--bpk-core-eco: #0fa1a9;--bpk-core-primary: #05203c;--bpk-other-line: #c1c7cf;--bpk-other-line-on-dark: rgba(255, 255, 255, 0.5);--bpk-other-overlay: rgba(0, 0, 0, 0.2);--bpk-other-scrim: rgba(0, 0, 0, 0.7);--bpk-other-shadow: rgba(22, 22, 22, 0.25);--bpk-status-danger-fill: #ffe9f9;--bpk-status-danger-spot: #e70866;--bpk-status-success-fill: #d4fff2;--bpk-status-success-spot: #0c838a;--bpk-status-warning-fill: #fff7cf;--bpk-status-warning-spot: #f55d42;--bpk-surface-contrast: #05203c;--bpk-surface-default: #ffffff;--bpk-surface-elevated: #ffffff;--bpk-surface-hero: #0062e3;--bpk-surface-highlight: #e0e4e9;--bpk-surface-low-contrast: #f7f9fb;--bpk-surface-subtle: #e3f0ff;--bpk-surface-tint: rgba(255, 255, 255, 0.1);--bpk-surface-promo: #0062e3;--bpk-text-disabled: rgba(0, 0, 0, 0.2);--bpk-text-disabled-on-dark: rgba(255, 255, 255, 0.5);--bpk-text-error: #e70866;--bpk-text-inverse: #ffffff;--bpk-text-on-dark: #ffffff;--bpk-text-on-light: #161616;--bpk-text-primary: #161616;--bpk-text-secondary: #626971;--bpk-text-success: #0c838a;--bpk-text-deprecated-link: #0062e3;--bpk-text-hero: #0062e3;--bpk-title: true;--bpk-typography-family-sans-serif: "Skyscanner Relative";--bpk-typography-family-serif: Larken;--bpk-typography-kerning-default: 0;--bpk-typography-kerning-loose: 0;--bpk-typography-kerning-tight: 0;--bpk-typography-style-body: 400;--bpk-typography-style-headline: 700;--bpk-typography-style-hero: 900;--bpk-typography-style-label: 700;--bpk-typography-style-subhead: 300}:root[data-theme=dark]{--bpk-canvas-contrast: #010913;--bpk-canvas-default: #010913;--bpk-private-badge-colour-bg-default: #243346;--bpk-private-badge-colour-bg-inverse: #243346;--bpk-private-badge-colour-bg-outline: rgba(255, 255, 255, 0);--bpk-private-badge-colour-bg-subtle: #243346;--bpk-private-badge-colour-stroke-outline: #ffffff;--bpk-private-badge-dimension-padding-horizontal-default: 0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle: 0.5rem;--bpk-private-badge-typography-tmp-badge-label: 0.875rem;--bpk-private-badge-typography-tmp-badge-line-height: 0;--bpk-private-button-colour-bg-destructive: #e0e4e9;--bpk-private-button-colour-bg-destructive-pressed: #ff649c;--bpk-private-button-colour-bg-disabled: #0b121d;--bpk-private-button-colour-bg-feature-pressed: #d1f7ff;--bpk-private-button-colour-bg-featured: #d1f7ff;--bpk-private-button-colour-bg-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-footer-pressed: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-primary: #024daf;--bpk-private-button-colour-bg-primary-on-dark: #ffffff;--bpk-private-button-colour-bg-primary-on-dark-pressed: #c1c7cf;--bpk-private-button-colour-bg-primary-on-light: #ffffff;--bpk-private-button-colour-bg-primary-on-light-pressed: #002b4b;--bpk-private-button-colour-bg-secondary: #243346;--bpk-private-button-colour-bg-secondary-pressed: #010913;--bpk-private-button-colour-bg-secondary-on-contrast: #243346;--bpk-private-button-colour-bg-secondary-on-contrast-pressed: #010913;--bpk-private-button-colour-bg-secondary-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-button-colour-bg-secondary-on-dark-disabled: #0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed: rgba(255, 255, 255, 0.2);--bpk-private-button-colour-text-disruptive: #ff649c;--bpk-private-button-colour-text-feature: #010913;--bpk-private-button-colour-text-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-text-link-on-dark: #ffffff;--bpk-private-button-colour-text-secondary: #ffffff;--bpk-private-button-dimension-radius: 0.5rem;--bpk-private-button-dimension-min-height-default: 2.25rem;--bpk-private-button-dimension-min-height-large: 3rem;--bpk-private-button-dimension-min-weight-large: 3rem;--bpk-private-button-dimension-padding-horizontal-default: 1rem;--bpk-private-button-dimension-padding-horizontal-large: 1rem;--bpk-private-button-typography-tmp-default-label: 1rem;--bpk-private-card-button-contained-fill: rgba(255, 255, 255, 0.1);--bpk-private-carousel-trigger-bg-default: rgba(255, 255, 255, 0.5);--bpk-private-carousel-trigger-bg-default-hover: rgba(255, 255, 255, 0.8);--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image: #010913;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image: #131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-default: #054184;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark: #131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image: #054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default: #054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark: #131d2b;--bpk-private-chip-group-filter-colour-stroke-icon-off-default: rgba(255, 255, 255, 0.2);--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark: rgba(255, 255, 255, 0.2);--bpk-private-chip-group-filter-dimensions-min-height: 2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover: #054184;--bpk-private-chip-colour-bg-default-on: #054184;--bpk-private-chip-colour-bg-disabled: #0b121d;--bpk-private-chip-colour-bg-on-contrast-hover: #131d2b;--bpk-private-chip-colour-bg-on-contrast-on: #054184;--bpk-private-chip-colour-bg-on-dark-dismissible-hover: #131d2b;--bpk-private-chip-colour-bg-on-dark-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-off: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-on: #131d2b;--bpk-private-chip-colour-bg-on-image-dismissible-hover: #054184;--bpk-private-chip-colour-bg-on-image-on: #010913;--bpk-private-chip-colour-border-default-dismissible-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-border-default-hover: #054184;--bpk-private-chip-colour-border-default-off: rgba(255, 255, 255, 0.2);--bpk-private-chip-colour-border-on-contrast-off: #131d2b;--bpk-private-chip-colour-border-on-contrast-on: #131d2b;--bpk-private-chip-colour-border-on-dark-disimissible-hover: #131d2b;--bpk-private-chip-colour-border-on-dark-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-off: rgba(255, 255, 255, 0.2);--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new: rgba(255, 255, 255, 0);--bpk-private-chip-colour-text-default-dismissible-hover: #ffffff;--bpk-private-chip-colour-text-dismissible-on-icon: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-text-on: #ffffff;--bpk-private-chip-colour-text-on-image: #ffffff;--bpk-private-chip-colour-text-on-image-dismissible-icon: #bdc4cb;--bpk-private-chip-colour-text-on-dark: #ffffff;--bpk-private-chip-colour-text-on-dark-dismisisble-hover: #ffffff;--bpk-private-chip-colour-text-on-dark-dismisisble-icon: #bdc4cb;--bpk-private-chip-dimension-min-height-width: 2rem;--bpk-private-chip-dimension-radius: 0.5rem;--bpk-private-date-selector-cheapest-month-highlight: #ffffff;--bpk-private-date-selector-flexible-date-card: #243346;--bpk-private-dimension-padding-veritcal: 0;--bpk-private-info-banner-default: #131d2b;--bpk-private-info-banner-on-contrast: #131d2b;--bpk-private-map-cluster-pin: #ffffff;--bpk-private-map-cluster-pin-previous-selection: #94c3ff;--bpk-private-map-marker-viewed: rgba(0, 0, 0, 0.8);--bpk-private-map-poi-pin: #8e47ba;--bpk-private-map-previous-selection: #cfe4ff;--bpk-private-navigation-tabs-hover: #002b4b;--bpk-private-navigation-tabs-outline: rgba(255, 255, 255, 0.2);--bpk-private-navigation-tabs-selected: #054184;--bpk-private-rating-bar-default: #243346;--bpk-private-rating-bar-on-contrast: #243346;--bpk-private-segmented-control-canvas-default: #131d2b;--bpk-private-segmented-control-surface-contrast: #131d2b;--bpk-private-segmented-control-surface-contrast-on: #054184;--bpk-private-shadow-large-blur: 0.875rem;--bpk-private-shadow-large-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-large-position-x: 0;--bpk-private-shadow-large-position-y: 0.25rem;--bpk-private-shadow-large-spread: 0;--bpk-private-shadow-small-blur: 0.1875rem;--bpk-private-shadow-small-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-small-position-x: 0;--bpk-private-shadow-small-position-y: 0.0625rem;--bpk-private-shadow-small-spread: 0;--bpk-private-shadow-xl-blur: 3.125rem;--bpk-private-shadow-xl-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-xl-position-x: 0;--bpk-private-shadow-xl-position-y: 0.75rem;--bpk-private-shadow-xl-spread: 0;--bpk-private-skeleton-on-dark: #243346;--bpk-private-speech-bubble-colour-bg-contrast: #131d2b;--bpk-private-speech-bubble-colour-bg-default: #131d2b;--bpk-private-trip-advisor: #9ce6c0;--bpk-core-accent: #84e9ff;--bpk-core-eco: #0fa1a9;--bpk-core-primary: #054184;--bpk-other-line: rgba(255, 255, 255, 0.2);--bpk-other-line-on-dark: rgba(255, 255, 255, 0.2);--bpk-other-overlay: rgba(255, 255, 255, 0.8);--bpk-other-scrim: rgba(0, 0, 0, 0.7);--bpk-other-shadow: rgba(22, 22, 22, 0.25);--bpk-status-danger-fill: #ffcadd;--bpk-status-danger-spot: #ff649c;--bpk-status-success-fill: #b1ffe7;--bpk-status-success-spot: #62f1c6;--bpk-status-warning-fill: #fbf1bb;--bpk-status-warning-spot: #feeb87;--bpk-surface-contrast: #010913;--bpk-surface-default: #131d2b;--bpk-surface-elevated: #243346;--bpk-surface-hero: #010913;--bpk-surface-highlight: #243346;--bpk-surface-low-contrast: #243346;--bpk-surface-subtle: #243346;--bpk-surface-tint: rgba(255, 255, 255, 0.1);--bpk-surface-promo: #243346;--bpk-text-disabled: rgba(255, 255, 255, 0.2);--bpk-text-disabled-on-dark: rgba(255, 255, 255, 0.5);--bpk-text-error: #ff649c;--bpk-text-inverse: #010913;--bpk-text-on-dark: #ffffff;--bpk-text-on-light: #010913;--bpk-text-primary: #ffffff;--bpk-text-secondary: #bdc4cb;--bpk-text-success: #62f1c6;--bpk-text-deprecated-link: #84e9ff;--bpk-text-hero: #010913;--bpk-title: true;--bpk-typography-family-sans-serif: "Skyscanner Relative";--bpk-typography-family-serif: Larken;--bpk-typography-kerning-default: 0;--bpk-typography-kerning-loose: 0;--bpk-typography-kerning-tight: 0;--bpk-typography-style-body: 400;--bpk-typography-style-headline: 700;--bpk-typography-style-hero: 900;--bpk-typography-style-label: 700;--bpk-typography-style-subhead: 300}html{font-size:100%;box-sizing:border-box}*{box-sizing:inherit}*::before,*::after{box-sizing:inherit}body{color:#161616;font-family:var(--bpk-base-font-stack, "Skyscanner Relative", -apple-system, BlinkMacSystemFont, "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif);font-size:1rem;line-height:1.3rem}body.scaffold-font-size{font-size:13px}body.enable-font-smoothing{-webkit-font-smoothing:antialiased}:focus-visible,button:focus-visible,[type=button]:focus-visible,[type=reset]:focus-visible,[type=submit]:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.hidden,.hide{display:none !important}.visuallyhidden,.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;white-space:nowrap;overflow:hidden;clip:rect(0 0 0 0)}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus,.visually-hidden.focusable:active,.visually-hidden.focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.invisible{visibility:hidden}.clearfix::before,.clearfix::after{content:"";display:table}.clearfix::after{clear:both} diff --git a/packages/bpk-stylesheets/index.scss b/packages/bpk-stylesheets/index.scss index eaa5c212e1..f397b16d58 100644 --- a/packages/bpk-stylesheets/index.scss +++ b/packages/bpk-stylesheets/index.scss @@ -19,6 +19,9 @@ @use '../bpk-mixins/tokens'; @use '../bpk-mixins/utils'; @use './normalize'; +@use '../../token-sync/css/primitives.css'; +@use '../../token-sync/css/theme-backpack-light.css'; +@use '../../token-sync/css/theme-backpack-dark.css'; // stylelint-disable-next-line selector-max-type html { From 4328a74a7569c6558d6c6475a753284f5d5f6b7b Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Mon, 18 May 2026 18:11:00 +0800 Subject: [PATCH 02/10] [CLOV-1412][bpk-stylesheets] Vendor token CSS at build time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address review feedback on #4492: 1. Sass paths must resolve from the published package. Previously index.scss did `@use '../../token-sync/css/*.css'`, which works in-repo but breaks for consumers compiling index.scss from node_modules — the published tarball does not include token-sync/. Mirror the normalize.scss precedent: copy the three CSS files into packages/bpk-stylesheets/ at build time (gitignored via the existing *.css rule), and switch index.scss to local paths. 2. README link to ../../token-sync/ would 404 on npm. Replace with absolute GitHub URL. base.css output is byte-identical to before. Co-Authored-By: Claude Opus 4.7 --- package.json | 1 + packages/bpk-stylesheets/README.md | 2 +- packages/bpk-stylesheets/index.scss | 6 +++--- scripts/scss/copy-token-css.sh | 25 +++++++++++++++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 scripts/scss/copy-token-css.sh diff --git a/package.json b/package.json index 9468a1b9aa..54a648481b 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "scripts": { "build": "run-s build:*", "build:copy-normal_css": "./scripts/scss/copy-normal_css.sh", + "build:copy-token-css": "bash ./scripts/scss/copy-token-css.sh", "build:gulp": "gulp", "build:sass": "node scripts/scss/styles-prod.js && rm packages/bpk-stylesheets/index.css", "build:stylesheets": "(cd packages/bpk-stylesheets && node build)", diff --git a/packages/bpk-stylesheets/README.md b/packages/bpk-stylesheets/README.md index 4b78492794..6a047df1cb 100644 --- a/packages/bpk-stylesheets/README.md +++ b/packages/bpk-stylesheets/README.md @@ -54,7 +54,7 @@ import '@skyscanner/backpack-web/bpk-stylesheets/larken.css'; ## Design tokens (CSS variables) -`base.css` ships the design token CSS variables generated by [`token-sync`](../../token-sync/). They are emitted as: +`base.css` ships the design token CSS variables generated by [`token-sync`](https://github.com/Skyscanner/backpack/tree/main/token-sync). They are emitted as: - `:root { … }` — Light theme semantic tokens + Spacing/Radius primitives (the default) - `:root[data-theme="dark"] { … }` — Dark theme overrides diff --git a/packages/bpk-stylesheets/index.scss b/packages/bpk-stylesheets/index.scss index f397b16d58..96906be4d2 100644 --- a/packages/bpk-stylesheets/index.scss +++ b/packages/bpk-stylesheets/index.scss @@ -19,9 +19,9 @@ @use '../bpk-mixins/tokens'; @use '../bpk-mixins/utils'; @use './normalize'; -@use '../../token-sync/css/primitives.css'; -@use '../../token-sync/css/theme-backpack-light.css'; -@use '../../token-sync/css/theme-backpack-dark.css'; +@use './primitives.css'; +@use './theme-backpack-light.css'; +@use './theme-backpack-dark.css'; // stylelint-disable-next-line selector-max-type html { diff --git a/scripts/scss/copy-token-css.sh b/scripts/scss/copy-token-css.sh new file mode 100644 index 0000000000..3b09e6b282 --- /dev/null +++ b/scripts/scss/copy-token-css.sh @@ -0,0 +1,25 @@ +# Backpack - Skyscanner's Design System +# +# Copyright 2016 Skyscanner Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +printf "📋 Copying token-sync CSS files to bpk-stylesheets...\n" + +cp token-sync/css/primitives.css packages/bpk-stylesheets/primitives.css +cp token-sync/css/theme-backpack-light.css packages/bpk-stylesheets/theme-backpack-light.css +cp token-sync/css/theme-backpack-dark.css packages/bpk-stylesheets/theme-backpack-dark.css + +printf "✅ Token CSS files copied.\n" From 32221daf24405f2ab54195cb2b58e908ed121b9d Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Mon, 18 May 2026 18:48:12 +0800 Subject: [PATCH 03/10] [CLOV-1412][bpk-stylesheets] Match copy-normal_css invocation pattern Make the new build:copy-token-css npm script consistent with its sibling build:copy-normal_css. - scripts/scss/copy-token-css.sh: set exec bit (100755) to match copy-normal_css.sh - package.json: drop the `bash` prefix and invoke directly as ./scripts/scss/copy-token-css.sh Both invocations work, but the file-mode/invocation mismatch was a latent footgun: a future contributor aligning package.json to the sibling pattern would have hit "permission denied" on a file committed without the exec bit. Co-Authored-By: Claude Opus 4.7 --- package.json | 2 +- scripts/scss/copy-token-css.sh | 0 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 scripts/scss/copy-token-css.sh diff --git a/package.json b/package.json index 54a648481b..b6f0b62792 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "scripts": { "build": "run-s build:*", "build:copy-normal_css": "./scripts/scss/copy-normal_css.sh", - "build:copy-token-css": "bash ./scripts/scss/copy-token-css.sh", + "build:copy-token-css": "./scripts/scss/copy-token-css.sh", "build:gulp": "gulp", "build:sass": "node scripts/scss/styles-prod.js && rm packages/bpk-stylesheets/index.css", "build:stylesheets": "(cd packages/bpk-stylesheets && node build)", diff --git a/scripts/scss/copy-token-css.sh b/scripts/scss/copy-token-css.sh old mode 100644 new mode 100755 From 4efaacd6ec1e48df9afc1d993ed25bea105bde48 Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Mon, 18 May 2026 19:28:40 +0800 Subject: [PATCH 04/10] [CLOV-1412][bpk-stylesheets] Document standalone build prerequisites Note in the Contributing section that index.scss depends on gitignored copy steps (normalize + token CSS), and that running build:stylesheets or build:sass standalone requires running the two copy scripts first. npm run build still handles this automatically via run-s build:*. Co-Authored-By: Claude Opus 4.7 --- packages/bpk-stylesheets/README.md | 11 +++++++++++ packages/bpk-stylesheets/base.css | 19 ------------------- 2 files changed, 11 insertions(+), 19 deletions(-) delete mode 100644 packages/bpk-stylesheets/base.css diff --git a/packages/bpk-stylesheets/README.md b/packages/bpk-stylesheets/README.md index 6a047df1cb..da9bb8fa35 100644 --- a/packages/bpk-stylesheets/README.md +++ b/packages/bpk-stylesheets/README.md @@ -155,3 +155,14 @@ Defined in `font.scss`, `larken.scss` Don't forget to rebuild and commit `base.css` after you make changes to this package. To build the `base.css` file run `npm run build:stylesheets` in the root folder. + +`index.scss` depends on two sets of files that are gitignored and copied in at build time: + +- `normalize.scss` — copied from `node_modules/normalize.css/` by `npm run build:copy-normal_css` +- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run build:copy-token-css` + +`npm run build` covers both via `run-s build:*` (alphabetical order). If you run `npm run build:stylesheets` or `npm run build:sass` standalone — for example after a fresh checkout, or after regenerating tokens with `npm run tokens:sync` — run the two copy steps first: + +```bash +npm run build:copy-normal_css && npm run build:copy-token-css +``` diff --git a/packages/bpk-stylesheets/base.css b/packages/bpk-stylesheets/base.css deleted file mode 100644 index 8eda29f88d..0000000000 --- a/packages/bpk-stylesheets/base.css +++ /dev/null @@ -1,19 +0,0 @@ -/* - * - * Backpack - Skyscanner's Design System - * - * Copyright 2016 Skyscanner Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:rgba(0,0,0,0);-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}:root{--bpk-radius-none: 0;--bpk-radius-full: 6.25rem;--bpk-radius-lg: 1.5rem;--bpk-radius-md: 0.75rem;--bpk-radius-nav-tabs: 1.125rem;--bpk-radius-sm: 0.5rem;--bpk-radius-xs: 0.25rem;--bpk-spacing-base: 1rem;--bpk-spacing-lg: 1.5rem;--bpk-spacing-md: 0.5rem;--bpk-spacing-none: 0;--bpk-spacing-sm: 0.25rem;--bpk-spacing-xl: 2rem;--bpk-spacing-xs: 0.125rem;--bpk-spacing-xxl: 2.5rem;--bpk-spacing-xxs: 0.0625rem;--bpk-spacing-xxxl: 4rem;--bpk-spacing-xxxxl: 6rem}:root{--bpk-canvas-contrast: #eff3f8;--bpk-canvas-default: #ffffff;--bpk-private-badge-colour-bg-default: #eff3f8;--bpk-private-badge-colour-bg-inverse: #ffffff;--bpk-private-badge-colour-bg-outline: rgba(255, 255, 255, 0);--bpk-private-badge-colour-bg-subtle: #eff3f8;--bpk-private-badge-colour-stroke-outline: #ffffff;--bpk-private-badge-dimension-padding-horizontal-default: 0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle: 0.5rem;--bpk-private-badge-typography-tmp-badge-label: 0.875rem;--bpk-private-badge-typography-tmp-badge-line-height: 0;--bpk-private-button-colour-bg-destructive: #e0e4e9;--bpk-private-button-colour-bg-destructive-pressed: #e70866;--bpk-private-button-colour-bg-disabled: #e0e4e9;--bpk-private-button-colour-bg-feature-pressed: #024daf;--bpk-private-button-colour-bg-featured: #0062e3;--bpk-private-button-colour-bg-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-footer-pressed: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-primary: #05203c;--bpk-private-button-colour-bg-primary-on-dark: #ffffff;--bpk-private-button-colour-bg-primary-on-dark-pressed: #c1c7cf;--bpk-private-button-colour-bg-primary-on-light: #ffffff;--bpk-private-button-colour-bg-primary-on-light-pressed: #154679;--bpk-private-button-colour-bg-secondary: #e0e4e9;--bpk-private-button-colour-bg-secondary-pressed: #c1c7cf;--bpk-private-button-colour-bg-secondary-on-contrast: #e0e4e9;--bpk-private-button-colour-bg-secondary-on-contrast-pressed: #c1c7cf;--bpk-private-button-colour-bg-secondary-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-button-colour-bg-secondary-on-dark-disabled: #0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed: #04182d;--bpk-private-button-colour-text-disruptive: #e70866;--bpk-private-button-colour-text-feature: #ffffff;--bpk-private-button-colour-text-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-text-link-on-dark: #ffffff;--bpk-private-button-colour-text-secondary: #161616;--bpk-private-button-dimension-radius: 0.5rem;--bpk-private-button-dimension-min-height-default: 2.25rem;--bpk-private-button-dimension-min-height-large: 3rem;--bpk-private-button-dimension-min-weight-large: 3rem;--bpk-private-button-dimension-padding-horizontal-default: 1rem;--bpk-private-button-dimension-padding-horizontal-large: 1rem;--bpk-private-button-typography-tmp-default-label: 1rem;--bpk-private-card-button-contained-fill: rgba(255, 255, 255, 0.8);--bpk-private-carousel-trigger-bg-default: rgba(255, 255, 255, 0.5);--bpk-private-carousel-trigger-bg-default-hover: rgba(255, 255, 255, 0.8);--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image: #eff3f8;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image: #ffffff;--bpk-private-chip-group-filter-colour-bg-icon-on-default: #05203c;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark: #ffffff;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image: #05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default: #05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark: #ffffff;--bpk-private-chip-group-filter-colour-stroke-icon-off-default: #c1c7cf;--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark: rgba(255, 255, 255, 0.5);--bpk-private-chip-group-filter-dimensions-min-height: 2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover: #05203c;--bpk-private-chip-colour-bg-default-on: #05203c;--bpk-private-chip-colour-bg-disabled: #e0e4e9;--bpk-private-chip-colour-bg-on-contrast-hover: #ffffff;--bpk-private-chip-colour-bg-on-contrast-on: #05203c;--bpk-private-chip-colour-bg-on-dark-dismissible-hover: #ffffff;--bpk-private-chip-colour-bg-on-dark-hover: #ffffff;--bpk-private-chip-colour-bg-on-dark-off: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-on: #ffffff;--bpk-private-chip-colour-bg-on-image-dismissible-hover: #05203c;--bpk-private-chip-colour-bg-on-image-on: #eff3f8;--bpk-private-chip-colour-border-default-dismissible-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-border-default-hover: #05203c;--bpk-private-chip-colour-border-default-off: #c1c7cf;--bpk-private-chip-colour-border-on-contrast-off: #ffffff;--bpk-private-chip-colour-border-on-contrast-on: #05203c;--bpk-private-chip-colour-border-on-dark-disimissible-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-off: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new: rgba(255, 255, 255, 0);--bpk-private-chip-colour-text-default-dismissible-hover: #ffffff;--bpk-private-chip-colour-text-dismissible-on-icon: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-text-on: #ffffff;--bpk-private-chip-colour-text-on-image: #ffffff;--bpk-private-chip-colour-text-on-image-dismissible-icon: #626971;--bpk-private-chip-colour-text-on-dark: #161616;--bpk-private-chip-colour-text-on-dark-dismisisble-hover: #161616;--bpk-private-chip-colour-text-on-dark-dismisisble-icon: #626971;--bpk-private-chip-dimension-min-height-width: 2rem;--bpk-private-chip-dimension-radius: 0.5rem;--bpk-private-date-selector-cheapest-month-highlight: #154679;--bpk-private-date-selector-flexible-date-card: #eff3f8;--bpk-private-dimension-padding-veritcal: 0;--bpk-private-info-banner-default: #eff3f8;--bpk-private-info-banner-on-contrast: #ffffff;--bpk-private-map-cluster-pin: #05203c;--bpk-private-map-cluster-pin-previous-selection: #94c3ff;--bpk-private-map-marker-viewed: rgba(255, 255, 255, 0.8);--bpk-private-map-poi-pin: #8e47ba;--bpk-private-map-previous-selection: #cfe4ff;--bpk-private-navigation-tabs-hover: #154679;--bpk-private-navigation-tabs-outline: rgba(255, 255, 255, 0.2);--bpk-private-navigation-tabs-selected: #024daf;--bpk-private-rating-bar-default: #e0e4e9;--bpk-private-rating-bar-on-contrast: #ffffff;--bpk-private-segmented-control-canvas-default: #eff3f8;--bpk-private-segmented-control-surface-contrast: rgba(255, 255, 255, 0.1);--bpk-private-segmented-control-surface-contrast-on: #024daf;--bpk-private-shadow-large-blur: 0.875rem;--bpk-private-shadow-large-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-large-position-x: 0;--bpk-private-shadow-large-position-y: 0.25rem;--bpk-private-shadow-large-spread: 0;--bpk-private-shadow-small-blur: 0.1875rem;--bpk-private-shadow-small-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-small-position-x: 0;--bpk-private-shadow-small-position-y: 0.0625rem;--bpk-private-shadow-small-spread: 0;--bpk-private-shadow-xl-blur: 3.125rem;--bpk-private-shadow-xl-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-xl-position-x: 0;--bpk-private-shadow-xl-position-y: 0.75rem;--bpk-private-shadow-xl-spread: 0;--bpk-private-skeleton-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-speech-bubble-colour-bg-contrast: #eff3f8;--bpk-private-speech-bubble-colour-bg-default: #ffffff;--bpk-private-trip-advisor: #00aa6c;--bpk-core-accent: #0062e3;--bpk-core-eco: #0fa1a9;--bpk-core-primary: #05203c;--bpk-other-line: #c1c7cf;--bpk-other-line-on-dark: rgba(255, 255, 255, 0.5);--bpk-other-overlay: rgba(0, 0, 0, 0.2);--bpk-other-scrim: rgba(0, 0, 0, 0.7);--bpk-other-shadow: rgba(22, 22, 22, 0.25);--bpk-status-danger-fill: #ffe9f9;--bpk-status-danger-spot: #e70866;--bpk-status-success-fill: #d4fff2;--bpk-status-success-spot: #0c838a;--bpk-status-warning-fill: #fff7cf;--bpk-status-warning-spot: #f55d42;--bpk-surface-contrast: #05203c;--bpk-surface-default: #ffffff;--bpk-surface-elevated: #ffffff;--bpk-surface-hero: #0062e3;--bpk-surface-highlight: #e0e4e9;--bpk-surface-low-contrast: #f7f9fb;--bpk-surface-subtle: #e3f0ff;--bpk-surface-tint: rgba(255, 255, 255, 0.1);--bpk-surface-promo: #0062e3;--bpk-text-disabled: rgba(0, 0, 0, 0.2);--bpk-text-disabled-on-dark: rgba(255, 255, 255, 0.5);--bpk-text-error: #e70866;--bpk-text-inverse: #ffffff;--bpk-text-on-dark: #ffffff;--bpk-text-on-light: #161616;--bpk-text-primary: #161616;--bpk-text-secondary: #626971;--bpk-text-success: #0c838a;--bpk-text-deprecated-link: #0062e3;--bpk-text-hero: #0062e3;--bpk-title: true;--bpk-typography-family-sans-serif: "Skyscanner Relative";--bpk-typography-family-serif: Larken;--bpk-typography-kerning-default: 0;--bpk-typography-kerning-loose: 0;--bpk-typography-kerning-tight: 0;--bpk-typography-style-body: 400;--bpk-typography-style-headline: 700;--bpk-typography-style-hero: 900;--bpk-typography-style-label: 700;--bpk-typography-style-subhead: 300}:root[data-theme=dark]{--bpk-canvas-contrast: #010913;--bpk-canvas-default: #010913;--bpk-private-badge-colour-bg-default: #243346;--bpk-private-badge-colour-bg-inverse: #243346;--bpk-private-badge-colour-bg-outline: rgba(255, 255, 255, 0);--bpk-private-badge-colour-bg-subtle: #243346;--bpk-private-badge-colour-stroke-outline: #ffffff;--bpk-private-badge-dimension-padding-horizontal-default: 0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle: 0.5rem;--bpk-private-badge-typography-tmp-badge-label: 0.875rem;--bpk-private-badge-typography-tmp-badge-line-height: 0;--bpk-private-button-colour-bg-destructive: #e0e4e9;--bpk-private-button-colour-bg-destructive-pressed: #ff649c;--bpk-private-button-colour-bg-disabled: #0b121d;--bpk-private-button-colour-bg-feature-pressed: #d1f7ff;--bpk-private-button-colour-bg-featured: #d1f7ff;--bpk-private-button-colour-bg-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-footer-pressed: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-primary: #024daf;--bpk-private-button-colour-bg-primary-on-dark: #ffffff;--bpk-private-button-colour-bg-primary-on-dark-pressed: #c1c7cf;--bpk-private-button-colour-bg-primary-on-light: #ffffff;--bpk-private-button-colour-bg-primary-on-light-pressed: #002b4b;--bpk-private-button-colour-bg-secondary: #243346;--bpk-private-button-colour-bg-secondary-pressed: #010913;--bpk-private-button-colour-bg-secondary-on-contrast: #243346;--bpk-private-button-colour-bg-secondary-on-contrast-pressed: #010913;--bpk-private-button-colour-bg-secondary-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-button-colour-bg-secondary-on-dark-disabled: #0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed: rgba(255, 255, 255, 0.2);--bpk-private-button-colour-text-disruptive: #ff649c;--bpk-private-button-colour-text-feature: #010913;--bpk-private-button-colour-text-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-text-link-on-dark: #ffffff;--bpk-private-button-colour-text-secondary: #ffffff;--bpk-private-button-dimension-radius: 0.5rem;--bpk-private-button-dimension-min-height-default: 2.25rem;--bpk-private-button-dimension-min-height-large: 3rem;--bpk-private-button-dimension-min-weight-large: 3rem;--bpk-private-button-dimension-padding-horizontal-default: 1rem;--bpk-private-button-dimension-padding-horizontal-large: 1rem;--bpk-private-button-typography-tmp-default-label: 1rem;--bpk-private-card-button-contained-fill: rgba(255, 255, 255, 0.1);--bpk-private-carousel-trigger-bg-default: rgba(255, 255, 255, 0.5);--bpk-private-carousel-trigger-bg-default-hover: rgba(255, 255, 255, 0.8);--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image: #010913;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image: #131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-default: #054184;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark: #131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image: #054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default: #054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark: #131d2b;--bpk-private-chip-group-filter-colour-stroke-icon-off-default: rgba(255, 255, 255, 0.2);--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark: rgba(255, 255, 255, 0.2);--bpk-private-chip-group-filter-dimensions-min-height: 2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover: #054184;--bpk-private-chip-colour-bg-default-on: #054184;--bpk-private-chip-colour-bg-disabled: #0b121d;--bpk-private-chip-colour-bg-on-contrast-hover: #131d2b;--bpk-private-chip-colour-bg-on-contrast-on: #054184;--bpk-private-chip-colour-bg-on-dark-dismissible-hover: #131d2b;--bpk-private-chip-colour-bg-on-dark-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-off: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-on: #131d2b;--bpk-private-chip-colour-bg-on-image-dismissible-hover: #054184;--bpk-private-chip-colour-bg-on-image-on: #010913;--bpk-private-chip-colour-border-default-dismissible-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-border-default-hover: #054184;--bpk-private-chip-colour-border-default-off: rgba(255, 255, 255, 0.2);--bpk-private-chip-colour-border-on-contrast-off: #131d2b;--bpk-private-chip-colour-border-on-contrast-on: #131d2b;--bpk-private-chip-colour-border-on-dark-disimissible-hover: #131d2b;--bpk-private-chip-colour-border-on-dark-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-off: rgba(255, 255, 255, 0.2);--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new: rgba(255, 255, 255, 0);--bpk-private-chip-colour-text-default-dismissible-hover: #ffffff;--bpk-private-chip-colour-text-dismissible-on-icon: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-text-on: #ffffff;--bpk-private-chip-colour-text-on-image: #ffffff;--bpk-private-chip-colour-text-on-image-dismissible-icon: #bdc4cb;--bpk-private-chip-colour-text-on-dark: #ffffff;--bpk-private-chip-colour-text-on-dark-dismisisble-hover: #ffffff;--bpk-private-chip-colour-text-on-dark-dismisisble-icon: #bdc4cb;--bpk-private-chip-dimension-min-height-width: 2rem;--bpk-private-chip-dimension-radius: 0.5rem;--bpk-private-date-selector-cheapest-month-highlight: #ffffff;--bpk-private-date-selector-flexible-date-card: #243346;--bpk-private-dimension-padding-veritcal: 0;--bpk-private-info-banner-default: #131d2b;--bpk-private-info-banner-on-contrast: #131d2b;--bpk-private-map-cluster-pin: #ffffff;--bpk-private-map-cluster-pin-previous-selection: #94c3ff;--bpk-private-map-marker-viewed: rgba(0, 0, 0, 0.8);--bpk-private-map-poi-pin: #8e47ba;--bpk-private-map-previous-selection: #cfe4ff;--bpk-private-navigation-tabs-hover: #002b4b;--bpk-private-navigation-tabs-outline: rgba(255, 255, 255, 0.2);--bpk-private-navigation-tabs-selected: #054184;--bpk-private-rating-bar-default: #243346;--bpk-private-rating-bar-on-contrast: #243346;--bpk-private-segmented-control-canvas-default: #131d2b;--bpk-private-segmented-control-surface-contrast: #131d2b;--bpk-private-segmented-control-surface-contrast-on: #054184;--bpk-private-shadow-large-blur: 0.875rem;--bpk-private-shadow-large-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-large-position-x: 0;--bpk-private-shadow-large-position-y: 0.25rem;--bpk-private-shadow-large-spread: 0;--bpk-private-shadow-small-blur: 0.1875rem;--bpk-private-shadow-small-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-small-position-x: 0;--bpk-private-shadow-small-position-y: 0.0625rem;--bpk-private-shadow-small-spread: 0;--bpk-private-shadow-xl-blur: 3.125rem;--bpk-private-shadow-xl-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-xl-position-x: 0;--bpk-private-shadow-xl-position-y: 0.75rem;--bpk-private-shadow-xl-spread: 0;--bpk-private-skeleton-on-dark: #243346;--bpk-private-speech-bubble-colour-bg-contrast: #131d2b;--bpk-private-speech-bubble-colour-bg-default: #131d2b;--bpk-private-trip-advisor: #9ce6c0;--bpk-core-accent: #84e9ff;--bpk-core-eco: #0fa1a9;--bpk-core-primary: #054184;--bpk-other-line: rgba(255, 255, 255, 0.2);--bpk-other-line-on-dark: rgba(255, 255, 255, 0.2);--bpk-other-overlay: rgba(255, 255, 255, 0.8);--bpk-other-scrim: rgba(0, 0, 0, 0.7);--bpk-other-shadow: rgba(22, 22, 22, 0.25);--bpk-status-danger-fill: #ffcadd;--bpk-status-danger-spot: #ff649c;--bpk-status-success-fill: #b1ffe7;--bpk-status-success-spot: #62f1c6;--bpk-status-warning-fill: #fbf1bb;--bpk-status-warning-spot: #feeb87;--bpk-surface-contrast: #010913;--bpk-surface-default: #131d2b;--bpk-surface-elevated: #243346;--bpk-surface-hero: #010913;--bpk-surface-highlight: #243346;--bpk-surface-low-contrast: #243346;--bpk-surface-subtle: #243346;--bpk-surface-tint: rgba(255, 255, 255, 0.1);--bpk-surface-promo: #243346;--bpk-text-disabled: rgba(255, 255, 255, 0.2);--bpk-text-disabled-on-dark: rgba(255, 255, 255, 0.5);--bpk-text-error: #ff649c;--bpk-text-inverse: #010913;--bpk-text-on-dark: #ffffff;--bpk-text-on-light: #010913;--bpk-text-primary: #ffffff;--bpk-text-secondary: #bdc4cb;--bpk-text-success: #62f1c6;--bpk-text-deprecated-link: #84e9ff;--bpk-text-hero: #010913;--bpk-title: true;--bpk-typography-family-sans-serif: "Skyscanner Relative";--bpk-typography-family-serif: Larken;--bpk-typography-kerning-default: 0;--bpk-typography-kerning-loose: 0;--bpk-typography-kerning-tight: 0;--bpk-typography-style-body: 400;--bpk-typography-style-headline: 700;--bpk-typography-style-hero: 900;--bpk-typography-style-label: 700;--bpk-typography-style-subhead: 300}html{font-size:100%;box-sizing:border-box}*{box-sizing:inherit}*::before,*::after{box-sizing:inherit}body{color:#161616;font-family:var(--bpk-base-font-stack, "Skyscanner Relative", -apple-system, BlinkMacSystemFont, "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif);font-size:1rem;line-height:1.3rem}body.scaffold-font-size{font-size:13px}body.enable-font-smoothing{-webkit-font-smoothing:antialiased}:focus-visible,button:focus-visible,[type=button]:focus-visible,[type=reset]:focus-visible,[type=submit]:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.hidden,.hide{display:none !important}.visuallyhidden,.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;white-space:nowrap;overflow:hidden;clip:rect(0 0 0 0)}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus,.visually-hidden.focusable:active,.visually-hidden.focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.invisible{visibility:hidden}.clearfix::before,.clearfix::after{content:"";display:table}.clearfix::after{clear:both} From 9b1b33b1643a3514cb59c828f9fdc64f8c9c26dc Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Mon, 18 May 2026 19:29:15 +0800 Subject: [PATCH 05/10] [CLOV-1412][bpk-stylesheets] Commit rebuilt base.css with token variables Co-Authored-By: Claude Opus 4.7 --- packages/bpk-stylesheets/base.css | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 packages/bpk-stylesheets/base.css diff --git a/packages/bpk-stylesheets/base.css b/packages/bpk-stylesheets/base.css new file mode 100644 index 0000000000..8eda29f88d --- /dev/null +++ b/packages/bpk-stylesheets/base.css @@ -0,0 +1,19 @@ +/* + * + * Backpack - Skyscanner's Design System + * + * Copyright 2016 Skyscanner Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:rgba(0,0,0,0);-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}:root{--bpk-radius-none: 0;--bpk-radius-full: 6.25rem;--bpk-radius-lg: 1.5rem;--bpk-radius-md: 0.75rem;--bpk-radius-nav-tabs: 1.125rem;--bpk-radius-sm: 0.5rem;--bpk-radius-xs: 0.25rem;--bpk-spacing-base: 1rem;--bpk-spacing-lg: 1.5rem;--bpk-spacing-md: 0.5rem;--bpk-spacing-none: 0;--bpk-spacing-sm: 0.25rem;--bpk-spacing-xl: 2rem;--bpk-spacing-xs: 0.125rem;--bpk-spacing-xxl: 2.5rem;--bpk-spacing-xxs: 0.0625rem;--bpk-spacing-xxxl: 4rem;--bpk-spacing-xxxxl: 6rem}:root{--bpk-canvas-contrast: #eff3f8;--bpk-canvas-default: #ffffff;--bpk-private-badge-colour-bg-default: #eff3f8;--bpk-private-badge-colour-bg-inverse: #ffffff;--bpk-private-badge-colour-bg-outline: rgba(255, 255, 255, 0);--bpk-private-badge-colour-bg-subtle: #eff3f8;--bpk-private-badge-colour-stroke-outline: #ffffff;--bpk-private-badge-dimension-padding-horizontal-default: 0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle: 0.5rem;--bpk-private-badge-typography-tmp-badge-label: 0.875rem;--bpk-private-badge-typography-tmp-badge-line-height: 0;--bpk-private-button-colour-bg-destructive: #e0e4e9;--bpk-private-button-colour-bg-destructive-pressed: #e70866;--bpk-private-button-colour-bg-disabled: #e0e4e9;--bpk-private-button-colour-bg-feature-pressed: #024daf;--bpk-private-button-colour-bg-featured: #0062e3;--bpk-private-button-colour-bg-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-footer-pressed: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-primary: #05203c;--bpk-private-button-colour-bg-primary-on-dark: #ffffff;--bpk-private-button-colour-bg-primary-on-dark-pressed: #c1c7cf;--bpk-private-button-colour-bg-primary-on-light: #ffffff;--bpk-private-button-colour-bg-primary-on-light-pressed: #154679;--bpk-private-button-colour-bg-secondary: #e0e4e9;--bpk-private-button-colour-bg-secondary-pressed: #c1c7cf;--bpk-private-button-colour-bg-secondary-on-contrast: #e0e4e9;--bpk-private-button-colour-bg-secondary-on-contrast-pressed: #c1c7cf;--bpk-private-button-colour-bg-secondary-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-button-colour-bg-secondary-on-dark-disabled: #0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed: #04182d;--bpk-private-button-colour-text-disruptive: #e70866;--bpk-private-button-colour-text-feature: #ffffff;--bpk-private-button-colour-text-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-text-link-on-dark: #ffffff;--bpk-private-button-colour-text-secondary: #161616;--bpk-private-button-dimension-radius: 0.5rem;--bpk-private-button-dimension-min-height-default: 2.25rem;--bpk-private-button-dimension-min-height-large: 3rem;--bpk-private-button-dimension-min-weight-large: 3rem;--bpk-private-button-dimension-padding-horizontal-default: 1rem;--bpk-private-button-dimension-padding-horizontal-large: 1rem;--bpk-private-button-typography-tmp-default-label: 1rem;--bpk-private-card-button-contained-fill: rgba(255, 255, 255, 0.8);--bpk-private-carousel-trigger-bg-default: rgba(255, 255, 255, 0.5);--bpk-private-carousel-trigger-bg-default-hover: rgba(255, 255, 255, 0.8);--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image: #eff3f8;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image: #ffffff;--bpk-private-chip-group-filter-colour-bg-icon-on-default: #05203c;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark: #ffffff;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image: #05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default: #05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark: #ffffff;--bpk-private-chip-group-filter-colour-stroke-icon-off-default: #c1c7cf;--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark: rgba(255, 255, 255, 0.5);--bpk-private-chip-group-filter-dimensions-min-height: 2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover: #05203c;--bpk-private-chip-colour-bg-default-on: #05203c;--bpk-private-chip-colour-bg-disabled: #e0e4e9;--bpk-private-chip-colour-bg-on-contrast-hover: #ffffff;--bpk-private-chip-colour-bg-on-contrast-on: #05203c;--bpk-private-chip-colour-bg-on-dark-dismissible-hover: #ffffff;--bpk-private-chip-colour-bg-on-dark-hover: #ffffff;--bpk-private-chip-colour-bg-on-dark-off: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-on: #ffffff;--bpk-private-chip-colour-bg-on-image-dismissible-hover: #05203c;--bpk-private-chip-colour-bg-on-image-on: #eff3f8;--bpk-private-chip-colour-border-default-dismissible-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-border-default-hover: #05203c;--bpk-private-chip-colour-border-default-off: #c1c7cf;--bpk-private-chip-colour-border-on-contrast-off: #ffffff;--bpk-private-chip-colour-border-on-contrast-on: #05203c;--bpk-private-chip-colour-border-on-dark-disimissible-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-off: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new: rgba(255, 255, 255, 0);--bpk-private-chip-colour-text-default-dismissible-hover: #ffffff;--bpk-private-chip-colour-text-dismissible-on-icon: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-text-on: #ffffff;--bpk-private-chip-colour-text-on-image: #ffffff;--bpk-private-chip-colour-text-on-image-dismissible-icon: #626971;--bpk-private-chip-colour-text-on-dark: #161616;--bpk-private-chip-colour-text-on-dark-dismisisble-hover: #161616;--bpk-private-chip-colour-text-on-dark-dismisisble-icon: #626971;--bpk-private-chip-dimension-min-height-width: 2rem;--bpk-private-chip-dimension-radius: 0.5rem;--bpk-private-date-selector-cheapest-month-highlight: #154679;--bpk-private-date-selector-flexible-date-card: #eff3f8;--bpk-private-dimension-padding-veritcal: 0;--bpk-private-info-banner-default: #eff3f8;--bpk-private-info-banner-on-contrast: #ffffff;--bpk-private-map-cluster-pin: #05203c;--bpk-private-map-cluster-pin-previous-selection: #94c3ff;--bpk-private-map-marker-viewed: rgba(255, 255, 255, 0.8);--bpk-private-map-poi-pin: #8e47ba;--bpk-private-map-previous-selection: #cfe4ff;--bpk-private-navigation-tabs-hover: #154679;--bpk-private-navigation-tabs-outline: rgba(255, 255, 255, 0.2);--bpk-private-navigation-tabs-selected: #024daf;--bpk-private-rating-bar-default: #e0e4e9;--bpk-private-rating-bar-on-contrast: #ffffff;--bpk-private-segmented-control-canvas-default: #eff3f8;--bpk-private-segmented-control-surface-contrast: rgba(255, 255, 255, 0.1);--bpk-private-segmented-control-surface-contrast-on: #024daf;--bpk-private-shadow-large-blur: 0.875rem;--bpk-private-shadow-large-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-large-position-x: 0;--bpk-private-shadow-large-position-y: 0.25rem;--bpk-private-shadow-large-spread: 0;--bpk-private-shadow-small-blur: 0.1875rem;--bpk-private-shadow-small-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-small-position-x: 0;--bpk-private-shadow-small-position-y: 0.0625rem;--bpk-private-shadow-small-spread: 0;--bpk-private-shadow-xl-blur: 3.125rem;--bpk-private-shadow-xl-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-xl-position-x: 0;--bpk-private-shadow-xl-position-y: 0.75rem;--bpk-private-shadow-xl-spread: 0;--bpk-private-skeleton-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-speech-bubble-colour-bg-contrast: #eff3f8;--bpk-private-speech-bubble-colour-bg-default: #ffffff;--bpk-private-trip-advisor: #00aa6c;--bpk-core-accent: #0062e3;--bpk-core-eco: #0fa1a9;--bpk-core-primary: #05203c;--bpk-other-line: #c1c7cf;--bpk-other-line-on-dark: rgba(255, 255, 255, 0.5);--bpk-other-overlay: rgba(0, 0, 0, 0.2);--bpk-other-scrim: rgba(0, 0, 0, 0.7);--bpk-other-shadow: rgba(22, 22, 22, 0.25);--bpk-status-danger-fill: #ffe9f9;--bpk-status-danger-spot: #e70866;--bpk-status-success-fill: #d4fff2;--bpk-status-success-spot: #0c838a;--bpk-status-warning-fill: #fff7cf;--bpk-status-warning-spot: #f55d42;--bpk-surface-contrast: #05203c;--bpk-surface-default: #ffffff;--bpk-surface-elevated: #ffffff;--bpk-surface-hero: #0062e3;--bpk-surface-highlight: #e0e4e9;--bpk-surface-low-contrast: #f7f9fb;--bpk-surface-subtle: #e3f0ff;--bpk-surface-tint: rgba(255, 255, 255, 0.1);--bpk-surface-promo: #0062e3;--bpk-text-disabled: rgba(0, 0, 0, 0.2);--bpk-text-disabled-on-dark: rgba(255, 255, 255, 0.5);--bpk-text-error: #e70866;--bpk-text-inverse: #ffffff;--bpk-text-on-dark: #ffffff;--bpk-text-on-light: #161616;--bpk-text-primary: #161616;--bpk-text-secondary: #626971;--bpk-text-success: #0c838a;--bpk-text-deprecated-link: #0062e3;--bpk-text-hero: #0062e3;--bpk-title: true;--bpk-typography-family-sans-serif: "Skyscanner Relative";--bpk-typography-family-serif: Larken;--bpk-typography-kerning-default: 0;--bpk-typography-kerning-loose: 0;--bpk-typography-kerning-tight: 0;--bpk-typography-style-body: 400;--bpk-typography-style-headline: 700;--bpk-typography-style-hero: 900;--bpk-typography-style-label: 700;--bpk-typography-style-subhead: 300}:root[data-theme=dark]{--bpk-canvas-contrast: #010913;--bpk-canvas-default: #010913;--bpk-private-badge-colour-bg-default: #243346;--bpk-private-badge-colour-bg-inverse: #243346;--bpk-private-badge-colour-bg-outline: rgba(255, 255, 255, 0);--bpk-private-badge-colour-bg-subtle: #243346;--bpk-private-badge-colour-stroke-outline: #ffffff;--bpk-private-badge-dimension-padding-horizontal-default: 0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle: 0.5rem;--bpk-private-badge-typography-tmp-badge-label: 0.875rem;--bpk-private-badge-typography-tmp-badge-line-height: 0;--bpk-private-button-colour-bg-destructive: #e0e4e9;--bpk-private-button-colour-bg-destructive-pressed: #ff649c;--bpk-private-button-colour-bg-disabled: #0b121d;--bpk-private-button-colour-bg-feature-pressed: #d1f7ff;--bpk-private-button-colour-bg-featured: #d1f7ff;--bpk-private-button-colour-bg-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-footer-pressed: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-primary: #024daf;--bpk-private-button-colour-bg-primary-on-dark: #ffffff;--bpk-private-button-colour-bg-primary-on-dark-pressed: #c1c7cf;--bpk-private-button-colour-bg-primary-on-light: #ffffff;--bpk-private-button-colour-bg-primary-on-light-pressed: #002b4b;--bpk-private-button-colour-bg-secondary: #243346;--bpk-private-button-colour-bg-secondary-pressed: #010913;--bpk-private-button-colour-bg-secondary-on-contrast: #243346;--bpk-private-button-colour-bg-secondary-on-contrast-pressed: #010913;--bpk-private-button-colour-bg-secondary-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-button-colour-bg-secondary-on-dark-disabled: #0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed: rgba(255, 255, 255, 0.2);--bpk-private-button-colour-text-disruptive: #ff649c;--bpk-private-button-colour-text-feature: #010913;--bpk-private-button-colour-text-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-text-link-on-dark: #ffffff;--bpk-private-button-colour-text-secondary: #ffffff;--bpk-private-button-dimension-radius: 0.5rem;--bpk-private-button-dimension-min-height-default: 2.25rem;--bpk-private-button-dimension-min-height-large: 3rem;--bpk-private-button-dimension-min-weight-large: 3rem;--bpk-private-button-dimension-padding-horizontal-default: 1rem;--bpk-private-button-dimension-padding-horizontal-large: 1rem;--bpk-private-button-typography-tmp-default-label: 1rem;--bpk-private-card-button-contained-fill: rgba(255, 255, 255, 0.1);--bpk-private-carousel-trigger-bg-default: rgba(255, 255, 255, 0.5);--bpk-private-carousel-trigger-bg-default-hover: rgba(255, 255, 255, 0.8);--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image: #010913;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image: #131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-default: #054184;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark: #131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image: #054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default: #054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark: #131d2b;--bpk-private-chip-group-filter-colour-stroke-icon-off-default: rgba(255, 255, 255, 0.2);--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark: rgba(255, 255, 255, 0.2);--bpk-private-chip-group-filter-dimensions-min-height: 2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover: #054184;--bpk-private-chip-colour-bg-default-on: #054184;--bpk-private-chip-colour-bg-disabled: #0b121d;--bpk-private-chip-colour-bg-on-contrast-hover: #131d2b;--bpk-private-chip-colour-bg-on-contrast-on: #054184;--bpk-private-chip-colour-bg-on-dark-dismissible-hover: #131d2b;--bpk-private-chip-colour-bg-on-dark-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-off: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-on: #131d2b;--bpk-private-chip-colour-bg-on-image-dismissible-hover: #054184;--bpk-private-chip-colour-bg-on-image-on: #010913;--bpk-private-chip-colour-border-default-dismissible-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-border-default-hover: #054184;--bpk-private-chip-colour-border-default-off: rgba(255, 255, 255, 0.2);--bpk-private-chip-colour-border-on-contrast-off: #131d2b;--bpk-private-chip-colour-border-on-contrast-on: #131d2b;--bpk-private-chip-colour-border-on-dark-disimissible-hover: #131d2b;--bpk-private-chip-colour-border-on-dark-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-off: rgba(255, 255, 255, 0.2);--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new: rgba(255, 255, 255, 0);--bpk-private-chip-colour-text-default-dismissible-hover: #ffffff;--bpk-private-chip-colour-text-dismissible-on-icon: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-text-on: #ffffff;--bpk-private-chip-colour-text-on-image: #ffffff;--bpk-private-chip-colour-text-on-image-dismissible-icon: #bdc4cb;--bpk-private-chip-colour-text-on-dark: #ffffff;--bpk-private-chip-colour-text-on-dark-dismisisble-hover: #ffffff;--bpk-private-chip-colour-text-on-dark-dismisisble-icon: #bdc4cb;--bpk-private-chip-dimension-min-height-width: 2rem;--bpk-private-chip-dimension-radius: 0.5rem;--bpk-private-date-selector-cheapest-month-highlight: #ffffff;--bpk-private-date-selector-flexible-date-card: #243346;--bpk-private-dimension-padding-veritcal: 0;--bpk-private-info-banner-default: #131d2b;--bpk-private-info-banner-on-contrast: #131d2b;--bpk-private-map-cluster-pin: #ffffff;--bpk-private-map-cluster-pin-previous-selection: #94c3ff;--bpk-private-map-marker-viewed: rgba(0, 0, 0, 0.8);--bpk-private-map-poi-pin: #8e47ba;--bpk-private-map-previous-selection: #cfe4ff;--bpk-private-navigation-tabs-hover: #002b4b;--bpk-private-navigation-tabs-outline: rgba(255, 255, 255, 0.2);--bpk-private-navigation-tabs-selected: #054184;--bpk-private-rating-bar-default: #243346;--bpk-private-rating-bar-on-contrast: #243346;--bpk-private-segmented-control-canvas-default: #131d2b;--bpk-private-segmented-control-surface-contrast: #131d2b;--bpk-private-segmented-control-surface-contrast-on: #054184;--bpk-private-shadow-large-blur: 0.875rem;--bpk-private-shadow-large-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-large-position-x: 0;--bpk-private-shadow-large-position-y: 0.25rem;--bpk-private-shadow-large-spread: 0;--bpk-private-shadow-small-blur: 0.1875rem;--bpk-private-shadow-small-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-small-position-x: 0;--bpk-private-shadow-small-position-y: 0.0625rem;--bpk-private-shadow-small-spread: 0;--bpk-private-shadow-xl-blur: 3.125rem;--bpk-private-shadow-xl-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-xl-position-x: 0;--bpk-private-shadow-xl-position-y: 0.75rem;--bpk-private-shadow-xl-spread: 0;--bpk-private-skeleton-on-dark: #243346;--bpk-private-speech-bubble-colour-bg-contrast: #131d2b;--bpk-private-speech-bubble-colour-bg-default: #131d2b;--bpk-private-trip-advisor: #9ce6c0;--bpk-core-accent: #84e9ff;--bpk-core-eco: #0fa1a9;--bpk-core-primary: #054184;--bpk-other-line: rgba(255, 255, 255, 0.2);--bpk-other-line-on-dark: rgba(255, 255, 255, 0.2);--bpk-other-overlay: rgba(255, 255, 255, 0.8);--bpk-other-scrim: rgba(0, 0, 0, 0.7);--bpk-other-shadow: rgba(22, 22, 22, 0.25);--bpk-status-danger-fill: #ffcadd;--bpk-status-danger-spot: #ff649c;--bpk-status-success-fill: #b1ffe7;--bpk-status-success-spot: #62f1c6;--bpk-status-warning-fill: #fbf1bb;--bpk-status-warning-spot: #feeb87;--bpk-surface-contrast: #010913;--bpk-surface-default: #131d2b;--bpk-surface-elevated: #243346;--bpk-surface-hero: #010913;--bpk-surface-highlight: #243346;--bpk-surface-low-contrast: #243346;--bpk-surface-subtle: #243346;--bpk-surface-tint: rgba(255, 255, 255, 0.1);--bpk-surface-promo: #243346;--bpk-text-disabled: rgba(255, 255, 255, 0.2);--bpk-text-disabled-on-dark: rgba(255, 255, 255, 0.5);--bpk-text-error: #ff649c;--bpk-text-inverse: #010913;--bpk-text-on-dark: #ffffff;--bpk-text-on-light: #010913;--bpk-text-primary: #ffffff;--bpk-text-secondary: #bdc4cb;--bpk-text-success: #62f1c6;--bpk-text-deprecated-link: #84e9ff;--bpk-text-hero: #010913;--bpk-title: true;--bpk-typography-family-sans-serif: "Skyscanner Relative";--bpk-typography-family-serif: Larken;--bpk-typography-kerning-default: 0;--bpk-typography-kerning-loose: 0;--bpk-typography-kerning-tight: 0;--bpk-typography-style-body: 400;--bpk-typography-style-headline: 700;--bpk-typography-style-hero: 900;--bpk-typography-style-label: 700;--bpk-typography-style-subhead: 300}html{font-size:100%;box-sizing:border-box}*{box-sizing:inherit}*::before,*::after{box-sizing:inherit}body{color:#161616;font-family:var(--bpk-base-font-stack, "Skyscanner Relative", -apple-system, BlinkMacSystemFont, "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif);font-size:1rem;line-height:1.3rem}body.scaffold-font-size{font-size:13px}body.enable-font-smoothing{-webkit-font-smoothing:antialiased}:focus-visible,button:focus-visible,[type=button]:focus-visible,[type=reset]:focus-visible,[type=submit]:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.hidden,.hide{display:none !important}.visuallyhidden,.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;white-space:nowrap;overflow:hidden;clip:rect(0 0 0 0)}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus,.visually-hidden.focusable:active,.visually-hidden.focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.invisible{visibility:hidden}.clearfix::before,.clearfix::after{content:"";display:table}.clearfix::after{clear:both} From 492fc5834f47d7bae8f27ad6c80e598260231ed2 Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Tue, 19 May 2026 11:45:47 +0800 Subject: [PATCH 06/10] [CLOV-1412][bpk-stylesheets] Move token CSS imports from SCSS to JS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously index.scss reached into vendored token CSS via @use, which forced build:sass (compiles all SCSS via glob) to depend on copy:token-css and made it tricky to wire copy into build:stylesheets without duplicating the work during npm run build. Move the three token CSS imports out of index.scss and into index.js (after ./index.scss) so they reach base.css through webpack's CSS pipeline instead of sass. To keep the published base.css from ballooning with three duplicated Apache license blocks (one per vendored token CSS file), wire postcss-discard-comments into the .css rule's postcss chain so headers are stripped before WrapperPlugin re-adds the single Backpack license header. Net effect: - build:sass no longer needs copy:token-css. - build:copy-token-css renamed to copy:token-css so it is no longer picked up by run-s build:*; build:stylesheets invokes it directly. - npm run build runs copy:token-css exactly once (via build:stylesheets); npm run build:stylesheets is self-contained on a fresh checkout. base.css size: 21,365 → 22,083 bytes raw (+3.4%), but gzipped/brotli are slightly smaller (-30 / -28 bytes) due to more regular formatting. README updated to reflect the new layout. Co-Authored-By: Claude Opus 4.7 --- package-lock.json | 68 ++-- package.json | 5 +- packages/bpk-stylesheets/README.md | 12 +- packages/bpk-stylesheets/base.css | 363 +++++++++++++++++- packages/bpk-stylesheets/index.js | 3 + packages/bpk-stylesheets/index.scss | 3 - .../bpk-stylesheets/webpack.config.babel.js | 3 +- 7 files changed, 418 insertions(+), 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index fcef64f6db..843f4dccc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,6 +70,7 @@ "lodash": "^4.18.1", "mini-css-extract-plugin": "^2.9.0", "npm-run-all": "^4.1.5", + "postcss-discard-comments": "^8.0.0", "postcss-flexbugs-fixes": "^5.0.2", "postcss-loader": "^8.2.0", "prop-types": "^15.7.2", @@ -9715,13 +9716,16 @@ ] }, "node_modules/baseline-browser-mapping": { - "version": "2.8.32", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz", - "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==", + "version": "2.10.31", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.31.tgz", + "integrity": "sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/basic-ftp": { @@ -9913,9 +9917,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, "funding": [ { @@ -9933,11 +9937,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -10195,9 +10199,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001757", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz", - "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==", + "version": "1.0.30001793", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", + "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", "dev": true, "funding": [ { @@ -12241,9 +12245,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.262", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz", - "integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==", + "version": "1.5.357", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.357.tgz", + "integrity": "sha512-NHlTIQDK8fmVwHwuIzmXYEJ1Ewq3D9wDNc0cWXxDGysP6Pb21giwGNkxiTifyKy/4SoPuN5l6GLP1W9Sv7zB2g==", "dev": true, "license": "ISC" }, @@ -21545,9 +21549,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.44", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", + "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", "dev": true, "license": "MIT" }, @@ -23007,6 +23011,22 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-discard-comments": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-8.0.0.tgz", + "integrity": "sha512-zGpvVLj2sbagEp+BTVETvAfkZdGVA6rALNujDK/WTIjdf1/rQOxOG8BBzkI8UQgnw8SkL6xffAfbtGMHFypadw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^22.11.0 || ^24.11.0 || >=26.0" + }, + "peerDependencies": { + "postcss": "^8.5.14" + } + }, "node_modules/postcss-flexbugs-fixes": { "version": "5.0.2", "dev": true, @@ -29278,9 +29298,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index b6f0b62792..cd320bb871 100644 --- a/package.json +++ b/package.json @@ -18,10 +18,10 @@ "scripts": { "build": "run-s build:*", "build:copy-normal_css": "./scripts/scss/copy-normal_css.sh", - "build:copy-token-css": "./scripts/scss/copy-token-css.sh", "build:gulp": "gulp", "build:sass": "node scripts/scss/styles-prod.js && rm packages/bpk-stylesheets/index.css", - "build:stylesheets": "(cd packages/bpk-stylesheets && node build)", + "build:stylesheets": "npm run copy:token-css && (cd packages/bpk-stylesheets && node build)", + "copy:token-css": "./scripts/scss/copy-token-css.sh", "check-bpk-dependencies": "node scripts/npm/check-bpk-dependencies.js", "check-react-versions": "node scripts/npm/check-react-versions.js", "check-pristine": "node scripts/check-pristine-state", @@ -174,6 +174,7 @@ "lodash": "^4.18.1", "mini-css-extract-plugin": "^2.9.0", "npm-run-all": "^4.1.5", + "postcss-discard-comments": "^8.0.0", "postcss-flexbugs-fixes": "^5.0.2", "postcss-loader": "^8.2.0", "prop-types": "^15.7.2", diff --git a/packages/bpk-stylesheets/README.md b/packages/bpk-stylesheets/README.md index da9bb8fa35..ec64ba33fb 100644 --- a/packages/bpk-stylesheets/README.md +++ b/packages/bpk-stylesheets/README.md @@ -156,13 +156,9 @@ Don't forget to rebuild and commit `base.css` after you make changes to this pac To build the `base.css` file run `npm run build:stylesheets` in the root folder. -`index.scss` depends on two sets of files that are gitignored and copied in at build time: +The webpack build depends on two sets of files that are gitignored and copied in at build time: -- `normalize.scss` — copied from `node_modules/normalize.css/` by `npm run build:copy-normal_css` -- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run build:copy-token-css` +- `normalize.scss` — copied from `node_modules/normalize.css/` by `npm run build:copy-normal_css`. Imported via `@use` in `index.scss`. +- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run copy:token-css`. Imported in `index.js` so they reach `base.css` through webpack's CSS pipeline (which strips their license headers via `postcss-discard-comments`); `index.scss` does not depend on them, so `build:sass` does not need them either. -`npm run build` covers both via `run-s build:*` (alphabetical order). If you run `npm run build:stylesheets` or `npm run build:sass` standalone — for example after a fresh checkout, or after regenerating tokens with `npm run tokens:sync` — run the two copy steps first: - -```bash -npm run build:copy-normal_css && npm run build:copy-token-css -``` +`build:stylesheets` invokes `copy:token-css` automatically, so `npm run build` and `npm run build:stylesheets` both work standalone (including after a fresh checkout or after regenerating tokens with `npm run tokens:sync`). For `build:sass`, run `npm run build:copy-normal_css` first if `normalize.scss` isn't already vendored. diff --git a/packages/bpk-stylesheets/base.css b/packages/bpk-stylesheets/base.css index 8eda29f88d..4ff13a9f5a 100644 --- a/packages/bpk-stylesheets/base.css +++ b/packages/bpk-stylesheets/base.css @@ -16,4 +16,365 @@ * See the License for the specific language governing permissions and * limitations under the License. * - *//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:rgba(0,0,0,0);-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}:root{--bpk-radius-none: 0;--bpk-radius-full: 6.25rem;--bpk-radius-lg: 1.5rem;--bpk-radius-md: 0.75rem;--bpk-radius-nav-tabs: 1.125rem;--bpk-radius-sm: 0.5rem;--bpk-radius-xs: 0.25rem;--bpk-spacing-base: 1rem;--bpk-spacing-lg: 1.5rem;--bpk-spacing-md: 0.5rem;--bpk-spacing-none: 0;--bpk-spacing-sm: 0.25rem;--bpk-spacing-xl: 2rem;--bpk-spacing-xs: 0.125rem;--bpk-spacing-xxl: 2.5rem;--bpk-spacing-xxs: 0.0625rem;--bpk-spacing-xxxl: 4rem;--bpk-spacing-xxxxl: 6rem}:root{--bpk-canvas-contrast: #eff3f8;--bpk-canvas-default: #ffffff;--bpk-private-badge-colour-bg-default: #eff3f8;--bpk-private-badge-colour-bg-inverse: #ffffff;--bpk-private-badge-colour-bg-outline: rgba(255, 255, 255, 0);--bpk-private-badge-colour-bg-subtle: #eff3f8;--bpk-private-badge-colour-stroke-outline: #ffffff;--bpk-private-badge-dimension-padding-horizontal-default: 0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle: 0.5rem;--bpk-private-badge-typography-tmp-badge-label: 0.875rem;--bpk-private-badge-typography-tmp-badge-line-height: 0;--bpk-private-button-colour-bg-destructive: #e0e4e9;--bpk-private-button-colour-bg-destructive-pressed: #e70866;--bpk-private-button-colour-bg-disabled: #e0e4e9;--bpk-private-button-colour-bg-feature-pressed: #024daf;--bpk-private-button-colour-bg-featured: #0062e3;--bpk-private-button-colour-bg-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-footer-pressed: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-primary: #05203c;--bpk-private-button-colour-bg-primary-on-dark: #ffffff;--bpk-private-button-colour-bg-primary-on-dark-pressed: #c1c7cf;--bpk-private-button-colour-bg-primary-on-light: #ffffff;--bpk-private-button-colour-bg-primary-on-light-pressed: #154679;--bpk-private-button-colour-bg-secondary: #e0e4e9;--bpk-private-button-colour-bg-secondary-pressed: #c1c7cf;--bpk-private-button-colour-bg-secondary-on-contrast: #e0e4e9;--bpk-private-button-colour-bg-secondary-on-contrast-pressed: #c1c7cf;--bpk-private-button-colour-bg-secondary-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-button-colour-bg-secondary-on-dark-disabled: #0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed: #04182d;--bpk-private-button-colour-text-disruptive: #e70866;--bpk-private-button-colour-text-feature: #ffffff;--bpk-private-button-colour-text-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-text-link-on-dark: #ffffff;--bpk-private-button-colour-text-secondary: #161616;--bpk-private-button-dimension-radius: 0.5rem;--bpk-private-button-dimension-min-height-default: 2.25rem;--bpk-private-button-dimension-min-height-large: 3rem;--bpk-private-button-dimension-min-weight-large: 3rem;--bpk-private-button-dimension-padding-horizontal-default: 1rem;--bpk-private-button-dimension-padding-horizontal-large: 1rem;--bpk-private-button-typography-tmp-default-label: 1rem;--bpk-private-card-button-contained-fill: rgba(255, 255, 255, 0.8);--bpk-private-carousel-trigger-bg-default: rgba(255, 255, 255, 0.5);--bpk-private-carousel-trigger-bg-default-hover: rgba(255, 255, 255, 0.8);--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image: #eff3f8;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image: #ffffff;--bpk-private-chip-group-filter-colour-bg-icon-on-default: #05203c;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark: #ffffff;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image: #05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default: #05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark: #ffffff;--bpk-private-chip-group-filter-colour-stroke-icon-off-default: #c1c7cf;--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark: rgba(255, 255, 255, 0.5);--bpk-private-chip-group-filter-dimensions-min-height: 2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover: #05203c;--bpk-private-chip-colour-bg-default-on: #05203c;--bpk-private-chip-colour-bg-disabled: #e0e4e9;--bpk-private-chip-colour-bg-on-contrast-hover: #ffffff;--bpk-private-chip-colour-bg-on-contrast-on: #05203c;--bpk-private-chip-colour-bg-on-dark-dismissible-hover: #ffffff;--bpk-private-chip-colour-bg-on-dark-hover: #ffffff;--bpk-private-chip-colour-bg-on-dark-off: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-on: #ffffff;--bpk-private-chip-colour-bg-on-image-dismissible-hover: #05203c;--bpk-private-chip-colour-bg-on-image-on: #eff3f8;--bpk-private-chip-colour-border-default-dismissible-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-border-default-hover: #05203c;--bpk-private-chip-colour-border-default-off: #c1c7cf;--bpk-private-chip-colour-border-on-contrast-off: #ffffff;--bpk-private-chip-colour-border-on-contrast-on: #05203c;--bpk-private-chip-colour-border-on-dark-disimissible-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-off: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new: rgba(255, 255, 255, 0);--bpk-private-chip-colour-text-default-dismissible-hover: #ffffff;--bpk-private-chip-colour-text-dismissible-on-icon: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-text-on: #ffffff;--bpk-private-chip-colour-text-on-image: #ffffff;--bpk-private-chip-colour-text-on-image-dismissible-icon: #626971;--bpk-private-chip-colour-text-on-dark: #161616;--bpk-private-chip-colour-text-on-dark-dismisisble-hover: #161616;--bpk-private-chip-colour-text-on-dark-dismisisble-icon: #626971;--bpk-private-chip-dimension-min-height-width: 2rem;--bpk-private-chip-dimension-radius: 0.5rem;--bpk-private-date-selector-cheapest-month-highlight: #154679;--bpk-private-date-selector-flexible-date-card: #eff3f8;--bpk-private-dimension-padding-veritcal: 0;--bpk-private-info-banner-default: #eff3f8;--bpk-private-info-banner-on-contrast: #ffffff;--bpk-private-map-cluster-pin: #05203c;--bpk-private-map-cluster-pin-previous-selection: #94c3ff;--bpk-private-map-marker-viewed: rgba(255, 255, 255, 0.8);--bpk-private-map-poi-pin: #8e47ba;--bpk-private-map-previous-selection: #cfe4ff;--bpk-private-navigation-tabs-hover: #154679;--bpk-private-navigation-tabs-outline: rgba(255, 255, 255, 0.2);--bpk-private-navigation-tabs-selected: #024daf;--bpk-private-rating-bar-default: #e0e4e9;--bpk-private-rating-bar-on-contrast: #ffffff;--bpk-private-segmented-control-canvas-default: #eff3f8;--bpk-private-segmented-control-surface-contrast: rgba(255, 255, 255, 0.1);--bpk-private-segmented-control-surface-contrast-on: #024daf;--bpk-private-shadow-large-blur: 0.875rem;--bpk-private-shadow-large-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-large-position-x: 0;--bpk-private-shadow-large-position-y: 0.25rem;--bpk-private-shadow-large-spread: 0;--bpk-private-shadow-small-blur: 0.1875rem;--bpk-private-shadow-small-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-small-position-x: 0;--bpk-private-shadow-small-position-y: 0.0625rem;--bpk-private-shadow-small-spread: 0;--bpk-private-shadow-xl-blur: 3.125rem;--bpk-private-shadow-xl-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-xl-position-x: 0;--bpk-private-shadow-xl-position-y: 0.75rem;--bpk-private-shadow-xl-spread: 0;--bpk-private-skeleton-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-speech-bubble-colour-bg-contrast: #eff3f8;--bpk-private-speech-bubble-colour-bg-default: #ffffff;--bpk-private-trip-advisor: #00aa6c;--bpk-core-accent: #0062e3;--bpk-core-eco: #0fa1a9;--bpk-core-primary: #05203c;--bpk-other-line: #c1c7cf;--bpk-other-line-on-dark: rgba(255, 255, 255, 0.5);--bpk-other-overlay: rgba(0, 0, 0, 0.2);--bpk-other-scrim: rgba(0, 0, 0, 0.7);--bpk-other-shadow: rgba(22, 22, 22, 0.25);--bpk-status-danger-fill: #ffe9f9;--bpk-status-danger-spot: #e70866;--bpk-status-success-fill: #d4fff2;--bpk-status-success-spot: #0c838a;--bpk-status-warning-fill: #fff7cf;--bpk-status-warning-spot: #f55d42;--bpk-surface-contrast: #05203c;--bpk-surface-default: #ffffff;--bpk-surface-elevated: #ffffff;--bpk-surface-hero: #0062e3;--bpk-surface-highlight: #e0e4e9;--bpk-surface-low-contrast: #f7f9fb;--bpk-surface-subtle: #e3f0ff;--bpk-surface-tint: rgba(255, 255, 255, 0.1);--bpk-surface-promo: #0062e3;--bpk-text-disabled: rgba(0, 0, 0, 0.2);--bpk-text-disabled-on-dark: rgba(255, 255, 255, 0.5);--bpk-text-error: #e70866;--bpk-text-inverse: #ffffff;--bpk-text-on-dark: #ffffff;--bpk-text-on-light: #161616;--bpk-text-primary: #161616;--bpk-text-secondary: #626971;--bpk-text-success: #0c838a;--bpk-text-deprecated-link: #0062e3;--bpk-text-hero: #0062e3;--bpk-title: true;--bpk-typography-family-sans-serif: "Skyscanner Relative";--bpk-typography-family-serif: Larken;--bpk-typography-kerning-default: 0;--bpk-typography-kerning-loose: 0;--bpk-typography-kerning-tight: 0;--bpk-typography-style-body: 400;--bpk-typography-style-headline: 700;--bpk-typography-style-hero: 900;--bpk-typography-style-label: 700;--bpk-typography-style-subhead: 300}:root[data-theme=dark]{--bpk-canvas-contrast: #010913;--bpk-canvas-default: #010913;--bpk-private-badge-colour-bg-default: #243346;--bpk-private-badge-colour-bg-inverse: #243346;--bpk-private-badge-colour-bg-outline: rgba(255, 255, 255, 0);--bpk-private-badge-colour-bg-subtle: #243346;--bpk-private-badge-colour-stroke-outline: #ffffff;--bpk-private-badge-dimension-padding-horizontal-default: 0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle: 0.5rem;--bpk-private-badge-typography-tmp-badge-label: 0.875rem;--bpk-private-badge-typography-tmp-badge-line-height: 0;--bpk-private-button-colour-bg-destructive: #e0e4e9;--bpk-private-button-colour-bg-destructive-pressed: #ff649c;--bpk-private-button-colour-bg-disabled: #0b121d;--bpk-private-button-colour-bg-feature-pressed: #d1f7ff;--bpk-private-button-colour-bg-featured: #d1f7ff;--bpk-private-button-colour-bg-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-footer-pressed: rgba(255, 255, 255, 0);--bpk-private-button-colour-bg-primary: #024daf;--bpk-private-button-colour-bg-primary-on-dark: #ffffff;--bpk-private-button-colour-bg-primary-on-dark-pressed: #c1c7cf;--bpk-private-button-colour-bg-primary-on-light: #ffffff;--bpk-private-button-colour-bg-primary-on-light-pressed: #002b4b;--bpk-private-button-colour-bg-secondary: #243346;--bpk-private-button-colour-bg-secondary-pressed: #010913;--bpk-private-button-colour-bg-secondary-on-contrast: #243346;--bpk-private-button-colour-bg-secondary-on-contrast-pressed: #010913;--bpk-private-button-colour-bg-secondary-on-dark: rgba(255, 255, 255, 0.1);--bpk-private-button-colour-bg-secondary-on-dark-disabled: #0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed: rgba(255, 255, 255, 0.2);--bpk-private-button-colour-text-disruptive: #ff649c;--bpk-private-button-colour-text-feature: #010913;--bpk-private-button-colour-text-footer: rgba(255, 255, 255, 0);--bpk-private-button-colour-text-link-on-dark: #ffffff;--bpk-private-button-colour-text-secondary: #ffffff;--bpk-private-button-dimension-radius: 0.5rem;--bpk-private-button-dimension-min-height-default: 2.25rem;--bpk-private-button-dimension-min-height-large: 3rem;--bpk-private-button-dimension-min-weight-large: 3rem;--bpk-private-button-dimension-padding-horizontal-default: 1rem;--bpk-private-button-dimension-padding-horizontal-large: 1rem;--bpk-private-button-typography-tmp-default-label: 1rem;--bpk-private-card-button-contained-fill: rgba(255, 255, 255, 0.1);--bpk-private-carousel-trigger-bg-default: rgba(255, 255, 255, 0.5);--bpk-private-carousel-trigger-bg-default-hover: rgba(255, 255, 255, 0.8);--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image: #010913;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image: #131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-default: #054184;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark: #131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image: #054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default: #054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark: #131d2b;--bpk-private-chip-group-filter-colour-stroke-icon-off-default: rgba(255, 255, 255, 0.2);--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark: rgba(255, 255, 255, 0.2);--bpk-private-chip-group-filter-dimensions-min-height: 2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover: #054184;--bpk-private-chip-colour-bg-default-on: #054184;--bpk-private-chip-colour-bg-disabled: #0b121d;--bpk-private-chip-colour-bg-on-contrast-hover: #131d2b;--bpk-private-chip-colour-bg-on-contrast-on: #054184;--bpk-private-chip-colour-bg-on-dark-dismissible-hover: #131d2b;--bpk-private-chip-colour-bg-on-dark-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-off: rgba(255, 255, 255, 0);--bpk-private-chip-colour-bg-on-dark-on: #131d2b;--bpk-private-chip-colour-bg-on-image-dismissible-hover: #054184;--bpk-private-chip-colour-bg-on-image-on: #010913;--bpk-private-chip-colour-border-default-dismissible-hover: rgba(255, 255, 255, 0);--bpk-private-chip-colour-border-default-hover: #054184;--bpk-private-chip-colour-border-default-off: rgba(255, 255, 255, 0.2);--bpk-private-chip-colour-border-on-contrast-off: #131d2b;--bpk-private-chip-colour-border-on-contrast-on: #131d2b;--bpk-private-chip-colour-border-on-dark-disimissible-hover: #131d2b;--bpk-private-chip-colour-border-on-dark-hover: #ffffff;--bpk-private-chip-colour-border-on-dark-off: rgba(255, 255, 255, 0.2);--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new: rgba(255, 255, 255, 0);--bpk-private-chip-colour-text-default-dismissible-hover: #ffffff;--bpk-private-chip-colour-text-dismissible-on-icon: rgba(255, 255, 255, 0.5);--bpk-private-chip-colour-text-on: #ffffff;--bpk-private-chip-colour-text-on-image: #ffffff;--bpk-private-chip-colour-text-on-image-dismissible-icon: #bdc4cb;--bpk-private-chip-colour-text-on-dark: #ffffff;--bpk-private-chip-colour-text-on-dark-dismisisble-hover: #ffffff;--bpk-private-chip-colour-text-on-dark-dismisisble-icon: #bdc4cb;--bpk-private-chip-dimension-min-height-width: 2rem;--bpk-private-chip-dimension-radius: 0.5rem;--bpk-private-date-selector-cheapest-month-highlight: #ffffff;--bpk-private-date-selector-flexible-date-card: #243346;--bpk-private-dimension-padding-veritcal: 0;--bpk-private-info-banner-default: #131d2b;--bpk-private-info-banner-on-contrast: #131d2b;--bpk-private-map-cluster-pin: #ffffff;--bpk-private-map-cluster-pin-previous-selection: #94c3ff;--bpk-private-map-marker-viewed: rgba(0, 0, 0, 0.8);--bpk-private-map-poi-pin: #8e47ba;--bpk-private-map-previous-selection: #cfe4ff;--bpk-private-navigation-tabs-hover: #002b4b;--bpk-private-navigation-tabs-outline: rgba(255, 255, 255, 0.2);--bpk-private-navigation-tabs-selected: #054184;--bpk-private-rating-bar-default: #243346;--bpk-private-rating-bar-on-contrast: #243346;--bpk-private-segmented-control-canvas-default: #131d2b;--bpk-private-segmented-control-surface-contrast: #131d2b;--bpk-private-segmented-control-surface-contrast-on: #054184;--bpk-private-shadow-large-blur: 0.875rem;--bpk-private-shadow-large-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-large-position-x: 0;--bpk-private-shadow-large-position-y: 0.25rem;--bpk-private-shadow-large-spread: 0;--bpk-private-shadow-small-blur: 0.1875rem;--bpk-private-shadow-small-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-small-position-x: 0;--bpk-private-shadow-small-position-y: 0.0625rem;--bpk-private-shadow-small-spread: 0;--bpk-private-shadow-xl-blur: 3.125rem;--bpk-private-shadow-xl-color: rgba(22, 22, 22, 0.25);--bpk-private-shadow-xl-position-x: 0;--bpk-private-shadow-xl-position-y: 0.75rem;--bpk-private-shadow-xl-spread: 0;--bpk-private-skeleton-on-dark: #243346;--bpk-private-speech-bubble-colour-bg-contrast: #131d2b;--bpk-private-speech-bubble-colour-bg-default: #131d2b;--bpk-private-trip-advisor: #9ce6c0;--bpk-core-accent: #84e9ff;--bpk-core-eco: #0fa1a9;--bpk-core-primary: #054184;--bpk-other-line: rgba(255, 255, 255, 0.2);--bpk-other-line-on-dark: rgba(255, 255, 255, 0.2);--bpk-other-overlay: rgba(255, 255, 255, 0.8);--bpk-other-scrim: rgba(0, 0, 0, 0.7);--bpk-other-shadow: rgba(22, 22, 22, 0.25);--bpk-status-danger-fill: #ffcadd;--bpk-status-danger-spot: #ff649c;--bpk-status-success-fill: #b1ffe7;--bpk-status-success-spot: #62f1c6;--bpk-status-warning-fill: #fbf1bb;--bpk-status-warning-spot: #feeb87;--bpk-surface-contrast: #010913;--bpk-surface-default: #131d2b;--bpk-surface-elevated: #243346;--bpk-surface-hero: #010913;--bpk-surface-highlight: #243346;--bpk-surface-low-contrast: #243346;--bpk-surface-subtle: #243346;--bpk-surface-tint: rgba(255, 255, 255, 0.1);--bpk-surface-promo: #243346;--bpk-text-disabled: rgba(255, 255, 255, 0.2);--bpk-text-disabled-on-dark: rgba(255, 255, 255, 0.5);--bpk-text-error: #ff649c;--bpk-text-inverse: #010913;--bpk-text-on-dark: #ffffff;--bpk-text-on-light: #010913;--bpk-text-primary: #ffffff;--bpk-text-secondary: #bdc4cb;--bpk-text-success: #62f1c6;--bpk-text-deprecated-link: #84e9ff;--bpk-text-hero: #010913;--bpk-title: true;--bpk-typography-family-sans-serif: "Skyscanner Relative";--bpk-typography-family-serif: Larken;--bpk-typography-kerning-default: 0;--bpk-typography-kerning-loose: 0;--bpk-typography-kerning-tight: 0;--bpk-typography-style-body: 400;--bpk-typography-style-headline: 700;--bpk-typography-style-hero: 900;--bpk-typography-style-label: 700;--bpk-typography-style-subhead: 300}html{font-size:100%;box-sizing:border-box}*{box-sizing:inherit}*::before,*::after{box-sizing:inherit}body{color:#161616;font-family:var(--bpk-base-font-stack, "Skyscanner Relative", -apple-system, BlinkMacSystemFont, "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif);font-size:1rem;line-height:1.3rem}body.scaffold-font-size{font-size:13px}body.enable-font-smoothing{-webkit-font-smoothing:antialiased}:focus-visible,button:focus-visible,[type=button]:focus-visible,[type=reset]:focus-visible,[type=submit]:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.hidden,.hide{display:none !important}.visuallyhidden,.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;white-space:nowrap;overflow:hidden;clip:rect(0 0 0 0)}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus,.visually-hidden.focusable:active,.visually-hidden.focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.invisible{visibility:hidden}.clearfix::before,.clearfix::after{content:"";display:table}.clearfix::after{clear:both} + *//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:rgba(0,0,0,0);-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}html{font-size:100%;box-sizing:border-box}*{box-sizing:inherit}*::before,*::after{box-sizing:inherit}body{color:#161616;font-family:var(--bpk-base-font-stack, "Skyscanner Relative", -apple-system, BlinkMacSystemFont, "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif);font-size:1rem;line-height:1.3rem}body.scaffold-font-size{font-size:13px}body.enable-font-smoothing{-webkit-font-smoothing:antialiased}:focus-visible,button:focus-visible,[type=button]:focus-visible,[type=reset]:focus-visible,[type=submit]:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.hidden,.hide{display:none !important}.visuallyhidden,.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;white-space:nowrap;overflow:hidden;clip:rect(0 0 0 0)}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus,.visually-hidden.focusable:active,.visually-hidden.focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.invisible{visibility:hidden}.clearfix::before,.clearfix::after{content:"";display:table}.clearfix::after{clear:both} +:root{ + --bpk-radius-none:0; + --bpk-radius-full:6.25rem; + --bpk-radius-lg:1.5rem; + --bpk-radius-md:0.75rem; + --bpk-radius-nav-tabs:1.125rem; + --bpk-radius-sm:0.5rem; + --bpk-radius-xs:0.25rem; + --bpk-spacing-base:1rem; + --bpk-spacing-lg:1.5rem; + --bpk-spacing-md:0.5rem; + --bpk-spacing-none:0; + --bpk-spacing-sm:0.25rem; + --bpk-spacing-xl:2rem; + --bpk-spacing-xs:0.125rem; + --bpk-spacing-xxl:2.5rem; + --bpk-spacing-xxs:0.0625rem; + --bpk-spacing-xxxl:4rem; + --bpk-spacing-xxxxl:6rem; +} + +:root{ + --bpk-canvas-contrast:#eff3f8; + --bpk-canvas-default:#ffffff; + --bpk-private-badge-colour-bg-default:#eff3f8; + --bpk-private-badge-colour-bg-inverse:#ffffff; + --bpk-private-badge-colour-bg-outline:rgba(255, 255, 255, 0); + --bpk-private-badge-colour-bg-subtle:#eff3f8; + --bpk-private-badge-colour-stroke-outline:#ffffff; + --bpk-private-badge-dimension-padding-horizontal-default:0.5rem; + --bpk-private-badge-dimension-padding-horizontal-subtle:0.5rem; + --bpk-private-badge-typography-tmp-badge-label:0.875rem; + --bpk-private-badge-typography-tmp-badge-line-height:0; + --bpk-private-button-colour-bg-destructive:#e0e4e9; + --bpk-private-button-colour-bg-destructive-pressed:#e70866; + --bpk-private-button-colour-bg-disabled:#e0e4e9; + --bpk-private-button-colour-bg-feature-pressed:#024daf; + --bpk-private-button-colour-bg-featured:#0062e3; + --bpk-private-button-colour-bg-footer:rgba(255, 255, 255, 0); + --bpk-private-button-colour-bg-footer-pressed:rgba(255, 255, 255, 0); + --bpk-private-button-colour-bg-primary:#05203c; + --bpk-private-button-colour-bg-primary-on-dark:#ffffff; + --bpk-private-button-colour-bg-primary-on-dark-pressed:#c1c7cf; + --bpk-private-button-colour-bg-primary-on-light:#ffffff; + --bpk-private-button-colour-bg-primary-on-light-pressed:#154679; + --bpk-private-button-colour-bg-secondary:#e0e4e9; + --bpk-private-button-colour-bg-secondary-pressed:#c1c7cf; + --bpk-private-button-colour-bg-secondary-on-contrast:#e0e4e9; + --bpk-private-button-colour-bg-secondary-on-contrast-pressed:#c1c7cf; + --bpk-private-button-colour-bg-secondary-on-dark:rgba(255, 255, 255, 0.1); + --bpk-private-button-colour-bg-secondary-on-dark-disabled:#0b121d; + --bpk-private-button-colour-bg-secondary-on-dark-pressed:#04182d; + --bpk-private-button-colour-text-disruptive:#e70866; + --bpk-private-button-colour-text-feature:#ffffff; + --bpk-private-button-colour-text-footer:rgba(255, 255, 255, 0); + --bpk-private-button-colour-text-link-on-dark:#ffffff; + --bpk-private-button-colour-text-secondary:#161616; + --bpk-private-button-dimension-radius:0.5rem; + --bpk-private-button-dimension-min-height-default:2.25rem; + --bpk-private-button-dimension-min-height-large:3rem; + --bpk-private-button-dimension-min-weight-large:3rem; + --bpk-private-button-dimension-padding-horizontal-default:1rem; + --bpk-private-button-dimension-padding-horizontal-large:1rem; + --bpk-private-button-typography-tmp-default-label:1rem; + --bpk-private-card-button-contained-fill:rgba(255, 255, 255, 0.8); + --bpk-private-carousel-trigger-bg-default:rgba(255, 255, 255, 0.5); + --bpk-private-carousel-trigger-bg-default-hover:rgba(255, 255, 255, 0.8); + --bpk-private-chip-group-filter-colour-bg-icon-hover-on-image:#eff3f8; + --bpk-private-chip-group-filter-colour-bg-icon-off-on-image:#ffffff; + --bpk-private-chip-group-filter-colour-bg-icon-on-default:#05203c; + --bpk-private-chip-group-filter-colour-bg-icon-on-on-dark:#ffffff; + --bpk-private-chip-group-filter-colour-bg-icon-on-on-image:#05203c; + --bpk-private-chip-group-filter-colour-stroke-icon-hover-default:#05203c; + --bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark:#ffffff; + --bpk-private-chip-group-filter-colour-stroke-icon-off-default:#c1c7cf; + --bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark:rgba(255, 255, 255, 0.5); + --bpk-private-chip-group-filter-dimensions-min-height:2.25rem; + --bpk-private-chip-colour-bg-default-dismissible-hover:#05203c; + --bpk-private-chip-colour-bg-default-on:#05203c; + --bpk-private-chip-colour-bg-disabled:#e0e4e9; + --bpk-private-chip-colour-bg-on-contrast-hover:#ffffff; + --bpk-private-chip-colour-bg-on-contrast-on:#05203c; + --bpk-private-chip-colour-bg-on-dark-dismissible-hover:#ffffff; + --bpk-private-chip-colour-bg-on-dark-hover:#ffffff; + --bpk-private-chip-colour-bg-on-dark-off:rgba(255, 255, 255, 0); + --bpk-private-chip-colour-bg-on-dark-on:#ffffff; + --bpk-private-chip-colour-bg-on-image-dismissible-hover:#05203c; + --bpk-private-chip-colour-bg-on-image-on:#eff3f8; + --bpk-private-chip-colour-border-default-dismissible-hover:rgba(255, 255, 255, 0); + --bpk-private-chip-colour-border-default-hover:#05203c; + --bpk-private-chip-colour-border-default-off:#c1c7cf; + --bpk-private-chip-colour-border-on-contrast-off:#ffffff; + --bpk-private-chip-colour-border-on-contrast-on:#05203c; + --bpk-private-chip-colour-border-on-dark-disimissible-hover:#ffffff; + --bpk-private-chip-colour-border-on-dark-hover:#ffffff; + --bpk-private-chip-colour-border-on-dark-off:rgba(255, 255, 255, 0.5); + --bpk-private-chip-colour-stroke-off-on-canvas-contrast-new:rgba(255, 255, 255, 0); + --bpk-private-chip-colour-text-default-dismissible-hover:#ffffff; + --bpk-private-chip-colour-text-dismissible-on-icon:rgba(255, 255, 255, 0.5); + --bpk-private-chip-colour-text-on:#ffffff; + --bpk-private-chip-colour-text-on-image:#ffffff; + --bpk-private-chip-colour-text-on-image-dismissible-icon:#626971; + --bpk-private-chip-colour-text-on-dark:#161616; + --bpk-private-chip-colour-text-on-dark-dismisisble-hover:#161616; + --bpk-private-chip-colour-text-on-dark-dismisisble-icon:#626971; + --bpk-private-chip-dimension-min-height-width:2rem; + --bpk-private-chip-dimension-radius:0.5rem; + --bpk-private-date-selector-cheapest-month-highlight:#154679; + --bpk-private-date-selector-flexible-date-card:#eff3f8; + --bpk-private-dimension-padding-veritcal:0; + --bpk-private-info-banner-default:#eff3f8; + --bpk-private-info-banner-on-contrast:#ffffff; + --bpk-private-map-cluster-pin:#05203c; + --bpk-private-map-cluster-pin-previous-selection:#94c3ff; + --bpk-private-map-marker-viewed:rgba(255, 255, 255, 0.8); + --bpk-private-map-poi-pin:#8e47ba; + --bpk-private-map-previous-selection:#cfe4ff; + --bpk-private-navigation-tabs-hover:#154679; + --bpk-private-navigation-tabs-outline:rgba(255, 255, 255, 0.2); + --bpk-private-navigation-tabs-selected:#024daf; + --bpk-private-rating-bar-default:#e0e4e9; + --bpk-private-rating-bar-on-contrast:#ffffff; + --bpk-private-segmented-control-canvas-default:#eff3f8; + --bpk-private-segmented-control-surface-contrast:rgba(255, 255, 255, 0.1); + --bpk-private-segmented-control-surface-contrast-on:#024daf; + --bpk-private-shadow-large-blur:0.875rem; + --bpk-private-shadow-large-color:rgba(22, 22, 22, 0.25); + --bpk-private-shadow-large-position-x:0; + --bpk-private-shadow-large-position-y:0.25rem; + --bpk-private-shadow-large-spread:0; + --bpk-private-shadow-small-blur:0.1875rem; + --bpk-private-shadow-small-color:rgba(22, 22, 22, 0.25); + --bpk-private-shadow-small-position-x:0; + --bpk-private-shadow-small-position-y:0.0625rem; + --bpk-private-shadow-small-spread:0; + --bpk-private-shadow-xl-blur:3.125rem; + --bpk-private-shadow-xl-color:rgba(22, 22, 22, 0.25); + --bpk-private-shadow-xl-position-x:0; + --bpk-private-shadow-xl-position-y:0.75rem; + --bpk-private-shadow-xl-spread:0; + --bpk-private-skeleton-on-dark:rgba(255, 255, 255, 0.1); + --bpk-private-speech-bubble-colour-bg-contrast:#eff3f8; + --bpk-private-speech-bubble-colour-bg-default:#ffffff; + --bpk-private-trip-advisor:#00aa6c; + --bpk-core-accent:#0062e3; + --bpk-core-eco:#0fa1a9; + --bpk-core-primary:#05203c; + --bpk-other-line:#c1c7cf; + --bpk-other-line-on-dark:rgba(255, 255, 255, 0.5); + --bpk-other-overlay:rgba(0, 0, 0, 0.2); + --bpk-other-scrim:rgba(0, 0, 0, 0.7); + --bpk-other-shadow:rgba(22, 22, 22, 0.25); + --bpk-status-danger-fill:#ffe9f9; + --bpk-status-danger-spot:#e70866; + --bpk-status-success-fill:#d4fff2; + --bpk-status-success-spot:#0c838a; + --bpk-status-warning-fill:#fff7cf; + --bpk-status-warning-spot:#f55d42; + --bpk-surface-contrast:#05203c; + --bpk-surface-default:#ffffff; + --bpk-surface-elevated:#ffffff; + --bpk-surface-hero:#0062e3; + --bpk-surface-highlight:#e0e4e9; + --bpk-surface-low-contrast:#f7f9fb; + --bpk-surface-subtle:#e3f0ff; + --bpk-surface-tint:rgba(255, 255, 255, 0.1); + --bpk-surface-promo:#0062e3; + --bpk-text-disabled:rgba(0, 0, 0, 0.2); + --bpk-text-disabled-on-dark:rgba(255, 255, 255, 0.5); + --bpk-text-error:#e70866; + --bpk-text-inverse:#ffffff; + --bpk-text-on-dark:#ffffff; + --bpk-text-on-light:#161616; + --bpk-text-primary:#161616; + --bpk-text-secondary:#626971; + --bpk-text-success:#0c838a; + --bpk-text-deprecated-link:#0062e3; + --bpk-text-hero:#0062e3; + --bpk-title:true; + --bpk-typography-family-sans-serif:'Skyscanner Relative'; + --bpk-typography-family-serif:Larken; + --bpk-typography-kerning-default:0; + --bpk-typography-kerning-loose:0; + --bpk-typography-kerning-tight:0; + --bpk-typography-style-body:400; + --bpk-typography-style-headline:700; + --bpk-typography-style-hero:900; + --bpk-typography-style-label:700; + --bpk-typography-style-subhead:300; +} + +:root[data-theme="dark"]{ + --bpk-canvas-contrast:#010913; + --bpk-canvas-default:#010913; + --bpk-private-badge-colour-bg-default:#243346; + --bpk-private-badge-colour-bg-inverse:#243346; + --bpk-private-badge-colour-bg-outline:rgba(255, 255, 255, 0); + --bpk-private-badge-colour-bg-subtle:#243346; + --bpk-private-badge-colour-stroke-outline:#ffffff; + --bpk-private-badge-dimension-padding-horizontal-default:0.5rem; + --bpk-private-badge-dimension-padding-horizontal-subtle:0.5rem; + --bpk-private-badge-typography-tmp-badge-label:0.875rem; + --bpk-private-badge-typography-tmp-badge-line-height:0; + --bpk-private-button-colour-bg-destructive:#e0e4e9; + --bpk-private-button-colour-bg-destructive-pressed:#ff649c; + --bpk-private-button-colour-bg-disabled:#0b121d; + --bpk-private-button-colour-bg-feature-pressed:#d1f7ff; + --bpk-private-button-colour-bg-featured:#d1f7ff; + --bpk-private-button-colour-bg-footer:rgba(255, 255, 255, 0); + --bpk-private-button-colour-bg-footer-pressed:rgba(255, 255, 255, 0); + --bpk-private-button-colour-bg-primary:#024daf; + --bpk-private-button-colour-bg-primary-on-dark:#ffffff; + --bpk-private-button-colour-bg-primary-on-dark-pressed:#c1c7cf; + --bpk-private-button-colour-bg-primary-on-light:#ffffff; + --bpk-private-button-colour-bg-primary-on-light-pressed:#002b4b; + --bpk-private-button-colour-bg-secondary:#243346; + --bpk-private-button-colour-bg-secondary-pressed:#010913; + --bpk-private-button-colour-bg-secondary-on-contrast:#243346; + --bpk-private-button-colour-bg-secondary-on-contrast-pressed:#010913; + --bpk-private-button-colour-bg-secondary-on-dark:rgba(255, 255, 255, 0.1); + --bpk-private-button-colour-bg-secondary-on-dark-disabled:#0b121d; + --bpk-private-button-colour-bg-secondary-on-dark-pressed:rgba(255, 255, 255, 0.2); + --bpk-private-button-colour-text-disruptive:#ff649c; + --bpk-private-button-colour-text-feature:#010913; + --bpk-private-button-colour-text-footer:rgba(255, 255, 255, 0); + --bpk-private-button-colour-text-link-on-dark:#ffffff; + --bpk-private-button-colour-text-secondary:#ffffff; + --bpk-private-button-dimension-radius:0.5rem; + --bpk-private-button-dimension-min-height-default:2.25rem; + --bpk-private-button-dimension-min-height-large:3rem; + --bpk-private-button-dimension-min-weight-large:3rem; + --bpk-private-button-dimension-padding-horizontal-default:1rem; + --bpk-private-button-dimension-padding-horizontal-large:1rem; + --bpk-private-button-typography-tmp-default-label:1rem; + --bpk-private-card-button-contained-fill:rgba(255, 255, 255, 0.1); + --bpk-private-carousel-trigger-bg-default:rgba(255, 255, 255, 0.5); + --bpk-private-carousel-trigger-bg-default-hover:rgba(255, 255, 255, 0.8); + --bpk-private-chip-group-filter-colour-bg-icon-hover-on-image:#010913; + --bpk-private-chip-group-filter-colour-bg-icon-off-on-image:#131d2b; + --bpk-private-chip-group-filter-colour-bg-icon-on-default:#054184; + --bpk-private-chip-group-filter-colour-bg-icon-on-on-dark:#131d2b; + --bpk-private-chip-group-filter-colour-bg-icon-on-on-image:#054184; + --bpk-private-chip-group-filter-colour-stroke-icon-hover-default:#054184; + --bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark:#131d2b; + --bpk-private-chip-group-filter-colour-stroke-icon-off-default:rgba(255, 255, 255, 0.2); + --bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark:rgba(255, 255, 255, 0.2); + --bpk-private-chip-group-filter-dimensions-min-height:2.25rem; + --bpk-private-chip-colour-bg-default-dismissible-hover:#054184; + --bpk-private-chip-colour-bg-default-on:#054184; + --bpk-private-chip-colour-bg-disabled:#0b121d; + --bpk-private-chip-colour-bg-on-contrast-hover:#131d2b; + --bpk-private-chip-colour-bg-on-contrast-on:#054184; + --bpk-private-chip-colour-bg-on-dark-dismissible-hover:#131d2b; + --bpk-private-chip-colour-bg-on-dark-hover:rgba(255, 255, 255, 0); + --bpk-private-chip-colour-bg-on-dark-off:rgba(255, 255, 255, 0); + --bpk-private-chip-colour-bg-on-dark-on:#131d2b; + --bpk-private-chip-colour-bg-on-image-dismissible-hover:#054184; + --bpk-private-chip-colour-bg-on-image-on:#010913; + --bpk-private-chip-colour-border-default-dismissible-hover:rgba(255, 255, 255, 0); + --bpk-private-chip-colour-border-default-hover:#054184; + --bpk-private-chip-colour-border-default-off:rgba(255, 255, 255, 0.2); + --bpk-private-chip-colour-border-on-contrast-off:#131d2b; + --bpk-private-chip-colour-border-on-contrast-on:#131d2b; + --bpk-private-chip-colour-border-on-dark-disimissible-hover:#131d2b; + --bpk-private-chip-colour-border-on-dark-hover:#ffffff; + --bpk-private-chip-colour-border-on-dark-off:rgba(255, 255, 255, 0.2); + --bpk-private-chip-colour-stroke-off-on-canvas-contrast-new:rgba(255, 255, 255, 0); + --bpk-private-chip-colour-text-default-dismissible-hover:#ffffff; + --bpk-private-chip-colour-text-dismissible-on-icon:rgba(255, 255, 255, 0.5); + --bpk-private-chip-colour-text-on:#ffffff; + --bpk-private-chip-colour-text-on-image:#ffffff; + --bpk-private-chip-colour-text-on-image-dismissible-icon:#bdc4cb; + --bpk-private-chip-colour-text-on-dark:#ffffff; + --bpk-private-chip-colour-text-on-dark-dismisisble-hover:#ffffff; + --bpk-private-chip-colour-text-on-dark-dismisisble-icon:#bdc4cb; + --bpk-private-chip-dimension-min-height-width:2rem; + --bpk-private-chip-dimension-radius:0.5rem; + --bpk-private-date-selector-cheapest-month-highlight:#ffffff; + --bpk-private-date-selector-flexible-date-card:#243346; + --bpk-private-dimension-padding-veritcal:0; + --bpk-private-info-banner-default:#131d2b; + --bpk-private-info-banner-on-contrast:#131d2b; + --bpk-private-map-cluster-pin:#ffffff; + --bpk-private-map-cluster-pin-previous-selection:#94c3ff; + --bpk-private-map-marker-viewed:rgba(0, 0, 0, 0.8); + --bpk-private-map-poi-pin:#8e47ba; + --bpk-private-map-previous-selection:#cfe4ff; + --bpk-private-navigation-tabs-hover:#002b4b; + --bpk-private-navigation-tabs-outline:rgba(255, 255, 255, 0.2); + --bpk-private-navigation-tabs-selected:#054184; + --bpk-private-rating-bar-default:#243346; + --bpk-private-rating-bar-on-contrast:#243346; + --bpk-private-segmented-control-canvas-default:#131d2b; + --bpk-private-segmented-control-surface-contrast:#131d2b; + --bpk-private-segmented-control-surface-contrast-on:#054184; + --bpk-private-shadow-large-blur:0.875rem; + --bpk-private-shadow-large-color:rgba(22, 22, 22, 0.25); + --bpk-private-shadow-large-position-x:0; + --bpk-private-shadow-large-position-y:0.25rem; + --bpk-private-shadow-large-spread:0; + --bpk-private-shadow-small-blur:0.1875rem; + --bpk-private-shadow-small-color:rgba(22, 22, 22, 0.25); + --bpk-private-shadow-small-position-x:0; + --bpk-private-shadow-small-position-y:0.0625rem; + --bpk-private-shadow-small-spread:0; + --bpk-private-shadow-xl-blur:3.125rem; + --bpk-private-shadow-xl-color:rgba(22, 22, 22, 0.25); + --bpk-private-shadow-xl-position-x:0; + --bpk-private-shadow-xl-position-y:0.75rem; + --bpk-private-shadow-xl-spread:0; + --bpk-private-skeleton-on-dark:#243346; + --bpk-private-speech-bubble-colour-bg-contrast:#131d2b; + --bpk-private-speech-bubble-colour-bg-default:#131d2b; + --bpk-private-trip-advisor:#9ce6c0; + --bpk-core-accent:#84e9ff; + --bpk-core-eco:#0fa1a9; + --bpk-core-primary:#054184; + --bpk-other-line:rgba(255, 255, 255, 0.2); + --bpk-other-line-on-dark:rgba(255, 255, 255, 0.2); + --bpk-other-overlay:rgba(255, 255, 255, 0.8); + --bpk-other-scrim:rgba(0, 0, 0, 0.7); + --bpk-other-shadow:rgba(22, 22, 22, 0.25); + --bpk-status-danger-fill:#ffcadd; + --bpk-status-danger-spot:#ff649c; + --bpk-status-success-fill:#b1ffe7; + --bpk-status-success-spot:#62f1c6; + --bpk-status-warning-fill:#fbf1bb; + --bpk-status-warning-spot:#feeb87; + --bpk-surface-contrast:#010913; + --bpk-surface-default:#131d2b; + --bpk-surface-elevated:#243346; + --bpk-surface-hero:#010913; + --bpk-surface-highlight:#243346; + --bpk-surface-low-contrast:#243346; + --bpk-surface-subtle:#243346; + --bpk-surface-tint:rgba(255, 255, 255, 0.1); + --bpk-surface-promo:#243346; + --bpk-text-disabled:rgba(255, 255, 255, 0.2); + --bpk-text-disabled-on-dark:rgba(255, 255, 255, 0.5); + --bpk-text-error:#ff649c; + --bpk-text-inverse:#010913; + --bpk-text-on-dark:#ffffff; + --bpk-text-on-light:#010913; + --bpk-text-primary:#ffffff; + --bpk-text-secondary:#bdc4cb; + --bpk-text-success:#62f1c6; + --bpk-text-deprecated-link:#84e9ff; + --bpk-text-hero:#010913; + --bpk-title:true; + --bpk-typography-family-sans-serif:'Skyscanner Relative'; + --bpk-typography-family-serif:Larken; + --bpk-typography-kerning-default:0; + --bpk-typography-kerning-loose:0; + --bpk-typography-kerning-tight:0; + --bpk-typography-style-body:400; + --bpk-typography-style-headline:700; + --bpk-typography-style-hero:900; + --bpk-typography-style-label:700; + --bpk-typography-style-subhead:300; +} + diff --git a/packages/bpk-stylesheets/index.js b/packages/bpk-stylesheets/index.js index 5654a2d7a0..651dd24aa2 100644 --- a/packages/bpk-stylesheets/index.js +++ b/packages/bpk-stylesheets/index.js @@ -17,6 +17,9 @@ */ import './index.scss'; +import './primitives.css'; +import './theme-backpack-light.css'; +import './theme-backpack-dark.css'; (() => { if (typeof document === 'undefined') { diff --git a/packages/bpk-stylesheets/index.scss b/packages/bpk-stylesheets/index.scss index 96906be4d2..eaa5c212e1 100644 --- a/packages/bpk-stylesheets/index.scss +++ b/packages/bpk-stylesheets/index.scss @@ -19,9 +19,6 @@ @use '../bpk-mixins/tokens'; @use '../bpk-mixins/utils'; @use './normalize'; -@use './primitives.css'; -@use './theme-backpack-light.css'; -@use './theme-backpack-dark.css'; // stylelint-disable-next-line selector-max-type html { diff --git a/packages/bpk-stylesheets/webpack.config.babel.js b/packages/bpk-stylesheets/webpack.config.babel.js index 999f4fc7e3..53136c8115 100644 --- a/packages/bpk-stylesheets/webpack.config.babel.js +++ b/packages/bpk-stylesheets/webpack.config.babel.js @@ -19,6 +19,7 @@ const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const postcssDiscardComments = require('postcss-discard-comments'); const WrapperPlugin = require('wrapper-webpack-plugin'); const postCssPlugins = require('../../scripts/webpack/postCssPlugins'); @@ -114,7 +115,7 @@ module.exports = { loader: 'postcss-loader', options: { postcssOptions: { - plugins: [postCssPlugins], + plugins: [...postCssPlugins(), postcssDiscardComments()], }, }, }, From ac5162e4e5c7f4828f0ffa148a21b131bb6e6aff Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Tue, 19 May 2026 11:53:16 +0800 Subject: [PATCH 07/10] [CLOV-1412][bpk-stylesheets] Replace postcss-discard-comments with inline PostCSS plugin --- package-lock.json | 68 +++++++------------ package.json | 1 - packages/bpk-stylesheets/README.md | 2 +- .../bpk-stylesheets/webpack.config.babel.js | 14 +++- 4 files changed, 37 insertions(+), 48 deletions(-) diff --git a/package-lock.json b/package-lock.json index 843f4dccc5..fcef64f6db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,7 +70,6 @@ "lodash": "^4.18.1", "mini-css-extract-plugin": "^2.9.0", "npm-run-all": "^4.1.5", - "postcss-discard-comments": "^8.0.0", "postcss-flexbugs-fixes": "^5.0.2", "postcss-loader": "^8.2.0", "prop-types": "^15.7.2", @@ -9716,16 +9715,13 @@ ] }, "node_modules/baseline-browser-mapping": { - "version": "2.10.31", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.31.tgz", - "integrity": "sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==", + "version": "2.8.32", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz", + "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" + "baseline-browser-mapping": "dist/cli.js" } }, "node_modules/basic-ftp": { @@ -9917,9 +9913,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", + "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", "dev": true, "funding": [ { @@ -9937,11 +9933,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", - "update-browserslist-db": "^1.2.3" + "baseline-browser-mapping": "^2.8.25", + "caniuse-lite": "^1.0.30001754", + "electron-to-chromium": "^1.5.249", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" @@ -10199,9 +10195,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001793", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", - "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", + "version": "1.0.30001757", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz", + "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==", "dev": true, "funding": [ { @@ -12245,9 +12241,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.357", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.357.tgz", - "integrity": "sha512-NHlTIQDK8fmVwHwuIzmXYEJ1Ewq3D9wDNc0cWXxDGysP6Pb21giwGNkxiTifyKy/4SoPuN5l6GLP1W9Sv7zB2g==", + "version": "1.5.262", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz", + "integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==", "dev": true, "license": "ISC" }, @@ -21549,9 +21545,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.44", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", - "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, @@ -23011,22 +23007,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-discard-comments": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-8.0.0.tgz", - "integrity": "sha512-zGpvVLj2sbagEp+BTVETvAfkZdGVA6rALNujDK/WTIjdf1/rQOxOG8BBzkI8UQgnw8SkL6xffAfbtGMHFypadw==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^7.1.1" - }, - "engines": { - "node": "^22.11.0 || ^24.11.0 || >=26.0" - }, - "peerDependencies": { - "postcss": "^8.5.14" - } - }, "node_modules/postcss-flexbugs-fixes": { "version": "5.0.2", "dev": true, @@ -29298,9 +29278,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index cd320bb871..efa1dfb7cf 100644 --- a/package.json +++ b/package.json @@ -174,7 +174,6 @@ "lodash": "^4.18.1", "mini-css-extract-plugin": "^2.9.0", "npm-run-all": "^4.1.5", - "postcss-discard-comments": "^8.0.0", "postcss-flexbugs-fixes": "^5.0.2", "postcss-loader": "^8.2.0", "prop-types": "^15.7.2", diff --git a/packages/bpk-stylesheets/README.md b/packages/bpk-stylesheets/README.md index ec64ba33fb..6902b4b300 100644 --- a/packages/bpk-stylesheets/README.md +++ b/packages/bpk-stylesheets/README.md @@ -159,6 +159,6 @@ To build the `base.css` file run `npm run build:stylesheets` in the root folder. The webpack build depends on two sets of files that are gitignored and copied in at build time: - `normalize.scss` — copied from `node_modules/normalize.css/` by `npm run build:copy-normal_css`. Imported via `@use` in `index.scss`. -- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run copy:token-css`. Imported in `index.js` so they reach `base.css` through webpack's CSS pipeline (which strips their license headers via `postcss-discard-comments`); `index.scss` does not depend on them, so `build:sass` does not need them either. +- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run copy:token-css`. Imported in `index.js` so they reach `base.css` through webpack's CSS pipeline (which strips their license headers via an inline PostCSS plugin in `webpack.config.babel.js`); `index.scss` does not depend on them, so `build:sass` does not need them either. `build:stylesheets` invokes `copy:token-css` automatically, so `npm run build` and `npm run build:stylesheets` both work standalone (including after a fresh checkout or after regenerating tokens with `npm run tokens:sync`). For `build:sass`, run `npm run build:copy-normal_css` first if `normalize.scss` isn't already vendored. diff --git a/packages/bpk-stylesheets/webpack.config.babel.js b/packages/bpk-stylesheets/webpack.config.babel.js index 53136c8115..e6223de076 100644 --- a/packages/bpk-stylesheets/webpack.config.babel.js +++ b/packages/bpk-stylesheets/webpack.config.babel.js @@ -19,11 +19,21 @@ const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const postcssDiscardComments = require('postcss-discard-comments'); const WrapperPlugin = require('wrapper-webpack-plugin'); const postCssPlugins = require('../../scripts/webpack/postCssPlugins'); +// Inline postcss plugin: strips license/comment blocks from the +// vendored token CSS files so they don't pile up inside base.css. +// WrapperPlugin re-adds the single Backpack license header. +const stripComments = { + postcssPlugin: 'strip-comments', + Once(root) { + root.walkComments((c) => c.remove()); + }, +}; +stripComments.postcss = true; + const TEXT = ` Backpack - Skyscanner's Design System @@ -115,7 +125,7 @@ module.exports = { loader: 'postcss-loader', options: { postcssOptions: { - plugins: [...postCssPlugins(), postcssDiscardComments()], + plugins: [...postCssPlugins(), stripComments], }, }, }, From 0d116b7f50b63fbbfcb0bf4f6b7f8ae906c7bdba Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Tue, 19 May 2026 12:58:38 +0800 Subject: [PATCH 08/10] [CLOV-1412] Add dev-release workflow for consumer testing Cherry-picked from #4441 to enable publishing dev versions of this branch for consumer-side verification. Co-Authored-By: Claude Opus 4.7 --- .../actions/pr-security-validation/action.yml | 148 +++++++++++++ .github/actions/upsert-pr-comment/action.yml | 59 +++++ .github/workflows/dev-release.yml | 204 ++++++++++++++++++ 3 files changed, 411 insertions(+) create mode 100644 .github/actions/pr-security-validation/action.yml create mode 100644 .github/actions/upsert-pr-comment/action.yml create mode 100644 .github/workflows/dev-release.yml diff --git a/.github/actions/pr-security-validation/action.yml b/.github/actions/pr-security-validation/action.yml new file mode 100644 index 0000000000..e598b0ba3a --- /dev/null +++ b/.github/actions/pr-security-validation/action.yml @@ -0,0 +1,148 @@ +name: PR Security Validation +description: Validates PR security before executing code with access to secrets + +inputs: + pr_number: + description: PR number to validate + required: true + github_token: + description: GitHub token with repo read permission + required: false + default: ${{ github.token }} + triggered_by: + description: User who triggered the workflow + required: false + default: ${{ github.actor }} + +outputs: + pr_number: + description: Validated PR number + value: ${{ steps.get-pr-data.outputs.pr_number }} + pr_sha: + description: PR commit SHA + value: ${{ steps.get-pr-data.outputs.pr_sha }} + pr_ref: + description: PR branch reference + value: ${{ steps.get-pr-data.outputs.pr_ref }} + pr_author: + description: PR author username + value: ${{ steps.get-pr-data.outputs.pr_author }} + +runs: + using: composite + steps: + - name: Get PR data + id: get-pr-data + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + PR_NUMBER: ${{ inputs.pr_number }} + with: + github-token: ${{ inputs.github_token }} + script: | + const prNumber = parseInt(process.env.PR_NUMBER, 10); + + try { + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: prNumber, + }); + + const prData = { + pr_number: pr.number, + pr_sha: pr.head.sha, + pr_ref: pr.head.ref, + head_repo: pr.head.repo?.full_name || 'null', + base_repo: pr.base.repo?.full_name || 'null', + pr_state: pr.state, + pr_author: pr.user.login, + }; + + if (!prData.pr_number || !prData.pr_sha) { + throw new Error(`PR data is incomplete (number: ${prData.pr_number}, sha: ${prData.pr_sha})`); + } + + core.setOutput('pr_number', prData.pr_number); + core.setOutput('pr_sha', prData.pr_sha); + core.setOutput('pr_ref', prData.pr_ref); + core.setOutput('head_repo', prData.head_repo); + core.setOutput('base_repo', prData.base_repo); + core.setOutput('pr_state', prData.pr_state); + core.setOutput('pr_author', prData.pr_author); + + core.info(`PR #${prData.pr_number}`); + core.info(`State: ${prData.pr_state}`); + core.info(`Author: ${prData.pr_author}`); + core.info(`Commit: ${prData.pr_sha}`); + core.info(`Head repo: ${prData.head_repo}`); + core.info(`Base repo: ${prData.base_repo}`); + } catch (error) { + core.setFailed(`Failed to fetch PR data: ${error.message}`); + } + + - name: Validate PR and check for forks + shell: bash + env: + HEAD_REPO: ${{ steps.get-pr-data.outputs.head_repo }} + BASE_REPO: ${{ steps.get-pr-data.outputs.base_repo }} + PR_STATE: ${{ steps.get-pr-data.outputs.pr_state }} + run: | + echo "Running security checks..." + + if [ "$PR_STATE" != "open" ]; then + echo "::error::PR is not open (state: $PR_STATE)" + exit 1 + fi + + if [ -z "$HEAD_REPO" ] || [ "$HEAD_REPO" = "null" ]; then + echo "::error::Cannot determine head repository. Rejecting as a security precaution." + exit 1 + fi + + if [ -z "$BASE_REPO" ] || [ "$BASE_REPO" = "null" ]; then + echo "::error::Cannot determine base repository. Rejecting as a security precaution." + exit 1 + fi + + if [ "$HEAD_REPO" != "$BASE_REPO" ]; then + echo "::error::Dev releases are not permitted from forked repositories." + echo "" + echo "Head repo: $HEAD_REPO" + echo "Base repo: $BASE_REPO" + echo "" + echo "Create a branch directly in the main repository instead of using a fork." + exit 1 + fi + + echo "PR is from the same repository" + + - name: Check user authorisation + id: check-authorisation + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + TRIGGERED_BY: ${{ inputs.triggered_by }} + with: + github-token: ${{ inputs.github_token }} + script: | + const triggeredBy = process.env.TRIGGERED_BY; + core.info(`Checking permission for user: ${triggeredBy}`); + + try { + const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: triggeredBy, + }); + + const userPermission = permission.permission; + core.info(`User permission: ${userPermission}`); + + if (!userPermission || userPermission === 'none' || userPermission === 'read') { + core.setFailed(`User ${triggeredBy} does not have write access to this repository (permission: ${userPermission}).`); + return; + } + + core.info(`User is authorised (permission: ${userPermission})`); + } catch (error) { + core.setFailed(`Unable to determine user permission: ${error.message}`); + } diff --git a/.github/actions/upsert-pr-comment/action.yml b/.github/actions/upsert-pr-comment/action.yml new file mode 100644 index 0000000000..37f58250bf --- /dev/null +++ b/.github/actions/upsert-pr-comment/action.yml @@ -0,0 +1,59 @@ +name: Upsert PR Comment +description: Create or update a comment on a pull request, identified by a unique marker + +inputs: + pr_number: + description: The pull request number to comment on + required: true + marker: + description: HTML comment marker used to identify and update existing comments + required: true + body: + description: Full comment body (should include the marker) + required: true + github_token: + description: GitHub token for API authentication + required: false + default: ${{ github.token }} + +runs: + using: composite + steps: + - name: Create or update PR comment + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + PR_NUMBER: ${{ inputs.pr_number }} + COMMENT_MARKER: ${{ inputs.marker }} + COMMENT_BODY: ${{ inputs.body }} + with: + github-token: ${{ inputs.github_token }} + script: | + const prNumber = Number(process.env.PR_NUMBER); + const marker = process.env.COMMENT_MARKER; + const body = process.env.COMMENT_BODY; + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + }); + + const existingComment = comments.find(comment => comment.body.includes(marker)); + + if (existingComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existingComment.id, + body, + }); + core.info(`Updated existing comment ${existingComment.id}`); + } else { + const { data: created } = await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body, + }); + core.info(`Created new comment ${created.id}`); + } diff --git a/.github/workflows/dev-release.yml b/.github/workflows/dev-release.yml new file mode 100644 index 0000000000..dca54f47c0 --- /dev/null +++ b/.github/workflows/dev-release.yml @@ -0,0 +1,204 @@ +name: Dev Release + +on: + pull_request: + types: [opened, synchronize, reopened] + workflow_dispatch: + inputs: + pr_number: + description: "Pull request number to publish a dev release from" + required: true + type: number + dry_run: + description: "Run the full build pipeline without publishing to npm" + required: false + type: boolean + default: false + +defaults: + run: + shell: bash -l {0} + +env: + CACHE_NAME: node-modules-cache + PR_COMMENT_MARKER: "" + PR_NUMBER: ${{ github.event.pull_request.number || inputs.pr_number }} + DRY_RUN: ${{ inputs.dry_run || false }} + +permissions: {} + +jobs: + SecurityCheck: + name: Validate PR and permissions + if: github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + outputs: + pr_sha: ${{ steps.validate.outputs.pr_sha }} + steps: + - name: Checkout for actions + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + sparse-checkout: .github/actions + + - name: Validate PR security + id: validate + uses: ./.github/actions/pr-security-validation + with: + pr_number: ${{ env.PR_NUMBER }} + + - name: Add or update failure comment on PR + if: failure() + uses: ./.github/actions/upsert-pr-comment + with: + pr_number: ${{ env.PR_NUMBER }} + marker: ${{ env.PR_COMMENT_MARKER }} + body: | + ${{ env.PR_COMMENT_MARKER }} + ### Dev Release Failed + + The dev release workflow failed a security check. See the [workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details. + + Triggered by @${{ github.actor }}. + + DevRelease: + name: Build and publish dev release + runs-on: ubuntu-latest + environment: Publishing + needs: [SecurityCheck] + if: always() && (needs.SecurityCheck.result == 'success' || needs.SecurityCheck.result == 'skipped') + permissions: + contents: read + outputs: + dev_version: ${{ steps.version.outputs.dev_version }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ needs.SecurityCheck.outputs.pr_sha || github.event.pull_request.head.sha }} + persist-credentials: false + fetch-depth: 0 + + - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version-file: ".nvmrc" + registry-url: 'https://registry.npmjs.org' + + - name: Cache npm dependencies + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + id: npm-cache + with: + path: | + node_modules/ + packages/node_modules/ + key: ${{ env.CACHE_NAME }}-${{ hashFiles('package-lock.json', 'packages/package-lock.json') }} + + - name: Install dependencies + if: ${{ steps.npm-cache.outputs.cache-hit != 'true' }} + run: npm ci + + - name: Determine dev version + id: version + run: | + BASE_VERSION=$(git describe --tags --abbrev=0 --exclude='*-*' HEAD) + DEV_VERSION="${BASE_VERSION}-dev-v${GITHUB_RUN_ID}.${GITHUB_RUN_ATTEMPT}" + echo "dev_version=${DEV_VERSION}" >> "$GITHUB_OUTPUT" + echo "Dev version: ${DEV_VERSION}" + + - name: Transpile + run: npm run transpile + + - name: Publish dev release to npm + if: ${{ env.DRY_RUN != 'true' }} + run: | + cd dist + npm version $DEV_VERSION --no-git-tag-version + npm publish --tag dev + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + DEV_VERSION: ${{ steps.version.outputs.dev_version }} + + ReportResults: + name: Report results on PR + runs-on: ubuntu-latest + needs: [SecurityCheck, DevRelease] + if: always() && github.event_name == 'workflow_dispatch' && needs.SecurityCheck.result == 'success' + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout for actions + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + sparse-checkout: .github/actions + + - name: Build comment body + id: build-body + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + DEV_VERSION: ${{ needs.DevRelease.outputs.dev_version }} + PR_SHA: ${{ needs.SecurityCheck.outputs.pr_sha }} + BUILD_RESULT: ${{ needs.DevRelease.result }} + DRY_RUN: ${{ env.DRY_RUN }} + RUN_ID: ${{ github.run_id }} + REPO: ${{ github.repository }} + PR_COMMENT_MARKER: ${{ env.PR_COMMENT_MARKER }} + with: + script: | + const marker = process.env.PR_COMMENT_MARKER; + let body; + + if (process.env.BUILD_RESULT === 'success' && process.env.DRY_RUN === 'true') { + body = [ + marker, + `### Dev Release Dry Run Successful`, + '', + `**Version (not published):** \`${process.env.DEV_VERSION}\``, + '', + 'The build and transpilation completed successfully. No package was published to npm.', + '', + 'Run the workflow again without dry run to publish this version.', + '', + `Triggered from commit ${process.env.PR_SHA} by @${context.actor}.`, + ].join('\n'); + } else if (process.env.BUILD_RESULT === 'success') { + body = [ + marker, + `### Dev Release Published`, + '', + `**Version:** \`${process.env.DEV_VERSION}\``, + '', + '**Install with:**', + '```', + `npm install @skyscanner/backpack-web@${process.env.DEV_VERSION}`, + '```', + '', + `You can also use the dev tag to install the latest dev release:`, + '```', + 'npm install @skyscanner/backpack-web@dev', + '```', + '', + `Published from commit ${process.env.PR_SHA} by @${context.actor}.`, + ].join('\n'); + } else { + body = [ + marker, + `### Dev Release Failed`, + '', + `The dev release workflow failed. See the [workflow run](https://github.com/${process.env.REPO}/actions/runs/${process.env.RUN_ID}) for details.`, + '', + `Triggered by @${context.actor}.`, + ].join('\n'); + } + + core.setOutput('body', body); + + - name: Update PR comment with results + uses: ./.github/actions/upsert-pr-comment + with: + pr_number: ${{ env.PR_NUMBER }} + marker: ${{ env.PR_COMMENT_MARKER }} + body: ${{ steps.build-body.outputs.body }} From a8cf78b05d719f4e1dd189654bdc160baaf17875 Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Tue, 19 May 2026 16:45:32 +0800 Subject: [PATCH 09/10] [CLOV-1412][bpk-stylesheets] Add css-minimizer-webpack-plugin Replaces the inline strip-comments PostCSS plugin with css-minimizer-webpack-plugin (cssnano default preset). cssnano strips comments and minifies the output, shrinking base.css. The Backpack license header added by wrapper-webpack-plugin is now emitted as a `/*!` important comment so cssnano preserves it. base.css 22,083 -> 19,876 bytes raw, gzip 4,023 -> 3,915, brotli 3,235 -> 3,174. Co-Authored-By: Claude Opus 4.7 --- package-lock.json | 867 +++++++++++++++++- package.json | 1 + .../src/bpk-stylesheets/README.md | 2 +- .../backpack-web/src/bpk-stylesheets/base.css | 365 +------- .../bpk-stylesheets/webpack.config.babel.js | 22 +- 5 files changed, 856 insertions(+), 401 deletions(-) diff --git a/package-lock.json b/package-lock.json index fcef64f6db..346acf292d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,6 +52,7 @@ "babel-plugin-require-context-hook": "^1.0.0", "core-js": "^3.47.0", "css-loader": "^7.1.2", + "css-minimizer-webpack-plugin": "^8.0.0", "d3-scale": "^4.0.2", "danger": "^13.0.4", "danger-plugin-toolbox": "^3.1.2", @@ -2522,6 +2523,13 @@ "@keyv/serialize": "^1.1.1" } }, + "node_modules/@colordx/core": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@colordx/core/-/core-5.4.3.tgz", + "integrity": "sha512-kIxYSfA5T8HXjav55UaaH/o/cKivF6jCCGIb8eqtcsfI46wsvlSiT8jMDyrl779qLec3c2c2oHBZo4oAhvbjrQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@csstools/color-helpers": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", @@ -9715,13 +9723,16 @@ ] }, "node_modules/baseline-browser-mapping": { - "version": "2.8.32", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz", - "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==", + "version": "2.10.31", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.31.tgz", + "integrity": "sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/basic-ftp": { @@ -9913,9 +9924,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, "funding": [ { @@ -9933,11 +9944,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -10194,10 +10205,23 @@ "node": ">=6" } }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, "node_modules/caniuse-lite": { - "version": "1.0.30001757", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz", - "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==", + "version": "1.0.30001793", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001793.tgz", + "integrity": "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==", "dev": true, "funding": [ { @@ -11093,6 +11117,19 @@ "node": ">=8" } }, + "node_modules/css-declaration-sorter": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.4.0.tgz", + "integrity": "sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, "node_modules/css-functions-list": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", @@ -11152,6 +11189,81 @@ "node": ">=10" } }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-8.0.0.tgz", + "integrity": "sha512-9bEpzHs8gEq6/cbEj418jXL/YWjBUD2YTLLk905Npt2JODqnRITin0+So5Vx4Dp5vyi2Lpt9pp2QHzQ7fdxNrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "cssnano": "^7.0.4", + "jest-worker": "^30.0.5", + "postcss": "^8.4.40", + "schema-utils": "^4.2.0", + "serialize-javascript": "^7.0.3" + }, + "engines": { + "node": ">= 20.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/serialize-javascript": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/css-select": { "version": "4.3.0", "dev": true, @@ -11251,6 +11363,85 @@ "node": ">=4" } }, + "node_modules/cssnano": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.9.tgz", + "integrity": "sha512-uPR75+5Dk/WJ/YSPR1/YDHdwMM9c5FsaARljfKWgeCKLKOtJ0we21xy/RcCjn53fZnD/f6yYEIZ8pu18+GnbNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^7.0.17", + "lilconfig": "^3.1.3" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano-preset-default": { + "version": "7.0.17", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.17.tgz", + "integrity": "sha512-11qO63A+czwguQFJCaTdICvbaxn0pJzz/XghLlv+OT7WyToDxAMR0Xb3/26/l0y0hQJywwNbj/SLSQlGBHE1OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.3", + "postcss-calc": "^10.1.1", + "postcss-colormin": "^7.0.10", + "postcss-convert-values": "^7.0.12", + "postcss-discard-comments": "^7.0.8", + "postcss-discard-duplicates": "^7.0.4", + "postcss-discard-empty": "^7.0.3", + "postcss-discard-overridden": "^7.0.3", + "postcss-merge-longhand": "^7.0.7", + "postcss-merge-rules": "^7.0.11", + "postcss-minify-font-values": "^7.0.3", + "postcss-minify-gradients": "^7.0.5", + "postcss-minify-params": "^7.0.9", + "postcss-minify-selectors": "^7.1.2", + "postcss-normalize-charset": "^7.0.3", + "postcss-normalize-display-values": "^7.0.3", + "postcss-normalize-positions": "^7.0.4", + "postcss-normalize-repeat-style": "^7.0.4", + "postcss-normalize-string": "^7.0.3", + "postcss-normalize-timing-functions": "^7.0.3", + "postcss-normalize-unicode": "^7.0.9", + "postcss-normalize-url": "^7.0.3", + "postcss-normalize-whitespace": "^7.0.3", + "postcss-ordered-values": "^7.0.4", + "postcss-reduce-initial": "^7.0.9", + "postcss-reduce-transforms": "^7.0.3", + "postcss-svgo": "^7.1.3", + "postcss-unique-selectors": "^7.0.7" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano-utils": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.3.tgz", + "integrity": "sha512-ynIREMICLxkxm7e9bCR9sh75s4Q5drICi0ua1yxo5jH2XPBqSKkl4dOh4EbFqtUmnTMhRffHgYL0EKKkMjtJTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, "node_modules/csso": { "version": "4.2.0", "dev": true, @@ -12241,9 +12432,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.262", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz", - "integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==", + "version": "1.5.359", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.359.tgz", + "integrity": "sha512-8lPELWuYZIWk7NDvCNthtmMw/7Q5Wu25NpM4djFMHBmk8DubPAtL4YTOp7ou0e7HyJtwkVlWv8XMLURnrtgJQw==", "dev": true, "license": "ISC" }, @@ -20208,6 +20399,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "dev": true, @@ -21545,9 +21749,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.44", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.44.tgz", + "integrity": "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==", "dev": true, "license": "MIT" }, @@ -23007,6 +23211,114 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-calc": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.1.1.tgz", + "integrity": "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12 || ^20.9 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.38" + } + }, + "node_modules/postcss-colormin": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.10.tgz", + "integrity": "sha512-yFr6JezOolHLta/buLE71VKPh2mXursp4saVe98/ol8ZnEWhL+racShqPKlvd/DKWLre/39B6HhcMXf7RZ3hxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colordx/core": "^5.4.3", + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-convert-values": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.12.tgz", + "integrity": "sha512-xurKu5qqk4viR3Cp3p4xBR4KfnZm4w4ys6+UBwBmeuBSNkH7+DtLnYOYnOffgtE4yx8sH9S1VZ6RAAvROXzP2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-discard-comments": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.8.tgz", + "integrity": "sha512-CvvS5S9WrXblFXCEJ9nVo+4z+eA7zSC7Z88V1HEJuwlQhlFnYTIjg1xJY+BCUiG2bvICap2tXii4mP22BD108Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.4.tgz", + "integrity": "sha512-VBNn1+EuMZkeGVVtz0gRfbNGtx9IFgAsAV+E2pHtXPrp4qfGBkhTIiAuE/wrb+Y6Pakg9NewAlfTpYIFAWODtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-discard-empty": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.3.tgz", + "integrity": "sha512-M2pyjQCU+/7cMHVtL6bKTHjv0lZnPLMpicgr67Dlth7AbuV9gjVTtUqaRwn6Pp6BwSDspUzhz8SaUrRykJU5Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.3.tgz", + "integrity": "sha512-aNovXo9UsZuRNLzHJtp13lHIvinDPfiXBPePpXkSjCbgp++iU2FqE+YxvjIsg6EdyPZsASFbfu+JcBFVsErXIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, "node_modules/postcss-flexbugs-fixes": { "version": "5.0.2", "dev": true, @@ -23112,6 +23424,113 @@ "dev": true, "license": "MIT" }, + "node_modules/postcss-merge-longhand": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.7.tgz", + "integrity": "sha512-b3mfYUxR388u5Pt0HPcVIUtUDn/k15UfTY9M+ORW+meCR6JLNxoZffiYvXyOYQoRYQNZyX/UFkMCM/mNHxe1qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^7.0.11" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-merge-rules": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.11.tgz", + "integrity": "sha512-SJUPM18g2BmPhf8BVlbwqWz4aK3pLu6u6xjfwEzra7xL6IBR10sUaiB++EzqcVfadPHrKBSMlNdP+XieykhI+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^5.0.3", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.3.tgz", + "integrity": "sha512-yilG/VOaNI74IylQvAQQxm3/wZVBkXyYUqNUAdxqwtbWUXPsbK1q8Ms0mL83v+f8YicgcyfYCRZtWACUdYajpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.5.tgz", + "integrity": "sha512-YraROyQRg3BI1+Hg8E05B/JPdnTm8EDSVu4P2BxdM+CRiOyfmou809+chGIqo6fQqwjPGQ947nbGncSjmTU1WQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colordx/core": "^5.4.3", + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-minify-params": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.9.tgz", + "integrity": "sha512-R8itbB8BhlpoYyBm1ou0dD+vJnQ3F6adQipR4UnkCHUwlo+S9WXJaDRg1RHjC8YVAtIdrQzSWvJl40HnGDTKjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.1.2.tgz", + "integrity": "sha512-aQtrEWKwqafNlExcKHQvPGsXR2+vlUqqJtf5XsCQcgsSb5PL4wlujWBYDJuWsP4UnQX1YHDHU8qRlD+1PzTQ+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1", + "caniuse-api": "^3.0.0", + "cssesc": "^3.0.0", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", @@ -23173,6 +23592,198 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-normalize-charset": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.3.tgz", + "integrity": "sha512-NoBfZu8PR4c2NlmjvrqQTzCzLY79hwcSRgNQ3ZiNK0ABzf9kYKloE/jNj+/8GQY1wsm8pRRgANk6ydLH8cwo0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.3.tgz", + "integrity": "sha512-ldsCX0QIt05pKIOobZtVQ48wXJecr+czw4+e1/YjVhLMqslShgpVxgPtI2CefURR8oyVoYaU/l829MMwExDMLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.4.tgz", + "integrity": "sha512-VEvlpeGd3Ju1Hqa/oN4jaP3+ms4laYwkEL9N9u+B6k54PZjXbW1n6wI+aVprf1BQXlCYpS5+1pl/7/vHiKgARg==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.4.tgz", + "integrity": "sha512-6mPKlY/8cSaDHxX502wERADarJsccwlky6yIrOapHH2ZgfoKAV94SbiTKfKEs4EEpdazuc3J72WsqeYk7hp9+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-normalize-string": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.3.tgz", + "integrity": "sha512-HnEQPUchi1eznmDKEYrKUTqrprEq97SrpUYClgUkv7V2zRODD9DFoUsYU+m9ZOetmD5ku7fEMZB/lwy8IT6xVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.3.tgz", + "integrity": "sha512-zmEzHdvpZBZu0OKlbJSfgASQvaayyAoVuWtvyr34IJ/LyS+DaOKvvR3EvFJ9RWWtNIx+CMvO125OVophaxNYew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.9.tgz", + "integrity": "sha512-DRAdWfeh/TjmhLJsw91vdiWCnUod9iwvM7xyS02/nF/sLsCR3A8l3pztrSUrWG8DSBqfX7yEk9FM0USaVJ2mSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-normalize-url": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.3.tgz", + "integrity": "sha512-CL93wmloq5qsffmFv+bw24MIRbmhHrp53qoh1LDAb/5TtjWEXI/np4xcP/Gw9oWCb2XyWnqHYLDUwiKRoJBA1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.3.tgz", + "integrity": "sha512-FdHjjn+Ht5Z2ZRjNOmeCbNq6lq09sUYKpmlF/Aq0XjVNSLTL6fmHlA/3swN2wP2caY9GV/tjSDcIIyS7aN7W0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-ordered-values": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.4.tgz", + "integrity": "sha512-nubSi49hDHQk4E8KIj+IbLY8Bg+8OcSUEhgyolgM+atnOvXjV7EjaR6bac4YGZoFyPa9mWoAF3EaYbWdFkKqVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.9.tgz", + "integrity": "sha512-ztTNPdIxXTxtBcG03E9u8v44M4ElXbMIRT7pf2onlquGula0Y83nKKxqM22FA/hMgkfCjN7ohevkVlaNwI8iOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.3.tgz", + "integrity": "sha512-FXsnN9ZwcZTT8Yf8cAHA8qIGUXcX6WfLd9JoYhrdDfmvsVhhfqkkv7m4AC3rwFOfz+GzkUa87OCKF9dUcicd+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, "node_modules/postcss-resolve-nested-selector": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", @@ -23258,6 +23869,197 @@ "postcss": "^8.4.20" } }, + "node_modules/postcss-svgo": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.1.3.tgz", + "integrity": "sha512-2QfoFOYMcj8lwcVEf9WeTlkVIAm7u2QvOEhMzkQU3KUhhGX/l8hVV9EtjMv4iq3E9iI3OeeMN0YoMLbGusuigw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^4.0.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/postcss-svgo/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/postcss-svgo/node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/postcss-svgo/node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/postcss-svgo/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/postcss-svgo/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/postcss-svgo/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/postcss-svgo/node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.7.tgz", + "integrity": "sha512-d+sCkaRnSefghOUdH8CMJZV9yUQhj2ojpe8Nw/lA+LV1UOfeleGkLTl6XdCFFSai9UJ+DJPb69FFuqthXYsY8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", "dev": true, @@ -26698,6 +27500,23 @@ "webpack": "^5.27.0" } }, + "node_modules/stylehacks": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.11.tgz", + "integrity": "sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, "node_modules/stylelint": { "version": "16.26.1", "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.26.1.tgz", @@ -29278,9 +30097,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index f79e9fc997..9d8fddd88d 100644 --- a/package.json +++ b/package.json @@ -156,6 +156,7 @@ "babel-plugin-require-context-hook": "^1.0.0", "core-js": "^3.47.0", "css-loader": "^7.1.2", + "css-minimizer-webpack-plugin": "^8.0.0", "d3-scale": "^4.0.2", "danger": "^13.0.4", "danger-plugin-toolbox": "^3.1.2", diff --git a/packages/backpack-web/src/bpk-stylesheets/README.md b/packages/backpack-web/src/bpk-stylesheets/README.md index 6902b4b300..081cf13c7e 100644 --- a/packages/backpack-web/src/bpk-stylesheets/README.md +++ b/packages/backpack-web/src/bpk-stylesheets/README.md @@ -159,6 +159,6 @@ To build the `base.css` file run `npm run build:stylesheets` in the root folder. The webpack build depends on two sets of files that are gitignored and copied in at build time: - `normalize.scss` — copied from `node_modules/normalize.css/` by `npm run build:copy-normal_css`. Imported via `@use` in `index.scss`. -- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run copy:token-css`. Imported in `index.js` so they reach `base.css` through webpack's CSS pipeline (which strips their license headers via an inline PostCSS plugin in `webpack.config.babel.js`); `index.scss` does not depend on them, so `build:sass` does not need them either. +- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run copy:token-css`. Imported in `index.js` so they reach `base.css` through webpack's CSS pipeline; `index.scss` does not depend on them, so `build:sass` does not need them either. The CSS pipeline runs `css-minimizer-webpack-plugin` (cssnano) which minifies and strips the per-file license blocks; the single Backpack license header is re-added by `wrapper-webpack-plugin` as a `/*!` important comment so cssnano preserves it. `build:stylesheets` invokes `copy:token-css` automatically, so `npm run build` and `npm run build:stylesheets` both work standalone (including after a fresh checkout or after regenerating tokens with `npm run tokens:sync`). For `build:sass`, run `npm run build:copy-normal_css` first if `normalize.scss` isn't already vendored. diff --git a/packages/backpack-web/src/bpk-stylesheets/base.css b/packages/backpack-web/src/bpk-stylesheets/base.css index 4ff13a9f5a..8d8991bccd 100644 --- a/packages/backpack-web/src/bpk-stylesheets/base.css +++ b/packages/backpack-web/src/bpk-stylesheets/base.css @@ -1,4 +1,4 @@ -/* +/*! * * Backpack - Skyscanner's Design System * @@ -16,365 +16,4 @@ * See the License for the specific language governing permissions and * limitations under the License. * - *//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:rgba(0,0,0,0);-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}html{font-size:100%;box-sizing:border-box}*{box-sizing:inherit}*::before,*::after{box-sizing:inherit}body{color:#161616;font-family:var(--bpk-base-font-stack, "Skyscanner Relative", -apple-system, BlinkMacSystemFont, "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif);font-size:1rem;line-height:1.3rem}body.scaffold-font-size{font-size:13px}body.enable-font-smoothing{-webkit-font-smoothing:antialiased}:focus-visible,button:focus-visible,[type=button]:focus-visible,[type=reset]:focus-visible,[type=submit]:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.hidden,.hide{display:none !important}.visuallyhidden,.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;white-space:nowrap;overflow:hidden;clip:rect(0 0 0 0)}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus,.visually-hidden.focusable:active,.visually-hidden.focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.invisible{visibility:hidden}.clearfix::before,.clearfix::after{content:"";display:table}.clearfix::after{clear:both} -:root{ - --bpk-radius-none:0; - --bpk-radius-full:6.25rem; - --bpk-radius-lg:1.5rem; - --bpk-radius-md:0.75rem; - --bpk-radius-nav-tabs:1.125rem; - --bpk-radius-sm:0.5rem; - --bpk-radius-xs:0.25rem; - --bpk-spacing-base:1rem; - --bpk-spacing-lg:1.5rem; - --bpk-spacing-md:0.5rem; - --bpk-spacing-none:0; - --bpk-spacing-sm:0.25rem; - --bpk-spacing-xl:2rem; - --bpk-spacing-xs:0.125rem; - --bpk-spacing-xxl:2.5rem; - --bpk-spacing-xxs:0.0625rem; - --bpk-spacing-xxxl:4rem; - --bpk-spacing-xxxxl:6rem; -} - -:root{ - --bpk-canvas-contrast:#eff3f8; - --bpk-canvas-default:#ffffff; - --bpk-private-badge-colour-bg-default:#eff3f8; - --bpk-private-badge-colour-bg-inverse:#ffffff; - --bpk-private-badge-colour-bg-outline:rgba(255, 255, 255, 0); - --bpk-private-badge-colour-bg-subtle:#eff3f8; - --bpk-private-badge-colour-stroke-outline:#ffffff; - --bpk-private-badge-dimension-padding-horizontal-default:0.5rem; - --bpk-private-badge-dimension-padding-horizontal-subtle:0.5rem; - --bpk-private-badge-typography-tmp-badge-label:0.875rem; - --bpk-private-badge-typography-tmp-badge-line-height:0; - --bpk-private-button-colour-bg-destructive:#e0e4e9; - --bpk-private-button-colour-bg-destructive-pressed:#e70866; - --bpk-private-button-colour-bg-disabled:#e0e4e9; - --bpk-private-button-colour-bg-feature-pressed:#024daf; - --bpk-private-button-colour-bg-featured:#0062e3; - --bpk-private-button-colour-bg-footer:rgba(255, 255, 255, 0); - --bpk-private-button-colour-bg-footer-pressed:rgba(255, 255, 255, 0); - --bpk-private-button-colour-bg-primary:#05203c; - --bpk-private-button-colour-bg-primary-on-dark:#ffffff; - --bpk-private-button-colour-bg-primary-on-dark-pressed:#c1c7cf; - --bpk-private-button-colour-bg-primary-on-light:#ffffff; - --bpk-private-button-colour-bg-primary-on-light-pressed:#154679; - --bpk-private-button-colour-bg-secondary:#e0e4e9; - --bpk-private-button-colour-bg-secondary-pressed:#c1c7cf; - --bpk-private-button-colour-bg-secondary-on-contrast:#e0e4e9; - --bpk-private-button-colour-bg-secondary-on-contrast-pressed:#c1c7cf; - --bpk-private-button-colour-bg-secondary-on-dark:rgba(255, 255, 255, 0.1); - --bpk-private-button-colour-bg-secondary-on-dark-disabled:#0b121d; - --bpk-private-button-colour-bg-secondary-on-dark-pressed:#04182d; - --bpk-private-button-colour-text-disruptive:#e70866; - --bpk-private-button-colour-text-feature:#ffffff; - --bpk-private-button-colour-text-footer:rgba(255, 255, 255, 0); - --bpk-private-button-colour-text-link-on-dark:#ffffff; - --bpk-private-button-colour-text-secondary:#161616; - --bpk-private-button-dimension-radius:0.5rem; - --bpk-private-button-dimension-min-height-default:2.25rem; - --bpk-private-button-dimension-min-height-large:3rem; - --bpk-private-button-dimension-min-weight-large:3rem; - --bpk-private-button-dimension-padding-horizontal-default:1rem; - --bpk-private-button-dimension-padding-horizontal-large:1rem; - --bpk-private-button-typography-tmp-default-label:1rem; - --bpk-private-card-button-contained-fill:rgba(255, 255, 255, 0.8); - --bpk-private-carousel-trigger-bg-default:rgba(255, 255, 255, 0.5); - --bpk-private-carousel-trigger-bg-default-hover:rgba(255, 255, 255, 0.8); - --bpk-private-chip-group-filter-colour-bg-icon-hover-on-image:#eff3f8; - --bpk-private-chip-group-filter-colour-bg-icon-off-on-image:#ffffff; - --bpk-private-chip-group-filter-colour-bg-icon-on-default:#05203c; - --bpk-private-chip-group-filter-colour-bg-icon-on-on-dark:#ffffff; - --bpk-private-chip-group-filter-colour-bg-icon-on-on-image:#05203c; - --bpk-private-chip-group-filter-colour-stroke-icon-hover-default:#05203c; - --bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark:#ffffff; - --bpk-private-chip-group-filter-colour-stroke-icon-off-default:#c1c7cf; - --bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark:rgba(255, 255, 255, 0.5); - --bpk-private-chip-group-filter-dimensions-min-height:2.25rem; - --bpk-private-chip-colour-bg-default-dismissible-hover:#05203c; - --bpk-private-chip-colour-bg-default-on:#05203c; - --bpk-private-chip-colour-bg-disabled:#e0e4e9; - --bpk-private-chip-colour-bg-on-contrast-hover:#ffffff; - --bpk-private-chip-colour-bg-on-contrast-on:#05203c; - --bpk-private-chip-colour-bg-on-dark-dismissible-hover:#ffffff; - --bpk-private-chip-colour-bg-on-dark-hover:#ffffff; - --bpk-private-chip-colour-bg-on-dark-off:rgba(255, 255, 255, 0); - --bpk-private-chip-colour-bg-on-dark-on:#ffffff; - --bpk-private-chip-colour-bg-on-image-dismissible-hover:#05203c; - --bpk-private-chip-colour-bg-on-image-on:#eff3f8; - --bpk-private-chip-colour-border-default-dismissible-hover:rgba(255, 255, 255, 0); - --bpk-private-chip-colour-border-default-hover:#05203c; - --bpk-private-chip-colour-border-default-off:#c1c7cf; - --bpk-private-chip-colour-border-on-contrast-off:#ffffff; - --bpk-private-chip-colour-border-on-contrast-on:#05203c; - --bpk-private-chip-colour-border-on-dark-disimissible-hover:#ffffff; - --bpk-private-chip-colour-border-on-dark-hover:#ffffff; - --bpk-private-chip-colour-border-on-dark-off:rgba(255, 255, 255, 0.5); - --bpk-private-chip-colour-stroke-off-on-canvas-contrast-new:rgba(255, 255, 255, 0); - --bpk-private-chip-colour-text-default-dismissible-hover:#ffffff; - --bpk-private-chip-colour-text-dismissible-on-icon:rgba(255, 255, 255, 0.5); - --bpk-private-chip-colour-text-on:#ffffff; - --bpk-private-chip-colour-text-on-image:#ffffff; - --bpk-private-chip-colour-text-on-image-dismissible-icon:#626971; - --bpk-private-chip-colour-text-on-dark:#161616; - --bpk-private-chip-colour-text-on-dark-dismisisble-hover:#161616; - --bpk-private-chip-colour-text-on-dark-dismisisble-icon:#626971; - --bpk-private-chip-dimension-min-height-width:2rem; - --bpk-private-chip-dimension-radius:0.5rem; - --bpk-private-date-selector-cheapest-month-highlight:#154679; - --bpk-private-date-selector-flexible-date-card:#eff3f8; - --bpk-private-dimension-padding-veritcal:0; - --bpk-private-info-banner-default:#eff3f8; - --bpk-private-info-banner-on-contrast:#ffffff; - --bpk-private-map-cluster-pin:#05203c; - --bpk-private-map-cluster-pin-previous-selection:#94c3ff; - --bpk-private-map-marker-viewed:rgba(255, 255, 255, 0.8); - --bpk-private-map-poi-pin:#8e47ba; - --bpk-private-map-previous-selection:#cfe4ff; - --bpk-private-navigation-tabs-hover:#154679; - --bpk-private-navigation-tabs-outline:rgba(255, 255, 255, 0.2); - --bpk-private-navigation-tabs-selected:#024daf; - --bpk-private-rating-bar-default:#e0e4e9; - --bpk-private-rating-bar-on-contrast:#ffffff; - --bpk-private-segmented-control-canvas-default:#eff3f8; - --bpk-private-segmented-control-surface-contrast:rgba(255, 255, 255, 0.1); - --bpk-private-segmented-control-surface-contrast-on:#024daf; - --bpk-private-shadow-large-blur:0.875rem; - --bpk-private-shadow-large-color:rgba(22, 22, 22, 0.25); - --bpk-private-shadow-large-position-x:0; - --bpk-private-shadow-large-position-y:0.25rem; - --bpk-private-shadow-large-spread:0; - --bpk-private-shadow-small-blur:0.1875rem; - --bpk-private-shadow-small-color:rgba(22, 22, 22, 0.25); - --bpk-private-shadow-small-position-x:0; - --bpk-private-shadow-small-position-y:0.0625rem; - --bpk-private-shadow-small-spread:0; - --bpk-private-shadow-xl-blur:3.125rem; - --bpk-private-shadow-xl-color:rgba(22, 22, 22, 0.25); - --bpk-private-shadow-xl-position-x:0; - --bpk-private-shadow-xl-position-y:0.75rem; - --bpk-private-shadow-xl-spread:0; - --bpk-private-skeleton-on-dark:rgba(255, 255, 255, 0.1); - --bpk-private-speech-bubble-colour-bg-contrast:#eff3f8; - --bpk-private-speech-bubble-colour-bg-default:#ffffff; - --bpk-private-trip-advisor:#00aa6c; - --bpk-core-accent:#0062e3; - --bpk-core-eco:#0fa1a9; - --bpk-core-primary:#05203c; - --bpk-other-line:#c1c7cf; - --bpk-other-line-on-dark:rgba(255, 255, 255, 0.5); - --bpk-other-overlay:rgba(0, 0, 0, 0.2); - --bpk-other-scrim:rgba(0, 0, 0, 0.7); - --bpk-other-shadow:rgba(22, 22, 22, 0.25); - --bpk-status-danger-fill:#ffe9f9; - --bpk-status-danger-spot:#e70866; - --bpk-status-success-fill:#d4fff2; - --bpk-status-success-spot:#0c838a; - --bpk-status-warning-fill:#fff7cf; - --bpk-status-warning-spot:#f55d42; - --bpk-surface-contrast:#05203c; - --bpk-surface-default:#ffffff; - --bpk-surface-elevated:#ffffff; - --bpk-surface-hero:#0062e3; - --bpk-surface-highlight:#e0e4e9; - --bpk-surface-low-contrast:#f7f9fb; - --bpk-surface-subtle:#e3f0ff; - --bpk-surface-tint:rgba(255, 255, 255, 0.1); - --bpk-surface-promo:#0062e3; - --bpk-text-disabled:rgba(0, 0, 0, 0.2); - --bpk-text-disabled-on-dark:rgba(255, 255, 255, 0.5); - --bpk-text-error:#e70866; - --bpk-text-inverse:#ffffff; - --bpk-text-on-dark:#ffffff; - --bpk-text-on-light:#161616; - --bpk-text-primary:#161616; - --bpk-text-secondary:#626971; - --bpk-text-success:#0c838a; - --bpk-text-deprecated-link:#0062e3; - --bpk-text-hero:#0062e3; - --bpk-title:true; - --bpk-typography-family-sans-serif:'Skyscanner Relative'; - --bpk-typography-family-serif:Larken; - --bpk-typography-kerning-default:0; - --bpk-typography-kerning-loose:0; - --bpk-typography-kerning-tight:0; - --bpk-typography-style-body:400; - --bpk-typography-style-headline:700; - --bpk-typography-style-hero:900; - --bpk-typography-style-label:700; - --bpk-typography-style-subhead:300; -} - -:root[data-theme="dark"]{ - --bpk-canvas-contrast:#010913; - --bpk-canvas-default:#010913; - --bpk-private-badge-colour-bg-default:#243346; - --bpk-private-badge-colour-bg-inverse:#243346; - --bpk-private-badge-colour-bg-outline:rgba(255, 255, 255, 0); - --bpk-private-badge-colour-bg-subtle:#243346; - --bpk-private-badge-colour-stroke-outline:#ffffff; - --bpk-private-badge-dimension-padding-horizontal-default:0.5rem; - --bpk-private-badge-dimension-padding-horizontal-subtle:0.5rem; - --bpk-private-badge-typography-tmp-badge-label:0.875rem; - --bpk-private-badge-typography-tmp-badge-line-height:0; - --bpk-private-button-colour-bg-destructive:#e0e4e9; - --bpk-private-button-colour-bg-destructive-pressed:#ff649c; - --bpk-private-button-colour-bg-disabled:#0b121d; - --bpk-private-button-colour-bg-feature-pressed:#d1f7ff; - --bpk-private-button-colour-bg-featured:#d1f7ff; - --bpk-private-button-colour-bg-footer:rgba(255, 255, 255, 0); - --bpk-private-button-colour-bg-footer-pressed:rgba(255, 255, 255, 0); - --bpk-private-button-colour-bg-primary:#024daf; - --bpk-private-button-colour-bg-primary-on-dark:#ffffff; - --bpk-private-button-colour-bg-primary-on-dark-pressed:#c1c7cf; - --bpk-private-button-colour-bg-primary-on-light:#ffffff; - --bpk-private-button-colour-bg-primary-on-light-pressed:#002b4b; - --bpk-private-button-colour-bg-secondary:#243346; - --bpk-private-button-colour-bg-secondary-pressed:#010913; - --bpk-private-button-colour-bg-secondary-on-contrast:#243346; - --bpk-private-button-colour-bg-secondary-on-contrast-pressed:#010913; - --bpk-private-button-colour-bg-secondary-on-dark:rgba(255, 255, 255, 0.1); - --bpk-private-button-colour-bg-secondary-on-dark-disabled:#0b121d; - --bpk-private-button-colour-bg-secondary-on-dark-pressed:rgba(255, 255, 255, 0.2); - --bpk-private-button-colour-text-disruptive:#ff649c; - --bpk-private-button-colour-text-feature:#010913; - --bpk-private-button-colour-text-footer:rgba(255, 255, 255, 0); - --bpk-private-button-colour-text-link-on-dark:#ffffff; - --bpk-private-button-colour-text-secondary:#ffffff; - --bpk-private-button-dimension-radius:0.5rem; - --bpk-private-button-dimension-min-height-default:2.25rem; - --bpk-private-button-dimension-min-height-large:3rem; - --bpk-private-button-dimension-min-weight-large:3rem; - --bpk-private-button-dimension-padding-horizontal-default:1rem; - --bpk-private-button-dimension-padding-horizontal-large:1rem; - --bpk-private-button-typography-tmp-default-label:1rem; - --bpk-private-card-button-contained-fill:rgba(255, 255, 255, 0.1); - --bpk-private-carousel-trigger-bg-default:rgba(255, 255, 255, 0.5); - --bpk-private-carousel-trigger-bg-default-hover:rgba(255, 255, 255, 0.8); - --bpk-private-chip-group-filter-colour-bg-icon-hover-on-image:#010913; - --bpk-private-chip-group-filter-colour-bg-icon-off-on-image:#131d2b; - --bpk-private-chip-group-filter-colour-bg-icon-on-default:#054184; - --bpk-private-chip-group-filter-colour-bg-icon-on-on-dark:#131d2b; - --bpk-private-chip-group-filter-colour-bg-icon-on-on-image:#054184; - --bpk-private-chip-group-filter-colour-stroke-icon-hover-default:#054184; - --bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark:#131d2b; - --bpk-private-chip-group-filter-colour-stroke-icon-off-default:rgba(255, 255, 255, 0.2); - --bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark:rgba(255, 255, 255, 0.2); - --bpk-private-chip-group-filter-dimensions-min-height:2.25rem; - --bpk-private-chip-colour-bg-default-dismissible-hover:#054184; - --bpk-private-chip-colour-bg-default-on:#054184; - --bpk-private-chip-colour-bg-disabled:#0b121d; - --bpk-private-chip-colour-bg-on-contrast-hover:#131d2b; - --bpk-private-chip-colour-bg-on-contrast-on:#054184; - --bpk-private-chip-colour-bg-on-dark-dismissible-hover:#131d2b; - --bpk-private-chip-colour-bg-on-dark-hover:rgba(255, 255, 255, 0); - --bpk-private-chip-colour-bg-on-dark-off:rgba(255, 255, 255, 0); - --bpk-private-chip-colour-bg-on-dark-on:#131d2b; - --bpk-private-chip-colour-bg-on-image-dismissible-hover:#054184; - --bpk-private-chip-colour-bg-on-image-on:#010913; - --bpk-private-chip-colour-border-default-dismissible-hover:rgba(255, 255, 255, 0); - --bpk-private-chip-colour-border-default-hover:#054184; - --bpk-private-chip-colour-border-default-off:rgba(255, 255, 255, 0.2); - --bpk-private-chip-colour-border-on-contrast-off:#131d2b; - --bpk-private-chip-colour-border-on-contrast-on:#131d2b; - --bpk-private-chip-colour-border-on-dark-disimissible-hover:#131d2b; - --bpk-private-chip-colour-border-on-dark-hover:#ffffff; - --bpk-private-chip-colour-border-on-dark-off:rgba(255, 255, 255, 0.2); - --bpk-private-chip-colour-stroke-off-on-canvas-contrast-new:rgba(255, 255, 255, 0); - --bpk-private-chip-colour-text-default-dismissible-hover:#ffffff; - --bpk-private-chip-colour-text-dismissible-on-icon:rgba(255, 255, 255, 0.5); - --bpk-private-chip-colour-text-on:#ffffff; - --bpk-private-chip-colour-text-on-image:#ffffff; - --bpk-private-chip-colour-text-on-image-dismissible-icon:#bdc4cb; - --bpk-private-chip-colour-text-on-dark:#ffffff; - --bpk-private-chip-colour-text-on-dark-dismisisble-hover:#ffffff; - --bpk-private-chip-colour-text-on-dark-dismisisble-icon:#bdc4cb; - --bpk-private-chip-dimension-min-height-width:2rem; - --bpk-private-chip-dimension-radius:0.5rem; - --bpk-private-date-selector-cheapest-month-highlight:#ffffff; - --bpk-private-date-selector-flexible-date-card:#243346; - --bpk-private-dimension-padding-veritcal:0; - --bpk-private-info-banner-default:#131d2b; - --bpk-private-info-banner-on-contrast:#131d2b; - --bpk-private-map-cluster-pin:#ffffff; - --bpk-private-map-cluster-pin-previous-selection:#94c3ff; - --bpk-private-map-marker-viewed:rgba(0, 0, 0, 0.8); - --bpk-private-map-poi-pin:#8e47ba; - --bpk-private-map-previous-selection:#cfe4ff; - --bpk-private-navigation-tabs-hover:#002b4b; - --bpk-private-navigation-tabs-outline:rgba(255, 255, 255, 0.2); - --bpk-private-navigation-tabs-selected:#054184; - --bpk-private-rating-bar-default:#243346; - --bpk-private-rating-bar-on-contrast:#243346; - --bpk-private-segmented-control-canvas-default:#131d2b; - --bpk-private-segmented-control-surface-contrast:#131d2b; - --bpk-private-segmented-control-surface-contrast-on:#054184; - --bpk-private-shadow-large-blur:0.875rem; - --bpk-private-shadow-large-color:rgba(22, 22, 22, 0.25); - --bpk-private-shadow-large-position-x:0; - --bpk-private-shadow-large-position-y:0.25rem; - --bpk-private-shadow-large-spread:0; - --bpk-private-shadow-small-blur:0.1875rem; - --bpk-private-shadow-small-color:rgba(22, 22, 22, 0.25); - --bpk-private-shadow-small-position-x:0; - --bpk-private-shadow-small-position-y:0.0625rem; - --bpk-private-shadow-small-spread:0; - --bpk-private-shadow-xl-blur:3.125rem; - --bpk-private-shadow-xl-color:rgba(22, 22, 22, 0.25); - --bpk-private-shadow-xl-position-x:0; - --bpk-private-shadow-xl-position-y:0.75rem; - --bpk-private-shadow-xl-spread:0; - --bpk-private-skeleton-on-dark:#243346; - --bpk-private-speech-bubble-colour-bg-contrast:#131d2b; - --bpk-private-speech-bubble-colour-bg-default:#131d2b; - --bpk-private-trip-advisor:#9ce6c0; - --bpk-core-accent:#84e9ff; - --bpk-core-eco:#0fa1a9; - --bpk-core-primary:#054184; - --bpk-other-line:rgba(255, 255, 255, 0.2); - --bpk-other-line-on-dark:rgba(255, 255, 255, 0.2); - --bpk-other-overlay:rgba(255, 255, 255, 0.8); - --bpk-other-scrim:rgba(0, 0, 0, 0.7); - --bpk-other-shadow:rgba(22, 22, 22, 0.25); - --bpk-status-danger-fill:#ffcadd; - --bpk-status-danger-spot:#ff649c; - --bpk-status-success-fill:#b1ffe7; - --bpk-status-success-spot:#62f1c6; - --bpk-status-warning-fill:#fbf1bb; - --bpk-status-warning-spot:#feeb87; - --bpk-surface-contrast:#010913; - --bpk-surface-default:#131d2b; - --bpk-surface-elevated:#243346; - --bpk-surface-hero:#010913; - --bpk-surface-highlight:#243346; - --bpk-surface-low-contrast:#243346; - --bpk-surface-subtle:#243346; - --bpk-surface-tint:rgba(255, 255, 255, 0.1); - --bpk-surface-promo:#243346; - --bpk-text-disabled:rgba(255, 255, 255, 0.2); - --bpk-text-disabled-on-dark:rgba(255, 255, 255, 0.5); - --bpk-text-error:#ff649c; - --bpk-text-inverse:#010913; - --bpk-text-on-dark:#ffffff; - --bpk-text-on-light:#010913; - --bpk-text-primary:#ffffff; - --bpk-text-secondary:#bdc4cb; - --bpk-text-success:#62f1c6; - --bpk-text-deprecated-link:#84e9ff; - --bpk-text-hero:#010913; - --bpk-title:true; - --bpk-typography-family-sans-serif:'Skyscanner Relative'; - --bpk-typography-family-serif:Larken; - --bpk-typography-kerning-default:0; - --bpk-typography-kerning-loose:0; - --bpk-typography-kerning-tight:0; - --bpk-typography-style-body:400; - --bpk-typography-style-headline:700; - --bpk-typography-style-hero:900; - --bpk-typography-style-label:700; - --bpk-typography-style-subhead:300; -} - + *//*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:initial}[hidden],template{display:none}a{background-color:#0000;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:initial;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:700}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}html{box-sizing:border-box;font-size:100%}*,:after,:before{box-sizing:inherit}body{color:#161616;font-family:var(--bpk-base-font-stack,"Skyscanner Relative",-apple-system,BlinkMacSystemFont,"Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif);font-size:1rem;line-height:1.3rem}body.scaffold-font-size{font-size:13px}body.enable-font-smoothing{-webkit-font-smoothing:antialiased}:focus-visible,[type=button]:focus-visible,[type=reset]:focus-visible,[type=submit]:focus-visible,button:focus-visible{outline:.125rem solid #0062e3;outline-offset:.125rem}.hidden,.hide{display:none!important}.visually-hidden,.visuallyhidden{border:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px;clip:rect(0 0 0 0)}.visually-hidden.focusable:active,.visually-hidden.focusable:focus,.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{height:auto;margin:0;overflow:visible;position:static;width:auto;clip:auto}.invisible{visibility:hidden}.clearfix:after,.clearfix:before{content:"";display:table}.clearfix:after{clear:both}:root{--bpk-radius-none:0;--bpk-radius-full:6.25rem;--bpk-radius-lg:1.5rem;--bpk-radius-md:0.75rem;--bpk-radius-nav-tabs:1.125rem;--bpk-radius-sm:0.5rem;--bpk-radius-xs:0.25rem;--bpk-spacing-base:1rem;--bpk-spacing-lg:1.5rem;--bpk-spacing-md:0.5rem;--bpk-spacing-none:0;--bpk-spacing-sm:0.25rem;--bpk-spacing-xl:2rem;--bpk-spacing-xs:0.125rem;--bpk-spacing-xxl:2.5rem;--bpk-spacing-xxs:0.0625rem;--bpk-spacing-xxxl:4rem;--bpk-spacing-xxxxl:6rem;--bpk-canvas-contrast:#eff3f8;--bpk-canvas-default:#fff;--bpk-private-badge-colour-bg-default:#eff3f8;--bpk-private-badge-colour-bg-inverse:#fff;--bpk-private-badge-colour-bg-outline:#fff0;--bpk-private-badge-colour-bg-subtle:#eff3f8;--bpk-private-badge-colour-stroke-outline:#fff;--bpk-private-badge-dimension-padding-horizontal-default:0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle:0.5rem;--bpk-private-badge-typography-tmp-badge-label:0.875rem;--bpk-private-badge-typography-tmp-badge-line-height:0;--bpk-private-button-colour-bg-destructive:#e0e4e9;--bpk-private-button-colour-bg-destructive-pressed:#e70866;--bpk-private-button-colour-bg-disabled:#e0e4e9;--bpk-private-button-colour-bg-feature-pressed:#024daf;--bpk-private-button-colour-bg-featured:#0062e3;--bpk-private-button-colour-bg-footer:#fff0;--bpk-private-button-colour-bg-footer-pressed:#fff0;--bpk-private-button-colour-bg-primary:#05203c;--bpk-private-button-colour-bg-primary-on-dark:#fff;--bpk-private-button-colour-bg-primary-on-dark-pressed:#c1c7cf;--bpk-private-button-colour-bg-primary-on-light:#fff;--bpk-private-button-colour-bg-primary-on-light-pressed:#154679;--bpk-private-button-colour-bg-secondary:#e0e4e9;--bpk-private-button-colour-bg-secondary-pressed:#c1c7cf;--bpk-private-button-colour-bg-secondary-on-contrast:#e0e4e9;--bpk-private-button-colour-bg-secondary-on-contrast-pressed:#c1c7cf;--bpk-private-button-colour-bg-secondary-on-dark:#ffffff1a;--bpk-private-button-colour-bg-secondary-on-dark-disabled:#0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed:#04182d;--bpk-private-button-colour-text-disruptive:#e70866;--bpk-private-button-colour-text-feature:#fff;--bpk-private-button-colour-text-footer:#fff0;--bpk-private-button-colour-text-link-on-dark:#fff;--bpk-private-button-colour-text-secondary:#161616;--bpk-private-button-dimension-radius:0.5rem;--bpk-private-button-dimension-min-height-default:2.25rem;--bpk-private-button-dimension-min-height-large:3rem;--bpk-private-button-dimension-min-weight-large:3rem;--bpk-private-button-dimension-padding-horizontal-default:1rem;--bpk-private-button-dimension-padding-horizontal-large:1rem;--bpk-private-button-typography-tmp-default-label:1rem;--bpk-private-card-button-contained-fill:#fffc;--bpk-private-carousel-trigger-bg-default:#ffffff80;--bpk-private-carousel-trigger-bg-default-hover:#fffc;--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image:#eff3f8;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image:#fff;--bpk-private-chip-group-filter-colour-bg-icon-on-default:#05203c;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark:#fff;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image:#05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default:#05203c;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark:#fff;--bpk-private-chip-group-filter-colour-stroke-icon-off-default:#c1c7cf;--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark:#ffffff80;--bpk-private-chip-group-filter-dimensions-min-height:2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover:#05203c;--bpk-private-chip-colour-bg-default-on:#05203c;--bpk-private-chip-colour-bg-disabled:#e0e4e9;--bpk-private-chip-colour-bg-on-contrast-hover:#fff;--bpk-private-chip-colour-bg-on-contrast-on:#05203c;--bpk-private-chip-colour-bg-on-dark-dismissible-hover:#fff;--bpk-private-chip-colour-bg-on-dark-hover:#fff;--bpk-private-chip-colour-bg-on-dark-off:#fff0;--bpk-private-chip-colour-bg-on-dark-on:#fff;--bpk-private-chip-colour-bg-on-image-dismissible-hover:#05203c;--bpk-private-chip-colour-bg-on-image-on:#eff3f8;--bpk-private-chip-colour-border-default-dismissible-hover:#fff0;--bpk-private-chip-colour-border-default-hover:#05203c;--bpk-private-chip-colour-border-default-off:#c1c7cf;--bpk-private-chip-colour-border-on-contrast-off:#fff;--bpk-private-chip-colour-border-on-contrast-on:#05203c;--bpk-private-chip-colour-border-on-dark-disimissible-hover:#fff;--bpk-private-chip-colour-border-on-dark-hover:#fff;--bpk-private-chip-colour-border-on-dark-off:#ffffff80;--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new:#fff0;--bpk-private-chip-colour-text-default-dismissible-hover:#fff;--bpk-private-chip-colour-text-dismissible-on-icon:#ffffff80;--bpk-private-chip-colour-text-on:#fff;--bpk-private-chip-colour-text-on-image:#fff;--bpk-private-chip-colour-text-on-image-dismissible-icon:#626971;--bpk-private-chip-colour-text-on-dark:#161616;--bpk-private-chip-colour-text-on-dark-dismisisble-hover:#161616;--bpk-private-chip-colour-text-on-dark-dismisisble-icon:#626971;--bpk-private-chip-dimension-min-height-width:2rem;--bpk-private-chip-dimension-radius:0.5rem;--bpk-private-date-selector-cheapest-month-highlight:#154679;--bpk-private-date-selector-flexible-date-card:#eff3f8;--bpk-private-dimension-padding-veritcal:0;--bpk-private-info-banner-default:#eff3f8;--bpk-private-info-banner-on-contrast:#fff;--bpk-private-map-cluster-pin:#05203c;--bpk-private-map-cluster-pin-previous-selection:#94c3ff;--bpk-private-map-marker-viewed:#fffc;--bpk-private-map-poi-pin:#8e47ba;--bpk-private-map-previous-selection:#cfe4ff;--bpk-private-navigation-tabs-hover:#154679;--bpk-private-navigation-tabs-outline:#fff3;--bpk-private-navigation-tabs-selected:#024daf;--bpk-private-rating-bar-default:#e0e4e9;--bpk-private-rating-bar-on-contrast:#fff;--bpk-private-segmented-control-canvas-default:#eff3f8;--bpk-private-segmented-control-surface-contrast:#ffffff1a;--bpk-private-segmented-control-surface-contrast-on:#024daf;--bpk-private-shadow-large-blur:0.875rem;--bpk-private-shadow-large-color:#16161640;--bpk-private-shadow-large-position-x:0;--bpk-private-shadow-large-position-y:0.25rem;--bpk-private-shadow-large-spread:0;--bpk-private-shadow-small-blur:0.1875rem;--bpk-private-shadow-small-color:#16161640;--bpk-private-shadow-small-position-x:0;--bpk-private-shadow-small-position-y:0.0625rem;--bpk-private-shadow-small-spread:0;--bpk-private-shadow-xl-blur:3.125rem;--bpk-private-shadow-xl-color:#16161640;--bpk-private-shadow-xl-position-x:0;--bpk-private-shadow-xl-position-y:0.75rem;--bpk-private-shadow-xl-spread:0;--bpk-private-skeleton-on-dark:#ffffff1a;--bpk-private-speech-bubble-colour-bg-contrast:#eff3f8;--bpk-private-speech-bubble-colour-bg-default:#fff;--bpk-private-trip-advisor:#00aa6c;--bpk-core-accent:#0062e3;--bpk-core-eco:#0fa1a9;--bpk-core-primary:#05203c;--bpk-other-line:#c1c7cf;--bpk-other-line-on-dark:#ffffff80;--bpk-other-overlay:#0003;--bpk-other-scrim:#000000b3;--bpk-other-shadow:#16161640;--bpk-status-danger-fill:#ffe9f9;--bpk-status-danger-spot:#e70866;--bpk-status-success-fill:#d4fff2;--bpk-status-success-spot:#0c838a;--bpk-status-warning-fill:#fff7cf;--bpk-status-warning-spot:#f55d42;--bpk-surface-contrast:#05203c;--bpk-surface-default:#fff;--bpk-surface-elevated:#fff;--bpk-surface-hero:#0062e3;--bpk-surface-highlight:#e0e4e9;--bpk-surface-low-contrast:#f7f9fb;--bpk-surface-subtle:#e3f0ff;--bpk-surface-tint:#ffffff1a;--bpk-surface-promo:#0062e3;--bpk-text-disabled:#0003;--bpk-text-disabled-on-dark:#ffffff80;--bpk-text-error:#e70866;--bpk-text-inverse:#fff;--bpk-text-on-dark:#fff;--bpk-text-on-light:#161616;--bpk-text-primary:#161616;--bpk-text-secondary:#626971;--bpk-text-success:#0c838a;--bpk-text-deprecated-link:#0062e3;--bpk-text-hero:#0062e3;--bpk-title:true;--bpk-typography-family-sans-serif:"Skyscanner Relative";--bpk-typography-family-serif:Larken;--bpk-typography-kerning-default:0;--bpk-typography-kerning-loose:0;--bpk-typography-kerning-tight:0;--bpk-typography-style-body:400;--bpk-typography-style-headline:700;--bpk-typography-style-hero:900;--bpk-typography-style-label:700;--bpk-typography-style-subhead:300}:root[data-theme=dark]{--bpk-canvas-contrast:#010913;--bpk-canvas-default:#010913;--bpk-private-badge-colour-bg-default:#243346;--bpk-private-badge-colour-bg-inverse:#243346;--bpk-private-badge-colour-bg-outline:#fff0;--bpk-private-badge-colour-bg-subtle:#243346;--bpk-private-badge-colour-stroke-outline:#fff;--bpk-private-badge-dimension-padding-horizontal-default:0.5rem;--bpk-private-badge-dimension-padding-horizontal-subtle:0.5rem;--bpk-private-badge-typography-tmp-badge-label:0.875rem;--bpk-private-badge-typography-tmp-badge-line-height:0;--bpk-private-button-colour-bg-destructive:#e0e4e9;--bpk-private-button-colour-bg-destructive-pressed:#ff649c;--bpk-private-button-colour-bg-disabled:#0b121d;--bpk-private-button-colour-bg-feature-pressed:#d1f7ff;--bpk-private-button-colour-bg-featured:#d1f7ff;--bpk-private-button-colour-bg-footer:#fff0;--bpk-private-button-colour-bg-footer-pressed:#fff0;--bpk-private-button-colour-bg-primary:#024daf;--bpk-private-button-colour-bg-primary-on-dark:#fff;--bpk-private-button-colour-bg-primary-on-dark-pressed:#c1c7cf;--bpk-private-button-colour-bg-primary-on-light:#fff;--bpk-private-button-colour-bg-primary-on-light-pressed:#002b4b;--bpk-private-button-colour-bg-secondary:#243346;--bpk-private-button-colour-bg-secondary-pressed:#010913;--bpk-private-button-colour-bg-secondary-on-contrast:#243346;--bpk-private-button-colour-bg-secondary-on-contrast-pressed:#010913;--bpk-private-button-colour-bg-secondary-on-dark:#ffffff1a;--bpk-private-button-colour-bg-secondary-on-dark-disabled:#0b121d;--bpk-private-button-colour-bg-secondary-on-dark-pressed:#fff3;--bpk-private-button-colour-text-disruptive:#ff649c;--bpk-private-button-colour-text-feature:#010913;--bpk-private-button-colour-text-footer:#fff0;--bpk-private-button-colour-text-link-on-dark:#fff;--bpk-private-button-colour-text-secondary:#fff;--bpk-private-button-dimension-radius:0.5rem;--bpk-private-button-dimension-min-height-default:2.25rem;--bpk-private-button-dimension-min-height-large:3rem;--bpk-private-button-dimension-min-weight-large:3rem;--bpk-private-button-dimension-padding-horizontal-default:1rem;--bpk-private-button-dimension-padding-horizontal-large:1rem;--bpk-private-button-typography-tmp-default-label:1rem;--bpk-private-card-button-contained-fill:#ffffff1a;--bpk-private-carousel-trigger-bg-default:#ffffff80;--bpk-private-carousel-trigger-bg-default-hover:#fffc;--bpk-private-chip-group-filter-colour-bg-icon-hover-on-image:#010913;--bpk-private-chip-group-filter-colour-bg-icon-off-on-image:#131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-default:#054184;--bpk-private-chip-group-filter-colour-bg-icon-on-on-dark:#131d2b;--bpk-private-chip-group-filter-colour-bg-icon-on-on-image:#054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-default:#054184;--bpk-private-chip-group-filter-colour-stroke-icon-hover-on-dark:#131d2b;--bpk-private-chip-group-filter-colour-stroke-icon-off-default:#fff3;--bpk-private-chip-group-filter-colour-stroke-icon-off-on-dark:#fff3;--bpk-private-chip-group-filter-dimensions-min-height:2.25rem;--bpk-private-chip-colour-bg-default-dismissible-hover:#054184;--bpk-private-chip-colour-bg-default-on:#054184;--bpk-private-chip-colour-bg-disabled:#0b121d;--bpk-private-chip-colour-bg-on-contrast-hover:#131d2b;--bpk-private-chip-colour-bg-on-contrast-on:#054184;--bpk-private-chip-colour-bg-on-dark-dismissible-hover:#131d2b;--bpk-private-chip-colour-bg-on-dark-hover:#fff0;--bpk-private-chip-colour-bg-on-dark-off:#fff0;--bpk-private-chip-colour-bg-on-dark-on:#131d2b;--bpk-private-chip-colour-bg-on-image-dismissible-hover:#054184;--bpk-private-chip-colour-bg-on-image-on:#010913;--bpk-private-chip-colour-border-default-dismissible-hover:#fff0;--bpk-private-chip-colour-border-default-hover:#054184;--bpk-private-chip-colour-border-default-off:#fff3;--bpk-private-chip-colour-border-on-contrast-off:#131d2b;--bpk-private-chip-colour-border-on-contrast-on:#131d2b;--bpk-private-chip-colour-border-on-dark-disimissible-hover:#131d2b;--bpk-private-chip-colour-border-on-dark-hover:#fff;--bpk-private-chip-colour-border-on-dark-off:#fff3;--bpk-private-chip-colour-stroke-off-on-canvas-contrast-new:#fff0;--bpk-private-chip-colour-text-default-dismissible-hover:#fff;--bpk-private-chip-colour-text-dismissible-on-icon:#ffffff80;--bpk-private-chip-colour-text-on:#fff;--bpk-private-chip-colour-text-on-image:#fff;--bpk-private-chip-colour-text-on-image-dismissible-icon:#bdc4cb;--bpk-private-chip-colour-text-on-dark:#fff;--bpk-private-chip-colour-text-on-dark-dismisisble-hover:#fff;--bpk-private-chip-colour-text-on-dark-dismisisble-icon:#bdc4cb;--bpk-private-chip-dimension-min-height-width:2rem;--bpk-private-chip-dimension-radius:0.5rem;--bpk-private-date-selector-cheapest-month-highlight:#fff;--bpk-private-date-selector-flexible-date-card:#243346;--bpk-private-dimension-padding-veritcal:0;--bpk-private-info-banner-default:#131d2b;--bpk-private-info-banner-on-contrast:#131d2b;--bpk-private-map-cluster-pin:#fff;--bpk-private-map-cluster-pin-previous-selection:#94c3ff;--bpk-private-map-marker-viewed:#000c;--bpk-private-map-poi-pin:#8e47ba;--bpk-private-map-previous-selection:#cfe4ff;--bpk-private-navigation-tabs-hover:#002b4b;--bpk-private-navigation-tabs-outline:#fff3;--bpk-private-navigation-tabs-selected:#054184;--bpk-private-rating-bar-default:#243346;--bpk-private-rating-bar-on-contrast:#243346;--bpk-private-segmented-control-canvas-default:#131d2b;--bpk-private-segmented-control-surface-contrast:#131d2b;--bpk-private-segmented-control-surface-contrast-on:#054184;--bpk-private-shadow-large-blur:0.875rem;--bpk-private-shadow-large-color:#16161640;--bpk-private-shadow-large-position-x:0;--bpk-private-shadow-large-position-y:0.25rem;--bpk-private-shadow-large-spread:0;--bpk-private-shadow-small-blur:0.1875rem;--bpk-private-shadow-small-color:#16161640;--bpk-private-shadow-small-position-x:0;--bpk-private-shadow-small-position-y:0.0625rem;--bpk-private-shadow-small-spread:0;--bpk-private-shadow-xl-blur:3.125rem;--bpk-private-shadow-xl-color:#16161640;--bpk-private-shadow-xl-position-x:0;--bpk-private-shadow-xl-position-y:0.75rem;--bpk-private-shadow-xl-spread:0;--bpk-private-skeleton-on-dark:#243346;--bpk-private-speech-bubble-colour-bg-contrast:#131d2b;--bpk-private-speech-bubble-colour-bg-default:#131d2b;--bpk-private-trip-advisor:#9ce6c0;--bpk-core-accent:#84e9ff;--bpk-core-eco:#0fa1a9;--bpk-core-primary:#054184;--bpk-other-line:#fff3;--bpk-other-line-on-dark:#fff3;--bpk-other-overlay:#fffc;--bpk-other-scrim:#000000b3;--bpk-other-shadow:#16161640;--bpk-status-danger-fill:#ffcadd;--bpk-status-danger-spot:#ff649c;--bpk-status-success-fill:#b1ffe7;--bpk-status-success-spot:#62f1c6;--bpk-status-warning-fill:#fbf1bb;--bpk-status-warning-spot:#feeb87;--bpk-surface-contrast:#010913;--bpk-surface-default:#131d2b;--bpk-surface-elevated:#243346;--bpk-surface-hero:#010913;--bpk-surface-highlight:#243346;--bpk-surface-low-contrast:#243346;--bpk-surface-subtle:#243346;--bpk-surface-tint:#ffffff1a;--bpk-surface-promo:#243346;--bpk-text-disabled:#fff3;--bpk-text-disabled-on-dark:#ffffff80;--bpk-text-error:#ff649c;--bpk-text-inverse:#010913;--bpk-text-on-dark:#fff;--bpk-text-on-light:#010913;--bpk-text-primary:#fff;--bpk-text-secondary:#bdc4cb;--bpk-text-success:#62f1c6;--bpk-text-deprecated-link:#84e9ff;--bpk-text-hero:#010913;--bpk-title:true;--bpk-typography-family-sans-serif:"Skyscanner Relative";--bpk-typography-family-serif:Larken;--bpk-typography-kerning-default:0;--bpk-typography-kerning-loose:0;--bpk-typography-kerning-tight:0;--bpk-typography-style-body:400;--bpk-typography-style-headline:700;--bpk-typography-style-hero:900;--bpk-typography-style-label:700;--bpk-typography-style-subhead:300} \ No newline at end of file diff --git a/packages/backpack-web/src/bpk-stylesheets/webpack.config.babel.js b/packages/backpack-web/src/bpk-stylesheets/webpack.config.babel.js index d4d2703da9..b82c07d993 100644 --- a/packages/backpack-web/src/bpk-stylesheets/webpack.config.babel.js +++ b/packages/backpack-web/src/bpk-stylesheets/webpack.config.babel.js @@ -18,22 +18,12 @@ const path = require('path'); +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const WrapperPlugin = require('wrapper-webpack-plugin'); const postCssPlugins = require('../../../../scripts/webpack/postCssPlugins'); -// Inline postcss plugin: strips license/comment blocks from the -// vendored token CSS files so they don't pile up inside base.css. -// WrapperPlugin re-adds the single Backpack license header. -const stripComments = { - postcssPlugin: 'strip-comments', - Once(root) { - root.walkComments((c) => c.remove()); - }, -}; -stripComments.postcss = true; - const TEXT = ` Backpack - Skyscanner's Design System @@ -52,7 +42,9 @@ See the License for the specific language governing permissions and limitations under the License. `; -const licenseHeader = `/* +// Use a `/*!` "important" comment so CssMinimizerPlugin (cssnano) preserves +// it through minification. +const licenseHeader = `/*! ${TEXT.replace(/^/gm, ' * ')} */`; @@ -67,6 +59,10 @@ module.exports = { filename: 'base.js', }, + optimization: { + minimizer: ['...', new CssMinimizerPlugin()], + }, + module: { rules: [ { @@ -125,7 +121,7 @@ module.exports = { loader: 'postcss-loader', options: { postcssOptions: { - plugins: [...postCssPlugins(), stripComments], + plugins: [postCssPlugins], }, }, }, From 5552934528e6e5537e1664e5e74766dd88d7bfe2 Mon Sep 17 00:00:00 2001 From: "gc.zhu" Date: Tue, 19 May 2026 17:24:56 +0800 Subject: [PATCH 10/10] [CLOV-1412] Tighten README docs around stylesheet rebuild - bpk-stylesheets: trim build pipeline notes to the essentials - token-sync: surface the `build:stylesheets` step after `tokens:sync` so regenerated tokens make it into `base.css` Co-Authored-By: Claude Opus 4.7 --- packages/backpack-web/src/bpk-stylesheets/README.md | 2 +- token-sync/README.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/backpack-web/src/bpk-stylesheets/README.md b/packages/backpack-web/src/bpk-stylesheets/README.md index 081cf13c7e..78a5328243 100644 --- a/packages/backpack-web/src/bpk-stylesheets/README.md +++ b/packages/backpack-web/src/bpk-stylesheets/README.md @@ -159,6 +159,6 @@ To build the `base.css` file run `npm run build:stylesheets` in the root folder. The webpack build depends on two sets of files that are gitignored and copied in at build time: - `normalize.scss` — copied from `node_modules/normalize.css/` by `npm run build:copy-normal_css`. Imported via `@use` in `index.scss`. -- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run copy:token-css`. Imported in `index.js` so they reach `base.css` through webpack's CSS pipeline; `index.scss` does not depend on them, so `build:sass` does not need them either. The CSS pipeline runs `css-minimizer-webpack-plugin` (cssnano) which minifies and strips the per-file license blocks; the single Backpack license header is re-added by `wrapper-webpack-plugin` as a `/*!` important comment so cssnano preserves it. +- `primitives.css`, `theme-backpack-light.css`, `theme-backpack-dark.css` — copied from `token-sync/css/` by `npm run copy:token-css`. Imported in `index.js` so they go through webpack's CSS pipeline, which minifies via `css-minimizer-webpack-plugin` and strips per-file license blocks. The Backpack license header is preserved as a `/*!` important comment. `build:stylesheets` invokes `copy:token-css` automatically, so `npm run build` and `npm run build:stylesheets` both work standalone (including after a fresh checkout or after regenerating tokens with `npm run tokens:sync`). For `build:sass`, run `npm run build:copy-normal_css` first if `normalize.scss` isn't already vendored. diff --git a/token-sync/README.md b/token-sync/README.md index 9570d92947..fa051d042c 100644 --- a/token-sync/README.md +++ b/token-sync/README.md @@ -177,5 +177,7 @@ default layout doesn't suit your build pipeline. ### Combined sync + build ```bash -npm run tokens:sync +npm run tokens:sync && npm run build:stylesheets ``` + +`tokens:sync` regenerates `token-sync/css/`; `build:stylesheets` copies them into `bpk-stylesheets/` and rebuilds `base.css` so the new tokens reach the published bundle.