/* Hybrid Rich Media Gallery. Tokens follow hybridadtech.com (Gilroy, #6103AC,
   lilac page, glass menus, pill buttons, navy footer). The gallery's own code uses no
   inline styles: no <style> or style="" in the markup and none from our scripts (house
   rule, test/site.test.mjs). The shell CSP allows 'unsafe-inline' styles only for the
   Cookiebot consent banner that GTM loads. JS sets styles only through the CSSOM: custom
   properties, the knowledge panel's min-height and the orbit connectors' stroke-dash*. */

@font-face { font-family: 'Gilroy'; src: url('../fonts/gilroy-regular.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Gilroy'; src: url('../fonts/gilroy-medium.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Gilroy'; src: url('../fonts/gilroy-semibold.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }

:root {
  --purple: #6103AC;
  --purple-hover: #932CE5;
  --purple-deep: #380E59;
  --pink: #F93790;
  --pink-glow: #FA67E0;
  --cyan: #03B1F7;
  --teal: #13BAA7;
  --orange: #E36C03;
  --navy: #202246;
  --text: #141414;
  --muted: #63656c;   /* brand grey #787A81 darkened for 4.5:1 on the page and on glass */
  --page: #F8F9FF;
  --lilac: #EFE7FF;
  --line: rgba(120, 122, 129, .3);
  --glass: rgba(255, 255, 255, .8);
  --shadow-card: 0 0 0 2px #fff inset, 10px 40px 60px -20px rgba(49, 50, 91, .18);
  --shadow-max: 10px 60px 60px 0 rgba(49, 50, 91, .15);
  --shadow-menu: 0 10px 20px 0 rgba(33, 33, 52, .25), 0 0 0 2px #fff inset;
  --radius-pill: 50px;
  --container: 1230px;
  --gutter: 15px;
  --header-h: 94px;
  --ease: cubic-bezier(.4, 0, .2, 1);
  --glow: #9b5de5;
  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + 8px); -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: 'Gilroy', Arial, sans-serif;
  font-size: 18px;
  line-height: 1.45;
  color: var(--text);
  background: var(--page);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; }
button { font: inherit; color: inherit; }
h1, h2, h3, p { margin: 0; }
::selection { background: rgb(165, 8, 179); color: #fff; }
:focus-visible { outline: 3px solid var(--purple-hover); outline-offset: 3px; border-radius: 6px; }
.contact-card :focus-visible, .site-footer :focus-visible { outline-color: #fff; }
section[tabindex="-1"]:focus { outline: none; }
[hidden] { display: none !important; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: 16px; top: -60px; z-index: 100; padding: 10px 18px; border-radius: 20px; background: var(--purple); color: #fff; font-weight: 500; text-decoration: none; transition: top .2s; }
.skip-link:focus { top: 12px; }

.container { width: 100%; max-width: calc(var(--container) + 2 * var(--gutter)); margin: 0 auto; padding: 0 var(--gutter); }
@media (min-width: 1500px) { :root { --container: 1440px; } }

.eyebrow { color: var(--purple); font-weight: 600; font-size: 22px; line-height: 1.2; margin-bottom: 14px; }
h1 { font-size: clamp(38px, 5vw, 64px); line-height: 1.12; font-weight: 600; letter-spacing: -.01em; }
h2 { font-size: clamp(30px, 3.4vw, 46px); line-height: 1.15; font-weight: 600; letter-spacing: -.005em; }
.lead, .section-lead { color: var(--muted); font-size: 19px; line-height: 1.5; }
.section-lead { margin-top: 14px; }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 50px; padding: 13px 34px; border: 0; border-radius: var(--radius-pill);
  font-size: 18px; font-weight: 500; line-height: 1.1; text-decoration: none; cursor: pointer;
  transition: background-color .3s var(--ease), color .3s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease);
}
.btn svg { width: 20px; height: 20px; flex: none; }
.btn-purple { background: var(--purple); color: #fff; }
.btn-purple:hover { background: var(--purple-hover); }
.btn-outline { background: transparent; color: var(--purple); box-shadow: 0 0 0 2px var(--purple) inset; }
.btn-outline:hover { background: var(--purple); color: #fff; }
.btn-white { background: #fff; color: var(--purple); }
.btn-white:hover { background: var(--lilac); }
.btn-ghost-white { background: transparent; color: #fff; box-shadow: 0 0 0 2px rgba(255, 255, 255, .7) inset; }
.btn-ghost-white:hover { background: rgba(255, 255, 255, .14); }
.btn-small { min-height: 42px; padding: 10px 22px; font-size: 16px; }
.link-button { border: 0; background: none; padding: 4px 0; color: var(--purple); font-weight: 500; font-size: 16px; cursor: pointer; text-decoration: underline; text-underline-offset: 4px; }
.link-button:hover { color: var(--purple-hover); }

/* Header */
.site-header { position: sticky; top: 0; z-index: 50; transition: background-color .3s, box-shadow .3s, backdrop-filter .3s; }
.site-header.is-scrolled { background: rgba(255, 255, 255, .8); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); box-shadow: 0 1px 0 rgba(120, 122, 129, .12); }
.header-inner { display: flex; align-items: center; gap: 28px; min-height: var(--header-h); }
.brand img { width: 103px; height: auto; }
.brand-tag { margin-left: -14px; padding: 4px 12px; border-radius: 20px; background: var(--lilac); color: var(--purple); font-size: 14px; font-weight: 600; white-space: nowrap; }
.main-nav { display: flex; gap: 30px; margin-left: auto; }
.main-nav a { font-size: 18px; font-weight: 500; text-decoration: none; transition: color .2s; }
.main-nav a:hover { color: var(--purple); }
.header-cta { padding: 13px 28px; }
/* Language-independent widths (load-time layout shift): the static HTML is Polish and app.js
   swaps in EN or DE after the first paint. The header button keeps the width of the Polish label
   (the longest), and the language code the width of "DE", so the nav beside them stays put. */
.header-cta { min-width: 229px; }
[data-lang-current] { display: inline-block; min-width: 1.25em; text-align: center; }

.lang { position: relative; }
.lang-button { display: inline-flex; align-items: center; gap: 6px; padding: 8px 4px; border: 0; background: none; color: var(--purple); font-size: 18px; font-weight: 500; cursor: pointer; transition: opacity .2s; }
.lang-button:hover, .lang-button[aria-expanded="true"] { opacity: .8; }
.chev { width: 11px; height: 6px; flex: none; transition: transform .2s; }
.lang-button[aria-expanded="true"] .chev { transform: rotate(180deg); }
/* Right-aligned under the button: the button is the last item of the header, so a centred
   menu would stick out past the page edge (even closed, it widens the page). */
.lang-menu {
  position: absolute; top: calc(100% + 10px); right: 0; transform: translateY(8px);
  display: grid; margin: 0; padding: 17px 14px; list-style: none;
  border-radius: 20px; background: var(--glass); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); box-shadow: var(--shadow-menu);
  opacity: 0; visibility: hidden; transition: opacity .2s linear, visibility 0s linear .2s, transform .2s ease-in-out;
}
.lang-menu.is-open { opacity: 1; visibility: visible; transform: none; transition: opacity .2s linear, visibility 0s, transform .2s ease-in-out; }
/* Whole rows are the targets (about 50x36 px); text sits where the 22/26 px padding and 10 px gap put it. */
.lang-menu a { display: block; padding: 5px 12px; font-size: 18px; font-weight: 500; text-decoration: none; transition: color .2s; }
.lang-menu a:hover, .lang-menu a:focus-visible { color: var(--purple-hover); }
.lang-menu a[aria-current="true"] { color: var(--purple); }

/* Hero */
.hero { position: relative; padding: 40px 0 90px; overflow-x: clip; }
.hero-glow {
  position: absolute; inset: -30% -10% auto auto; width: 70vw; height: 70vw; max-width: 1100px; max-height: 1100px; pointer-events: none;
  background:
    radial-gradient(closest-side at 62% 42%, rgba(147, 44, 229, .30), transparent 70%),
    radial-gradient(closest-side at 78% 62%, rgba(250, 103, 224, .26), transparent 70%),
    radial-gradient(closest-side at 40% 70%, rgba(3, 177, 247, .14), transparent 70%);
  filter: blur(10px);
}
.hero-grid { position: relative; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 56px; align-items: center; }
.hero-copy .lead { margin-top: 22px; max-width: 489px; }
.hero-stats { display: flex; flex-wrap: wrap; gap: 14px 32px; margin: 30px 0 0; padding: 0; list-style: none; color: var(--muted); font-size: 17px; }
.hero-stats strong { color: var(--purple); font-size: 34px; font-weight: 600; line-height: 1; margin-right: 4px; }
/* Each number keeps the width of its longest language (German "Werbemittel", English "industries",
   Polish "formatów"), so the second and third do not move when app.js translates the page. */
.hero-stats li:nth-child(1) { min-width: 140px; }
.hero-stats li:nth-child(2) { min-width: 113px; }
.hero-stats li:nth-child(3) { min-width: 101px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }
.hero-actions .btn-purple { min-width: 245px; } /* the German label, the longest: the second button never moves */
/* The static HTML is Polish and app.js swaps in EN or DE after the first paint. The hero
   copy keeps one height in all three languages so nothing below it jumps (layout shift):
   the lead reserves the line count of the longest language (1 line = 1.5em). The lead is
   capped at 489 px (the copy column at 1280-1440 px), a width where all three languages take
   four lines (they do from about 436 to 499 px): wider, Polish and English need one line less
   than German and leave an empty reserved line above the stats. Below 460 px that line stays,
   the cost of reserving for German. From 1001 to 1230 px the copy column is 378 px wide: the
   title keeps two lines and the stats one row in every language, and the buttons take two rows
   in every language (the first button keeps the width of the German label, so "Porozmawiajmy"
   sits in the same place in all three); the room of two rows (two 50 px buttons and the 14 px
   gap) stays reserved.
   Tuned to the current copy; e2e "the hero keeps its height" checks it. */
.hero-copy .lead { min-height: 6em; }
@media (min-width: 1001px) and (max-width: 1230px) {
  .hero-copy h1 { font-size: min(5vw, 55px); }
  .hero-copy .lead { min-height: 7.5em; }
  .hero-actions { min-height: calc(2 * 50px + 14px); align-content: flex-start; }
  .hero-actions .btn { min-width: 245px; } /* both stacked pills take the reserved width */
  .hero-stats { gap: 10px 16px; font-size: 15px; }
  .hero-stats strong { font-size: 28px; }
  .hero-stats li:nth-child(1) { min-width: 122px; }
  .hero-stats li:nth-child(2) { min-width: 98px; }
  .hero-stats li:nth-child(3) { min-width: 89px; }
}
@media (max-width: 480px) {
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-stats { gap: 10px 12px; font-size: 15px; } /* 12 px: the three reserved widths fit one row from 360 px */
  .hero-stats strong { font-size: 28px; }
  .hero-stats li:nth-child(1) { min-width: 122px; }
  .hero-stats li:nth-child(2) { min-width: 98px; }
  .hero-stats li:nth-child(3) { min-width: 89px; }
}
@media (max-width: 460px) { .hero-copy h1 { min-height: 2.24em; } }
@media (max-width: 459px) { .hero-copy .lead { min-height: 7.5em; } }
@media (max-width: 397px) { .hero-copy .lead { min-height: 9em; } }
/* Below 360 px the three numbers still fit one row in every language (longest: DE "Werbemittel"
   109 px, "Branchen" 88 px, PL "formatów" 81 px; 110 + 89 + 81 + 2 x 6 = 292 of 296 px). */
@media (max-width: 359px) {
  .hero-stats { gap: 6px; font-size: 14px; }
  .hero-stats strong { font-size: 22px; }
  .hero-stats li:nth-child(1) { min-width: 110px; }
  .hero-stats li:nth-child(2) { min-width: 89px; }
  .hero-stats li:nth-child(3) { min-width: 81px; }
}

.showreel { position: relative; margin: 0; aspect-ratio: 16 / 9; border-radius: 30px; overflow: hidden; background: linear-gradient(135deg, #f3ecff, #fde9f6); box-shadow: var(--shadow-card); }
.showreel-video { width: 100%; height: 100%; object-fit: cover; }
.showreel-toggle {
  position: absolute; right: 16px; bottom: 16px; display: grid; place-items: center; width: 46px; height: 46px; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .78); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); color: var(--purple); cursor: pointer; box-shadow: 0 6px 18px rgba(33, 33, 52, .18);
}
.showreel-toggle svg { width: 20px; height: 20px; }
.showreel-toggle .icon-play { display: none; }
.showreel.is-paused .showreel-toggle .icon-play { display: block; }
.showreel.is-paused .showreel-toggle .icon-pause { display: none; }

/* Configurator */
.gallery { padding: 40px 0 60px; }
.configurator {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "intro  viewer filters"
    "info   viewer qr";
  gap: 28px 40px;
  align-items: start;
}
.cfg-intro { grid-area: intro; }
.cfg-filters { grid-area: filters; }
.cfg-viewer { grid-area: viewer; display: grid; justify-items: center; gap: 18px; }
.cfg-info { grid-area: info; }
.qr-card { grid-area: qr; }
.cfg-intro h2 { font-size: clamp(28px, 2.5vw, 38px); }
.cfg-intro .section-lead { font-size: 17px; }

.info-card, .qr-card, .cfg-filters {
  border-radius: 30px; background: var(--glass); box-shadow: var(--shadow-card);
}
.info-card { padding: 28px 28px 30px; display: grid; gap: 16px; }
.info-head { display: grid; gap: 2px; }
.info-brand { font-size: 30px; line-height: 1.1; font-weight: 600; }
.info-advertiser { color: var(--muted); font-size: 15px; }
.info-desc { color: #3c3d44; font-size: 17px; line-height: 1.5; }
.info-want { justify-self: start; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 20px; font-size: 14px; font-weight: 500; line-height: 1.2; background: #f1f1f6; color: #4a4b55; }
.chip-format { background: #f1e7fb; color: var(--purple); }
.chip-industry { background: #e3f6f3; color: #0a7366; }
.chip-mechanic { background: #fff; box-shadow: 0 0 0 1px rgba(120, 122, 129, .28) inset; color: #4a4b55; }

.demo { display: grid; gap: 10px; padding: 16px 18px 18px; border-radius: 22px; background: linear-gradient(135deg, rgba(97, 3, 172, .07), rgba(249, 55, 144, .06)); box-shadow: 0 0 0 1px rgba(97, 3, 172, .12) inset; }
.demo-title { display: flex; align-items: center; gap: 8px; color: var(--purple); font-weight: 600; font-size: 16px; }
.demo-title svg { width: 20px; height: 20px; }
.demo-text { color: var(--muted); font-size: 15px; line-height: 1.45; }
.demo-options { display: flex; flex-wrap: wrap; gap: 6px; }
.demo-option {
  display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 5px 13px; border: 0; border-radius: 20px; cursor: pointer;
  background: #fff; color: var(--text); font-size: 15px; font-weight: 500; box-shadow: 0 0 0 1px rgba(97, 3, 172, .18) inset; transition: background-color .2s, color .2s, box-shadow .2s;
}
.demo-option svg { width: 17px; height: 17px; }
.demo-option:hover { color: var(--purple-hover); }
.demo-option[aria-checked="true"] { background: var(--purple); color: #fff; box-shadow: none; }

.specs { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; margin: 0; font-size: 15px; }
.specs dt { color: var(--muted); }
.specs dd { margin: 0; font-weight: 500; }
.info-note { color: var(--muted); font-size: 14px; line-height: 1.45; }

/* Filters (dropdowns styled like the language menu on hybridadtech.com) */
.cfg-filters { padding: 24px; display: grid; gap: 18px; }
.dropdown { position: relative; display: grid; gap: 8px; }
.dd-caption { color: var(--muted); font-size: 15px; font-weight: 500; }
.dd-button {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; min-height: 54px; padding: 12px 20px;
  border: 0; border-radius: 20px; background: #fff; cursor: pointer; text-align: left;
  font-size: 18px; font-weight: 500; box-shadow: 0 0 0 1px rgba(120, 122, 129, .22) inset, 0 6px 14px -6px rgba(33, 33, 52, .12);
  transition: box-shadow .2s, color .2s;
}
.dd-button:hover { color: var(--purple); }
.dd-button:disabled { cursor: default; color: var(--muted); }
.dd-button .chev { color: var(--purple); }
.dropdown.is-open .dd-button { box-shadow: 0 0 0 2px var(--purple) inset; }
.dropdown.is-open .dd-button .chev { transform: rotate(180deg); }
.dropdown.is-filtered .dd-value { color: var(--purple); }
.dd-list {
  position: absolute; z-index: 20; top: calc(100% + 8px); left: 0; right: 0;
  max-height: min(420px, 60vh); overflow: auto; margin: 0; padding: 12px; list-style: none;
  border-radius: 20px; background: rgba(255, 255, 255, .86); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: var(--shadow-menu);
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity .2s linear, visibility 0s linear .2s, transform .2s ease-in-out;
}
.dropdown.is-open .dd-list { opacity: 1; visibility: visible; transform: none; transition: opacity .2s linear, visibility 0s, transform .2s ease-in-out; }
.dd-list:focus { outline: none; }
.dd-list [role="option"] {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 12px; border-radius: 12px;
  color: #000; font-size: 17px; font-weight: 500; cursor: pointer; transition: color .15s, background-color .15s;
}
.dd-list [role="option"].is-active { color: var(--purple-hover); background: rgba(147, 44, 229, .07); }
.dd-list [role="option"][aria-selected="true"] { color: var(--purple); }
/* Keyboard focus is a shape, not only a tint: it must stay visible on the selected option too.
   dropdown.js sets .is-keyboard while the list is driven by keys (the pointer only tints). */
.dd-list.is-keyboard [role="option"].is-active { box-shadow: inset 0 0 0 2px var(--purple-hover); }
.dd-list [role="option"][aria-disabled="true"] { color: #b9bac2; cursor: default; background: none; }
.dd-count { min-width: 28px; padding: 2px 8px; border-radius: 12px; background: #f1f1f6; color: #5f6168; font-size: 13px; text-align: center; }
[aria-selected="true"] > .dd-count { background: #f1e7fb; color: var(--purple); }
.filter-status { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 28px; }
.result-count { color: var(--muted); font-size: 16px; font-weight: 500; }

.qr-card { display: flex; align-items: center; gap: 18px; padding: 20px 22px; }
.qr { flex: none; width: 108px; height: 108px; padding: 6px; border-radius: 14px; background: #fff; box-shadow: 0 0 0 1px rgba(120, 122, 129, .2) inset; }
.qr svg { width: 100%; height: 100%; }
.qr-title { font-weight: 600; font-size: 16px; }
.qr-hint { margin-top: 4px; color: var(--muted); font-size: 14px; line-height: 1.4; }

/* Viewer and phone. fitPhone() in app.js reads the arrow width and the .viewer gap
   (here and in the 730px block) to size the phone between the arrows. */
.viewer { display: flex; align-items: center; gap: 22px; }
.arrow {
  display: grid; place-items: center; width: 58px; height: 58px; flex: none; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, .9); color: var(--purple); box-shadow: 0 0 0 2px #fff inset, 0 10px 24px -8px rgba(49, 50, 91, .35);
  transition: background-color .25s var(--ease), color .25s var(--ease), transform .25s var(--ease);
}
.arrow svg { width: 26px; height: 26px; }
.arrow:hover { background: var(--purple); color: #fff; }
.arrow:active { transform: scale(.94); }
.arrow:disabled { opacity: .35; cursor: default; background: #fff; color: var(--purple); }

/* The phone is laid out at its natural size and scaled as a whole (JS sets --phone-scale). */
.phone-stage { --phone-scale: .82; position: relative; isolation: isolate; width: calc(390px * var(--phone-scale)); height: calc(838px * var(--phone-scale)); flex: none; }
.phone-glow {
  position: absolute; inset: 8% -18% 4%; z-index: -1; border-radius: 50%; pointer-events: none;
  background-color: color-mix(in srgb, var(--glow) 55%, #c9a4ff);
  filter: blur(70px); opacity: .55; transition: background-color .8s var(--ease);
}
.phone { position: absolute; top: 0; left: 0; width: 390px; height: 838px; transform: scale(var(--phone-scale)); transform-origin: 0 0; }
.phone-body {
  position: absolute; inset: 0; padding: 15px; border-radius: 68px;
  background: linear-gradient(145deg, #2b2d33, #0c0c10 40%, #16171c);
  box-shadow:
    0 0 0 2px #d5d8e0, 0 0 0 3.5px #9da1ad, 0 0 0 5px #eceef3,
    0 50px 80px -30px rgba(49, 50, 91, .45), 0 24px 40px -18px rgba(49, 50, 91, .35);
}
/* Keyboard focus inside the creative frame (phone.js sets .is-frame-focused): a ring around the
   phone, 3-4px on screen at any scale (outline widths snap down to whole px before the scale).
   A ring on the iframe itself would be clipped by .phone-screen. */
.phone-stage.is-frame-focused .phone-body { outline: calc(4px / var(--phone-scale)) solid var(--purple); outline-offset: calc(10px + 3px / var(--phone-scale)); }
.phone-btn { position: absolute; width: 5px; border-radius: 3px; background: linear-gradient(90deg, #8f93a0, #d9dce4); }
.phone-btn-action { left: -9px; top: 150px; height: 34px; }
.phone-btn-vol-up { left: -9px; top: 210px; height: 62px; }
.phone-btn-vol-down { left: -9px; top: 286px; height: 62px; }
.phone-btn-power { right: -9px; top: 232px; height: 96px; background: linear-gradient(270deg, #8f93a0, #d9dce4); }
.phone-screen { position: relative; width: 360px; height: 808px; border-radius: 54px; overflow: hidden; background: #fff; isolation: isolate; }
.island { position: absolute; top: 26px; left: 50%; width: 118px; height: 34px; margin-left: -59px; border-radius: 20px; background: #000; z-index: 6; pointer-events: none; }
.home-indicator { position: absolute; bottom: 9px; left: 50%; width: 132px; height: 5px; margin-left: -66px; border-radius: 3px; background: rgba(20, 20, 20, .55); z-index: 6; pointer-events: none; }

/* Fake publisher app behind the interstitial */
.app { position: absolute; inset: 0; background: #fff; }
.statusbar { position: absolute; top: 0; left: 0; right: 0; height: 44px; display: flex; align-items: flex-end; justify-content: space-between; padding: 0 30px 9px 38px; font-size: 15px; font-weight: 600; z-index: 5; }
.sb-icons { display: flex; gap: 5px; align-items: center; }
.sb-icons i { display: block; width: 16px; height: 10px; border-radius: 2px; background: #141414; }
.sb-icons i:first-child { width: 17px; clip-path: polygon(0 100%, 100% 0, 100% 100%); border-radius: 0; }
.sb-icons i:nth-child(2) { width: 14px; border-radius: 7px 7px 2px 2px; }
.sb-icons i:last-child { width: 24px; border-radius: 3px; box-shadow: 0 0 0 1.5px #141414 inset; background: linear-gradient(90deg, #141414 72%, transparent 72%); }
.app-bar { position: absolute; top: 44px; left: 0; right: 0; height: 54px; display: flex; align-items: center; gap: 12px; padding: 0 20px; border-bottom: 1px solid #eee; }
.app-logo { width: 30px; height: 30px; border-radius: 9px; background: linear-gradient(135deg, var(--purple), var(--pink)); }
.app-title { width: 110px; height: 12px; border-radius: 6px; background: #d9dae2; }
.app-avatar { width: 28px; height: 28px; margin-left: auto; border-radius: 50%; background: #e6e7ee; }
.app-feed { position: absolute; top: 112px; left: 20px; right: 20px; display: grid; gap: 12px; }
.app-hero { height: 190px; border-radius: 18px; background: linear-gradient(135deg, #e9dcff, #ffd9ef 60%, #d7f1ff); }
.app-line { height: 11px; border-radius: 6px; background: #e3e4eb; }
.app-row { display: flex; gap: 12px; margin: 4px 0; }
.app-thumb { width: 92px; height: 72px; flex: none; border-radius: 12px; background: #eceaf6; }
.app-col { flex: 1; display: grid; gap: 9px; align-content: center; }
.w50 { width: 50%; } .w60 { width: 60%; } .w65 { width: 65%; } .w70 { width: 70%; } .w75 { width: 75%; } .w80 { width: 80%; } .w90 { width: 90%; }

.ad-layer { position: absolute; top: 44px; left: 0; width: 360px; height: 740px; z-index: 2; }
.ad-dim { position: absolute; inset: -44px 0 -24px; background: rgba(16, 14, 32, .58); backdrop-filter: blur(1.5px); -webkit-backdrop-filter: blur(1.5px); }
.ad-poster, .ad-frame, .ad-frame iframe { position: absolute; inset: 0; width: 360px; height: 740px; }
.ad-poster { object-fit: cover; transition: opacity .35s var(--ease); }
.ad-layer.is-live .ad-poster { opacity: 0; }
.ad-frame iframe { border: 0; background: transparent; color-scheme: normal; }
.ad-closed { position: absolute; inset: 44px 0 0; z-index: 3; display: grid; place-content: center; justify-items: center; gap: 16px; background: rgba(248, 249, 255, .82); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); font-weight: 600; }
.ad-closed .btn svg { width: 18px; height: 18px; }
.toast {
  position: absolute; left: 14px; right: 14px; bottom: 26px; z-index: 7; display: grid; grid-template-columns: 1fr auto; gap: 8px 10px; align-items: center;
  --toast-unit: clamp(1px, calc(1px / var(--phone-scale)), 1.6px);
  padding: calc(14 * var(--toast-unit)) calc(14 * var(--toast-unit)) calc(14 * var(--toast-unit)) calc(18 * var(--toast-unit));
  border-radius: 20px; background: rgba(20, 18, 40, .9); color: #fff; font-size: calc(14 * var(--toast-unit)); line-height: 1.35;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); box-shadow: 0 12px 30px rgba(0, 0, 0, .3);
  animation: toast-in .25s var(--ease);
}
.toast-link { grid-column: 1; color: #fff; font-weight: 600; text-underline-offset: 3px; }
.toast-dismiss { grid-column: 2; grid-row: 1 / span 2; align-self: start; display: grid; place-items: center; width: calc(36 * var(--toast-unit)); height: calc(36 * var(--toast-unit)); border: 0; border-radius: 50%; background: rgba(255, 255, 255, .14); color: #fff; cursor: pointer; }
.toast-dismiss svg { width: calc(16 * var(--toast-unit)); height: calc(16 * var(--toast-unit)); }
@keyframes toast-in { from { opacity: 0; transform: translateY(10px); } }
.empty-state { position: absolute; inset: 44px 0 24px; z-index: 3; display: grid; place-items: center; align-content: center; gap: 22px; padding: 40px; text-align: center; background: var(--page); color: var(--muted); font-weight: 500; }
.empty-state .btn svg { width: 18px; height: 18px; }

.viewer-bar { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.counter { color: var(--text); font-size: 16px; font-weight: 600; letter-spacing: .02em; line-height: 1.45; min-height: 1.45em; } /* full height before the text arrives: fitPhone() measures the bar at boot */
.viewer-tools { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.cfg-viewer.is-empty .viewer-tools { visibility: hidden; }
.tool {
  display: inline-flex; align-items: center; gap: 7px; min-height: 40px; padding: 8px 14px; border: 0; border-radius: 20px; cursor: pointer;
  background: transparent; color: var(--text); font-size: 15px; font-weight: 500; transition: background-color .2s, color .2s;
}
.tool svg { width: 18px; height: 18px; color: var(--purple); }
.tool:hover { background: rgba(97, 3, 172, .08); color: var(--purple); }

/* Full screen: the phone fills the viewport. fitPhone() reads the paddings, the gaps and
   grid-auto-flow (column: the tools beside the phone) of .cfg-viewer. The padding keeps
   clear of notches and home indicators (viewport-fit=cover). */
.cfg-viewer:fullscreen {
  --fs-pad: 24px; display: grid; place-items: center; align-content: center; background: radial-gradient(circle at 50% 40%, #f3eaff, var(--page) 70%);
  padding: max(var(--fs-pad), env(safe-area-inset-top)) max(var(--fs-pad), env(safe-area-inset-right)) max(var(--fs-pad), env(safe-area-inset-bottom)) max(var(--fs-pad), env(safe-area-inset-left));
}
.cfg-viewer:fullscreen .viewer-bar .tool[data-copy-link] { display: none; }
.cfg-viewer.is-pseudo-fullscreen {
  --fs-pad: 16px; position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; align-content: center; background: radial-gradient(circle at 50% 40%, #f3eaff, var(--page) 70%);
  padding: max(var(--fs-pad), env(safe-area-inset-top)) max(var(--fs-pad), env(safe-area-inset-right)) max(var(--fs-pad), env(safe-area-inset-bottom)) max(var(--fs-pad), env(safe-area-inset-left));
}
.cfg-viewer.is-pseudo-fullscreen .tool[data-copy-link] { display: none; }
html.has-pseudo-fullscreen { overflow: hidden; }
/* Short landscape screens: the tools stand beside the phone, which takes the whole height. */
@media (orientation: landscape) and (max-height: 500px) {
  .cfg-viewer:fullscreen { grid-auto-flow: column; justify-content: center; column-gap: 16px; }
  .cfg-viewer:fullscreen .viewer-tools { flex-direction: column; }
  .cfg-viewer.is-pseudo-fullscreen { grid-auto-flow: column; justify-content: center; column-gap: 16px; }
  .cfg-viewer.is-pseudo-fullscreen .viewer-tools { flex-direction: column; }
}

/* Rail of thumbnails */
.rail { margin-top: 44px; }
/* Padding (and the same scroll-padding, so snapping keeps it) leaves room for the 3+3 px focus ring inside the scroller. */
.rail-list { display: flex; gap: 14px; margin: 0 -7px; padding: 6px 7px 16px; scroll-padding-inline: 7px; list-style: none; overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: thin; scrollbar-color: #7d2db1 transparent; }
.rail-item { flex: none; scroll-snap-align: start; }
.rail-button { display: grid; gap: 8px; width: 92px; padding: 0; border: 0; background: none; cursor: pointer; text-align: center; }
.rail-thumb { width: 92px; height: 189px; border-radius: 16px; object-fit: cover; background: linear-gradient(160deg, #3a2b5c, #1b1830); box-shadow: 0 0 0 1px rgba(120, 122, 129, .2); transition: box-shadow .2s, transform .2s; }
.rail-name { font-size: 13px; font-weight: 500; line-height: 1.2; color: #4a4b55; }
.rail-button:hover .rail-thumb { transform: translateY(-3px); }
.rail-button[aria-current="true"] .rail-thumb { box-shadow: 0 0 0 3px var(--purple); }
.rail-button[aria-current="true"] .rail-name { color: var(--purple); font-weight: 600; }

/* Why Rich Media */
.why { padding: 100px 0; }
.why-grid {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); grid-template-rows: auto 1fr;
  grid-template-areas: "copy orbit" "detail orbit"; gap: 0 50px; align-items: start;
}
/* DOM order is copy, orbit (the tablist), detail (the tabpanel): Tab goes tile -> panel. */
.why-copy { grid-area: copy; align-self: end; }
.orbit-wrap { grid-area: orbit; align-self: center; }
.why-detail { grid-area: detail; }
.why-panel { margin-top: 34px; outline-offset: 8px; }
.why-index { color: var(--purple); font-weight: 600; font-size: 16px; letter-spacing: .06em; }
.why-title { margin-top: 8px; font-size: 30px; line-height: 1.2; font-weight: 600; }
.why-text { margin-top: 12px; color: var(--muted); font-size: 19px; line-height: 1.5; max-width: 520px; }
.why-link { display: inline-flex; align-items: center; gap: 8px; margin-top: 18px; color: var(--purple); font-weight: 500; text-decoration: none; }
.why-link svg { width: 20px; height: 20px; transition: transform .2s; }
.why-link:hover svg { transform: translateX(4px); }
.why-panel.is-swapping > * { animation: why-in .45s var(--ease) both; }
@keyframes why-in { from { opacity: 0; transform: translateY(8px); } }
.why-controls { display: flex; align-items: center; gap: 18px; margin-top: 28px; }
.why-progress { display: flex; gap: 10px; }
.why-pause {
  display: grid; place-items: center; width: 40px; height: 40px; flex: none; border: 0; border-radius: 50%; cursor: pointer;
  background: #fff; color: var(--purple); box-shadow: 0 0 0 1px rgba(97, 3, 172, .2) inset; transition: background-color .2s, color .2s;
}
.why-pause:hover { background: var(--purple); color: #fff; }
.why-pause svg { width: 16px; height: 16px; }
.why-pause .icon-play { display: none; }
.why-pause[aria-pressed="true"] .icon-play { display: block; }
.why-pause[aria-pressed="true"] .icon-pause { display: none; }
.orbit.is-stopped .benefit-tile * { animation-play-state: paused !important; }
.why-progress span { position: relative; height: 4px; width: 40px; border-radius: 999px; background: rgba(120, 122, 129, .3); overflow: hidden; transition: width .4s var(--ease); }
.why-progress span.is-active { width: 150px; }
.why-progress span.is-active::after { content: ''; position: absolute; inset: 0; background: var(--purple); transform-origin: 0 50%; animation: why-progress var(--why-duration, 5s) linear forwards; }
.why-progress.is-paused span.is-active::after { animation: none; transform: none; }
.why-progress.is-static span.is-active::after { animation: none; transform: none; }
@keyframes why-progress { from { transform: scaleX(0); } }

.orbit-wrap { display: grid; place-items: center; }
.orbit { position: relative; width: 100%; max-width: 620px; aspect-ratio: 620 / 540; container-type: inline-size; }
.orbit-bg, .orbit-lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.orbit-word { font-family: 'Gilroy', Arial, sans-serif; font-size: 13px; font-weight: 600; letter-spacing: .2em; fill: var(--muted); }
.orbit-lines .base { fill: none; stroke: #787A81; stroke-opacity: .3; stroke-width: 2; }
.orbit-lines .live { fill: none; stroke: url(#orbit-gradient); stroke-width: 2.5; stroke-linecap: round; transition: stroke-dashoffset 1s var(--ease); }
.orbit-centre {
  position: absolute; left: 25.8%; top: 37.9%; width: 48.4%; height: 24.1%; display: grid; place-content: center; justify-items: center; gap: .6cqw;
  border-radius: 4.8cqw; background: rgba(255, 255, 255, .85); box-shadow: 0 0 0 2px rgba(120, 122, 129, .3); transition: box-shadow .5s ease-in-out;
}
.orbit.has-active .orbit-centre { box-shadow: 0 0 0 2px rgba(147, 44, 229, .18), 0 0 26px -8px var(--purple); }
.orbit-centre img { width: 24cqw; height: auto; }
.orbit-centre-tag { color: #0a7366; font-size: max(12px, 2.2cqw); font-weight: 500; }
.orbit-tiles { position: absolute; inset: 0; }
.benefit-tile {
  position: absolute; width: 14.2cqw; height: 14.2cqw; padding: 2.3cqw; border: 0; border-radius: 3.5cqw; cursor: pointer;
  background: rgba(255, 255, 255, .85); box-shadow: 0 0 0 2px #fff inset, 0 8px 18px -10px rgba(49, 50, 91, .25);
  filter: grayscale(.7); transition: filter .25s ease-in-out, transform .25s ease-in-out, box-shadow .25s ease-in-out;
}
.benefit-tile svg { width: 100%; height: 100%; }
.benefit-tile:hover, .benefit-tile.is-active { filter: grayscale(0); transform: scale(1.06); box-shadow: 0 0 0 2px #fff inset, 0 0 22px rgba(97, 3, 172, .22); }
.benefit-tile:focus-visible { outline-offset: 4px; border-radius: 3.5cqw; }
.tile-label {
  position: absolute; left: 50%; top: calc(100% + 1.4cqw); padding: 3px 11px; border-radius: 20px; background: #fff; box-shadow: 0 4px 14px rgba(33, 33, 52, .12);
  color: var(--purple); font-size: max(12px, 2.3cqw); font-weight: 500; white-space: nowrap; pointer-events: none;
  opacity: 0; transform: translate(-50%, -5px) scale(.95); transition: opacity .25s, transform .25s;
}
.benefit-tile:hover .tile-label, .benefit-tile.is-active .tile-label { opacity: 1; transform: translate(-50%, 0) scale(1); }
.tile-1 { left: 24.2%; top: 9.3%; }
.tile-2 { left: 61.6%; top: 9.3%; }
.tile-3 { left: 81.5%; top: 41.9%; }
.tile-4 { left: 61.6%; top: 74.4%; }
.tile-5 { left: 24.2%; top: 74.4%; }
.tile-6 { left: 4.4%; top: 41.9%; }
.tile-6 .tile-label { left: 0; transform: translate(0, -5px) scale(.95); transform-origin: 0 50%; }
.tile-3 .tile-label { left: auto; right: 0; transform: translate(0, -5px) scale(.95); transform-origin: 100% 50%; }
.benefit-tile.tile-6:hover .tile-label, .benefit-tile.tile-6.is-active .tile-label,
.benefit-tile.tile-3:hover .tile-label, .benefit-tile.tile-3.is-active .tile-label { transform: translate(0, 0) scale(1); }

/* Contact */
.contact { padding: 30px 0 100px; }
.contact-card {
  position: relative; display: grid; grid-template-columns: minmax(0, 1.4fr) auto; gap: 40px; align-items: center; overflow: hidden;
  padding: 64px 70px; border-radius: 50px; color: #fff;
  background: radial-gradient(circle at 85% 20%, rgba(250, 103, 224, .55), transparent 45%), radial-gradient(circle at 10% 110%, rgba(3, 177, 247, .35), transparent 45%), linear-gradient(120deg, #4b0386, var(--purple) 45%, var(--purple-hover));
  box-shadow: var(--shadow-max);
}
.contact-copy h2 { max-width: 640px; }
.contact-copy p { margin-top: 16px; max-width: 640px; color: #fff; font-size: 19px; } /* solid: the pink glow behind it on phones */
.contact-actions { display: grid; gap: 12px; justify-items: stretch; }

/* Footer */
.site-footer { background: var(--navy); color: #fff; }
.footer-grid { display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 40px 90px; padding: 70px var(--gutter) 60px; }
.footer-brand p { margin-top: 18px; max-width: 340px; color: rgba(255, 255, 255, .7); font-size: 16px; }
.footer-brand img { width: 120px; height: auto; }
.footer-head { font-weight: 600; font-size: 18px; margin-bottom: 14px; }
.footer-links { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; color: rgba(255, 255, 255, .85); font-size: 17px; }
.footer-links a { text-decoration: none; }
.footer-links a:hover { color: #fff; text-decoration: underline; text-underline-offset: 4px; }
.socials { display: flex; gap: 12px; margin-top: 18px; }
.socials a { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: #fff; color: var(--navy); transition: background-color .2s, color .2s; }
.socials a:hover { background: var(--purple-hover); color: #fff; }
.socials svg { width: 20px; height: 20px; }
.footer-bottom { background: rgba(255, 255, 255, .06); }
.footer-bottom-inner { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 30px; padding-top: 18px; padding-bottom: 18px; color: rgba(255, 255, 255, .7); font-size: 15px; }

/* Wide layouts: option labels stay on one line; the list may be wider than its button.
   At 1231 px and up the filters are the right-hand column, so the list grows to the left. */
@media (min-width: 1001px) {
  .dd-label { white-space: nowrap; }
  .dd-list { right: auto; min-width: 100%; width: max-content; max-width: calc(100vw - 2 * var(--gutter)); }
}
@media (min-width: 1231px) {
  .dd-list { left: auto; right: 0; }
}
/* Wide layouts: the viewer column stays on screen while the info card (with the
   personalisation switches) scrolls past it. fitPhone() sizes the column to fit below
   the header with room to spare; very short windows, where it cannot, keep the normal flow. */
@media (min-width: 1001px) and (min-height: 540px) {
  .cfg-viewer { position: sticky; top: calc(var(--header-h) + 16px); }
}
/* From 1001 px the viewer column is as wide as its tools row, which is widest in Polish (the static
   HTML): keep that width in every language, so the columns beside it do not move when app.js
   translates the page (e2e "language-independent widths"). Tighter tools keep the reserve small
   (PL 572 px, DE 559, EN 453), so English and German do not lose much of the side columns. */
@media (min-width: 1001px) {
  .tool { padding: 8px 10px; gap: 6px; }
  .viewer-tools { gap: 2px; }
  .cfg-viewer { min-width: 572px; }
}
/* From 1001 px the gallery is in the first view, so the phone gets its fitted size before app.js
   runs: the same budget as fitPhone() for wide screens (window height minus the 94 px header, the
   73 px tools row, 77 px with touch, and 110 px; at most 760 px; at least min(320 px, height minus
   110 px)) over the 838 px phone, a length divided by a length (typed arithmetic). fitPhone() then
   sets the same value (e2e "the phone is sized right at boot"). Older browsers keep the default. */
@supports (scale: calc(100dvh / 1px)) {
  @media (min-width: 1001px) {
    .phone-stage {
      --fit-h: max(min(100dvh - 277px, 760px), min(320px, 100dvh - 110px));
      --phone-scale: max(.3, min(1, var(--fit-h) / 838px));
    }
  }
  @media (min-width: 1001px) and (pointer: coarse) {
    .phone-stage { --fit-h: max(min(100dvh - 281px, 760px), min(320px, 100dvh - 110px)); }
  }
}

/* Responsive */
@media (max-width: 1230px) {
  :root { --container: 964px; --gutter: 12px; }
  .main-nav { display: none; }
  .header-cta { margin-left: auto; }
  .configurator {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto auto 1fr;
    grid-template-areas: "intro viewer" "filters viewer" "info viewer" "qr viewer";
  }
}
@media (max-width: 1000px) {
  :root { --header-h: 76px; }
  .hero-grid { grid-template-columns: 1fr; }
  .why-grid { grid-template-columns: 1fr; grid-template-rows: none; grid-template-areas: "copy" "orbit" "detail"; gap: 24px; }
  .why-copy { align-self: start; }
  .hero { padding-bottom: 60px; }
  .showreel { aspect-ratio: 16 / 10; }
  .configurator { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; grid-template-areas: "intro" "filters" "viewer" "info"; gap: 22px; }
  /* The switches sit right under the phone, before the description and their own
     explanation, so the phone and the switches share the screen after a tap. */
  .demo { order: -1; }
  .demo-text { order: 1; }
  .cfg-filters { grid-template-columns: 1fr 1fr; padding: 18px; gap: 14px; }
  .filter-status { grid-column: 1 / -1; }
  .qr-card { display: none !important; }
  .contact-card { grid-template-columns: 1fr; padding: 44px 32px; border-radius: 36px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 730px) {
  body { font-size: 17px; }
  .header-cta { display: none; }
  .brand-tag { display: none; }
  .lang { margin-left: auto; }
  .hero { padding-top: 10px; }
  .showreel { border-radius: 26px; }
  .viewer { gap: 10px; }
  .arrow { width: 46px; height: 46px; }
  .arrow svg { width: 22px; height: 22px; }
  .phone-stage { --phone-scale: .55; } /* before JS: phone + arrows fit 350px and up */
  .cfg-viewer:fullscreen { --fs-pad: 8px; gap: 10px; }
  .cfg-viewer.is-pseudo-fullscreen { --fs-pad: 8px; gap: 10px; }
  .cfg-filters { grid-template-columns: 1fr; }
  .dd-button { min-height: 50px; font-size: 17px; }
  .info-card { padding: 22px; }
  .info-brand { font-size: 26px; }
  .why { padding: 70px 0; }
  .footer-grid { grid-template-columns: 1fr; gap: 32px; }
  .why-progress { gap: 8px; }
  .why-progress span { width: 22px; }
  .why-progress span.is-active { width: 96px; }
}
/* Wide screens: "Kopiuj link" keeps its text and width (no column moves) and the confirmation
   shows as a bubble under the tool (app.js sets data-copied). */
.tool[data-copy-link] { position: relative; }
.tool.is-copied::after {
  content: attr(data-copied); position: absolute; left: 50%; top: calc(100% + 6px); z-index: 5; transform: translateX(-50%);
  padding: 5px 12px; border-radius: 14px; background: var(--navy); color: #fff; font-size: 14px; font-weight: 500; white-space: nowrap; pointer-events: none;
}
/* Phones, and short landscape screens up to 1000 px: the tools are icons (their names stay for
   screen readers); "Link skopiowany" shows as a bubble under the copy tool. */
@media (max-width: 730px), (max-width: 1000px) and (orientation: landscape) and (max-height: 500px) {
  .tool span { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .tool { position: relative; padding: 10px; }
  .tool.is-copied::after { content: none; } /* the label itself is the bubble here */
  .tool.is-copied span {
    left: 50%; top: calc(100% + 4px); z-index: 5; width: auto; height: auto; margin: 0; overflow: visible; clip: auto;
    padding: 5px 12px; border-radius: 14px; background: var(--navy); color: #fff; font-size: 14px; transform: translateX(-50%);
  }
  .tool svg { width: 22px; height: 22px; }
}

@media (max-width: 730px) and (orientation: portrait) {
  .showreel { aspect-ratio: 4 / 5; } /* matches the 4:5 clip initShowreel() picks for an upright phone */
  /* Full screen on an upright phone: the phone takes the whole width and the arrows join the tools
     row under it (.viewer drops its box), so nothing covers the creative. The auto columns share the
     phone's width, which puts the arrows under its edges. fitPhone() reads display: contents on
     .viewer as "the arrows take no width". Separate rules: an unknown :fullscreen drops the list. */
  .cfg-viewer:fullscreen { grid-template: "stage stage stage" auto "prev bar next" auto / auto auto auto; justify-content: center; }
  .cfg-viewer:fullscreen .viewer { display: contents; }
  .cfg-viewer:fullscreen .phone-stage { grid-area: stage; }
  .cfg-viewer:fullscreen .viewer-bar { grid-area: bar; }
  .cfg-viewer:fullscreen .arrow-prev { grid-area: prev; justify-self: start; align-self: end; }
  .cfg-viewer:fullscreen .arrow-next { grid-area: next; justify-self: end; align-self: end; }
  .cfg-viewer.is-pseudo-fullscreen { grid-template: "stage stage stage" auto "prev bar next" auto / auto auto auto; justify-content: center; }
  .cfg-viewer.is-pseudo-fullscreen .viewer { display: contents; }
  .cfg-viewer.is-pseudo-fullscreen .phone-stage { grid-area: stage; }
  .cfg-viewer.is-pseudo-fullscreen .viewer-bar { grid-area: bar; }
  .cfg-viewer.is-pseudo-fullscreen .arrow-prev { grid-area: prev; justify-self: start; align-self: end; }
  .cfg-viewer.is-pseudo-fullscreen .arrow-next { grid-area: next; justify-self: end; align-self: end; }
}
/* Upright phones: a long list of personalisation switches (the cities, four or more) is one row
   that scrolls sideways (seven cities would take three or four rows), so after a switch most of
   the phone above them stays on screen. The padding keeps the focus ring inside the row; app.js
   scrolls the chosen switch into view. Two or three switches (weather, pollen) wrap instead, so
   none starts scrolled out of view. Wider upright screens (561-730 px) have room for the rows. */
@media (max-width: 560px) and (orientation: portrait) {
  .demo-options:has(> :nth-child(4)) { flex-wrap: nowrap; overflow-x: auto; margin: -6px -18px; padding: 6px 18px; scrollbar-width: thin; scrollbar-color: #7d2db1 transparent; }
  .demo-options:has(> :nth-child(4)) .demo-option { flex: none; }
}
/* Short landscape screens from 600 to 1000 px (a phone on its side, a laptop at 200% zoom): the
   tools stand beside the phone and the info card beside both, so the creative, its tools and the
   personalisation switches (first in the card) share one screen. fitPhone() reads
   grid-auto-flow: column on .cfg-viewer as "the tools are beside the phone" and keeps the card its
   min-width (the specs list needs 188 px, plus the card's padding), so the page never scrolls
   sideways; below 600 px the phone at its smallest (117 px) leaves no such room and the page keeps
   one column.
   The counter keeps one width (the widest is "39 von 39"), so the phone column does not change with
   the language, the position or the catalogue load. */
@media (min-width: 600px) and (max-width: 1000px) and (orientation: landscape) and (max-height: 500px) {
  .configurator { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "intro intro" "filters filters" "viewer info"; }
  .cfg-viewer { grid-auto-flow: column; align-items: center; column-gap: 12px; }
  .cfg-info { min-width: 232px; } /* 188 + 2 x 22 px */
  @media (min-width: 731px) { .cfg-info { min-width: 244px; } } /* the padding is 28 px there */
  .counter { min-width: 4.75em; text-align: center; }
  /* Before JS: the smallest phone, so the row fits from 600 px (a wider page would make a mobile
     browser zoom out and report a taller viewport to fitPhone()). */
  .phone-stage { --phone-scale: .3; }
  .viewer-tools { flex-direction: column; }
  .tool.is-copied span { left: calc(100% + 4px); top: 50%; transform: translateY(-50%); }
}
/* There the viewer column also stays on screen while the info card scrolls past it, like on wide
   screens: fitPhone() gives it the height under the header, which it fills from 344 px (lower, the
   phone at its smallest scale is taller than that room, and a sticky phone would hide its bottom).
   revealViewer() measures the column's place from the row it shares with the info card. */
@media (min-width: 600px) and (max-width: 1000px) and (orientation: landscape) and (min-height: 344px) and (max-height: 500px) {
  .cfg-viewer { position: sticky; top: calc(var(--header-h) + 8px); }
}
/* Touch screens: personalisation switches and tools at 44 px, the size of a fingertip. */
@media (pointer: coarse) {
  .demo-option { min-height: 44px; }
  .tool { min-width: 44px; min-height: 44px; justify-content: center; }
  .why-pause { width: 44px; height: 44px; }
}
@media (max-width: 349px) {
  .phone-stage { --phone-scale: .45; } /* before JS */
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  /* The rule above gives every element a .01ms transition of all properties, so a menu and
     its items would stay visibility:hidden for one more frame and focus could not enter them. */
  .dd-list, .dd-list *, .lang-menu, .lang-menu * { transition: none !important; }
}
