@charset "UTF-8";

/* =====================================================================
   UI PREFERENCES: page scale + light/dark theme (with js/ui-prefs.js)

   PAGE SCALE
   The whole site is drawn at --ui-scale (default ~72% on desktop, 100%
   on phones; the reader can change it with the slider in the
   secondary header). It's done with CSS zoom on <html>, which resizes
   everything equally and re-flows the layout, like browser zoom, so no
   component needed rewriting. Two things zoom does NOT do the way
   browser zoom does, handled here and in ui-prefs.js:
   - vw/vh units would shrink with the zoom. Every vw/vh in the site's
     CSS is written as calc(N * var(--vw)) / var(--vh) instead, which
     divides the zoom back out, so "6vw" still means 6% of the window.
   - @media width queries see the real window, not the zoomed layout.
     Width breakpoints are therefore applied by classes on <html>
     (bp-max-418 / 600 / 1024 / 1080) that ui-prefs.js sets from the
     effective width (window width / scale). Each converted rule keeps
     its original @media copy, scoped to html:not(.dfui), as the no-JS
     fallback.
   Script notes: getBoundingClientRect(), scrollY, innerWidth/Height
   and pointer clientX/Y are in screen pixels; offsetWidth/clientWidth
   are in unzoomed CSS pixels. Don't mix the two in one calculation.

   THEME
   <html data-theme="dark"> switches the theme tokens (tokens.css).
   Rule: UI follows the theme; image containers never do. All image
   containers, case-study images, KVs and animations keep their own
   colours. Exceptions that DO follow it: the interactive experiences'
   UI and controls, the EPA canvas content, the logo carousel, icons and
   the site logo. The Inspace 3D viewer keeps a fixed light scene.
   ===================================================================== */

:root {
	--ui-scale: 1;
	--vw: calc(1vw / var(--ui-scale));
	--vh: calc(1vh / var(--ui-scale));
}

html {
	zoom: var(--ui-scale);
	/* Paint the page itself: left transparent, the browser shows its own
	   canvas colour, which with color-scheme: dark is a mid-dark grey
	   (lighter than the modules). The page is the extreme of each theme
	   (#FFFFFF / #000000); the module panels sit one small step in. */
	background-color: var(--color-background-page);
}

/* ---- Tool strip (built by ui-prefs.js as the first thing in #topbar) ----
   Sits at the very top of the window, above the header, and is kept OUT
   of the page scaling entirely: zoom: 1/scale cancels the page zoom, and
   every size inside it is a fixed px value that never refers to the
   scale, so nothing in the strip moves or resizes while the slider is
   dragged. Always 24px tall on screen, with the dashed divider (at its
   native 8x1 size) along its bottom edge. */
.ui-toolbar {
	zoom: calc(1 / var(--ui-scale));
	box-sizing: border-box;
	height: 24px;
	background-image: url("../image-assets/module-container-assets/section-divider.svg");
	background-repeat: repeat-x;
	background-position: left bottom;
	background-size: 8px 1px;
}

.ui-toolbar__inner {
	box-sizing: border-box;
	height: 100%;
	padding-inline: 16px;
	display: flex;
	align-items: center;
	justify-content: flex-start;
	gap: 14px;
	font-family: "Open Sans", sans-serif;
	font-size: 11px;
	line-height: 1;
	color: var(--color-text-primary);
}

.ui-toolbar__group {
	display: flex;
	align-items: center;
	gap: 6px;
}

.ui-toolbar__label {
	font-weight: 600;
	letter-spacing: 0.02em;
	user-select: none;
}

.ui-toolbar__value {
	min-width: 3.2em;
	text-align: right;
	font-variant-numeric: tabular-nums;
	user-select: none;
}

.ui-toolbar__sep {
	width: 1px;
	height: 12px;
	background: var(--color-border-default);
}

.ui-toolbar__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: inherit;
	cursor: pointer;
}

.ui-toolbar__btn:hover {
	background: var(--color-overlay-tint);
}

.ui-toolbar__btn:focus-visible,
.ui-toolbar__range:focus-visible {
	outline: 1px solid var(--color-border-strong);
	outline-offset: 1px;
}

.ui-toolbar__btn .material-symbols-outlined {
	font-size: 16px;
	line-height: 1;
}

/* Reset only shows once the size has been changed, but keeps its space
   while hidden, so the slider never shifts under the pointer. */
.ui-toolbar__btn[hidden] {
	display: inline-flex;
	visibility: hidden;
}

/* Slider: thin #333 track and a round thumb, themed. */
.ui-toolbar__range {
	-webkit-appearance: none;
	appearance: none;
	width: 120px;
	height: 16px;
	margin: 0;
	background: transparent;
	cursor: pointer;
}

.ui-toolbar__range::-webkit-slider-runnable-track {
	height: 1px;
	background: var(--color-border-strong);
}

.ui-toolbar__range::-moz-range-track {
	height: 1px;
	background: var(--color-border-strong);
}

.ui-toolbar__range::-webkit-slider-thumb {
	-webkit-appearance: none;
	width: 12px;
	height: 12px;
	margin-top: -5.5px;
	border: 1px solid var(--color-border-strong);
	border-radius: 50%;
	background: var(--color-background-page);
}

.ui-toolbar__range::-moz-range-thumb {
	width: 10px;
	height: 10px;
	border: 1px solid var(--color-border-strong);
	border-radius: 50%;
	background: var(--color-background-page);
}

@media (max-width: 418px) {
	.ui-toolbar__label {
		display: none;
	}
	.ui-toolbar__range {
		width: 90px;
	}
}

/* ---- Dark theme: UI artwork ----
   Dark copies of the UI SVGs (same file name + -dark, greys mapped to the
   dark theme's inverse steps; the colour bars keep their CMYK swatches).
   Generated alongside each rule that uses the light file. */
html[data-theme="dark"] .ui-toolbar {
	background-image: url("../image-assets/module-container-assets/section-divider-dark.svg");
}
html[data-theme="dark"] .nav-container {
	background-image: url("../image-assets/module-container-assets/section-divider-dark.svg");
}
html[data-theme="dark"] .nav-logo-link {
	background-image: url("../image-assets/logo/logo-8-dark.svg");
}
html[data-theme="dark"] .nav-logo-link--inline {
	background-image: none;
}
html[data-theme="dark"] .menu-container {
	background-image: url("../image-assets/module-container-assets/section-divider-dark.svg");
}
html[data-theme="dark"] .printer-marks-container {
	background-image:
		url("../image-assets/module-container-assets/registration-marks-tl-dark.svg"),
		url("../image-assets/module-container-assets/registration-marks-bl-dark.svg"),
		url("../image-assets/module-container-assets/registration-marks-br-dark.svg"),
		url("../image-assets/module-container-assets/registration-marks-tr-dark.svg"),
		url("../image-assets/module-container-assets/colour-bar-dark.svg"),
		url("../image-assets/module-container-assets/colour-bar-dark.svg"),
		url("../image-assets/module-container-assets/tint-bar-dark.svg");
}
html[data-theme="dark"] .section-divider {
	background-image: url("../image-assets/module-container-assets/section-divider-dark.svg");
}
html[data-theme="dark"] .footer-logo-link {
	background-image: url("../image-assets/logo/logo-32-dark.svg");
}
html[data-theme="dark"] .footer-printer-marks {
	background-image:
		url("../image-assets/module-container-assets/registration-marks-tl-dark.svg"),
		url("../image-assets/module-container-assets/registration-marks-bl-dark.svg"),
		url("../image-assets/module-container-assets/registration-marks-br-dark.svg"),
		url("../image-assets/module-container-assets/registration-marks-tr-dark.svg");
}
html[data-theme="dark"] dt::before {
	background: url('../image-assets/icons-etc/bullet-dark.svg') center / contain no-repeat;
}

/* ---- Dark theme: things that stay light ----
   .theme-pinned-light: an area that behaves like an image container: it
   keeps the light theme whatever the page theme, by re-declaring the
   light theme tokens (tokens.css) on itself. Everything inside that uses
   the tokens (grid paper, buttons, text, the cube loader via
   js/cube-loader.js) stays light.
   Used on the Inspace 3D viewer's viewport (.dtv-stage: the scene, start
   screen, loader and error message), so the model preview reads the same
   in both themes. The rest of the module (controls + guide bar, frame)
   and the printer-marks container around it follow the theme. */
html[data-theme="dark"] .theme-pinned-light {
	color-scheme: light;
	--color-background-page: var(--color-grey-neutral-000);
	--color-background-surface: var(--color-grey-neutral-050);
	--color-background-surface-raised: var(--color-grey-neutral-000);
	--color-background-subtle: var(--color-grey-neutral-200);
	--color-background-muted: var(--color-grey-neutral-300);
	--color-background-inverse: var(--color-grey-neutral-700);
	--color-background-inverse-hover: var(--color-grey-neutral-600);
	--color-text-primary: var(--color-grey-neutral-700);
	--color-text-secondary: var(--color-grey-neutral-500);
	--color-text-inverse: var(--color-grey-neutral-000);
	--color-border-strong: var(--color-grey-neutral-700);
	--color-border-default: var(--color-grey-neutral-300);
	--color-border-subtle: var(--color-grey-neutral-200);
	--color-overlay-scrim: var(--color-black-50);
	--color-overlay-tint: var(--color-black-05);
	--color-primary-elements-000: var(--color-grey-neutral-000);
	--color-primary-elements-050: var(--color-grey-neutral-050);
	--color-primary-elements-100: var(--color-grey-neutral-100);
	--color-primary-elements-200: var(--color-grey-neutral-200);
	--color-primary-elements-300: var(--color-grey-neutral-300);
	--color-primary-elements-400: var(--color-grey-neutral-400);
	--color-primary-elements-500: var(--color-grey-neutral-500);
	--color-primary-elements-600: var(--color-grey-neutral-600);
	--color-primary-elements-700: var(--color-grey-neutral-700);
	--color-primary-elements-800: var(--color-grey-neutral-800);
	--color-primary-elements-900: var(--color-grey-neutral-900);
}

/* The 3D scene's own colours are read by the JS from .dtv-widget (which
   follows the theme), so pin them to the light values there too. */
html[data-theme="dark"] .dtv-widget {
	--dtv-sky-zenith: var(--color-grey-neutral-200);
	--dtv-sky-horizon: var(--color-grey-neutral-000);
	--dtv-grid-color: var(--color-grey-neutral-200);
	--dtv-grid-major-color: var(--color-grey-neutral-200);
	--dtv-placeholder-fill: var(--color-grey-neutral-200);
	--dtv-placeholder-edge: var(--color-grey-neutral-700);
}

/* The scroll-driven turntable is an image container, so its placeholder
   stays light too. */
html[data-theme="dark"] .ttv-widget {
	--ttv-placeholder-fill: var(--color-grey-neutral-200);
	--ttv-placeholder-edge: var(--color-grey-neutral-700);
}

/* ---- Media that follows the theme (case-by-case, opt-in) ----
   By default image containers never change with the theme. A page can opt
   a container in with class="theme-media" plus its two colours inline:
     style="--bg-light: #F1F3F4; --bg-dark: #202124;"
   First used on google-summits.html: the Summits brand had its own dark
   mode, so the panels switch while the KV brand colours stay the same
   (the Security KV swaps to a dark-grid version of itself, via
   img data-src-dark / source data-srcset-dark). */
.theme-media {
	background-color: var(--bg-light);
}

html[data-theme="dark"] .theme-media {
	background-color: var(--bg-dark);
}

/* Google Cloud lockup for dark panels (white "Cloud") */
html[data-theme="dark"] .theme-media .logo-google {
	background-image: url("../image-assets/case-study-images/client_logo-google_cloud-thumbnail.svg");
	--logo-aspect: 256 / 45;
}

/* Black/white brands (DataStax, Cricket for Climate, adidas on
   work.html): black panel with a white logo in light mode, white panel
   with a black logo in dark mode, per their brand guidelines. */
html[data-theme="dark"] .theme-media .banner-logo--white {
	filter: brightness(0);
}

