/* One stylesheet, no build step. Change the colours here. */

:root {
  /* The palette */
  --navy: #253c6d; /* page background */
  --navy-2: #30497d; /* cards, pop-up */
  --navy-3: #455b8a; /* borders, highlights */
  --orange: #f2842f; /* accent: buttons, prices, active tab */

  /* Text colours chosen to read well on the blues above */
  --text: #f3f6fc;
  --text-soft: #c5cfe4;
  --on-orange: #16264a;
  --danger: #ffb8ab;

  --border: rgba(255, 255, 255, 0.1);
  --shadow-soft: 0 18px 45px rgba(10, 20, 45, 0.35);
  --font-family: 'Roboto', system-ui, sans-serif;

  /* Room left at the top of each panel for the banner */
  --header-space: 4.5rem;

  /* The space between the window's edges and the content (same as the banner's). */
  --gutter: clamp(1.25rem, 3vw, 3.5rem);

  /* The largest a "fit-image" photo may be drawn; each area sets its own. */
  --fit-h: 60dvh;
  --fit-w: 80vw;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  min-height: 100%;
  width: 100%;
}

html {
  /* A sideways swipe that reaches the end of a row of pictures must not be
     taken by the browser as "go back to the previous web page". */
  overscroll-behavior-x: none;
  background: var(--navy);
  color-scheme: dark;
  scrollbar-color: var(--navy-3) transparent;
}

body {
  overscroll-behavior-x: none;
  background:
    radial-gradient(circle at top left, rgba(69, 91, 138, 0.55), transparent 40%),
    radial-gradient(circle at bottom right, rgba(48, 73, 125, 0.7), transparent 45%),
    var(--navy);
  color: var(--text);
  display: flex;
  flex-direction: column;
  font-family: var(--font-family);
  min-height: 100dvh;
}

/* The single page: the window itself never scrolls, the panels do. */
body.is-panels {
  height: 100dvh;
  overflow: hidden;
}

a {
  color: inherit;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent; /* no grey flash on phones when a link is touched */
}

/* Browsers can show a blinking text cursor on ordinary text (Edge and Chrome
   do after F7, "caret browsing", is pressed). Only the form's boxes take
   typing, so only they show it. */
body {
  caret-color: transparent;
}

input,
textarea {
  caret-color: var(--text);
}

img {
  max-width: 100%;
}

button,
input,
textarea,
select {
  font: inherit;
}

button {
  border: none;
  border-radius: 999px;
  cursor: pointer;
  transition: transform 0.2s ease, opacity 0.2s ease, box-shadow 0.2s ease;
}

button:hover {
  opacity: 0.92;
  transform: translateY(-1px);
}

input,
textarea,
select {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--navy-3);
  border-radius: 18px;
  color: var(--text);
  padding: 0.9rem 1rem;
  width: 100%;
}

::placeholder {
  color: var(--text-soft);
  opacity: 0.7;
}

input:focus,
textarea:focus,
select:focus {
  border-color: var(--orange);
  box-shadow: 0 0 0 3px rgba(242, 132, 47, 0.2);
  outline: none;
}

:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 2px;
}

.visually-hidden {
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.container {
  padding: 0 var(--gutter);
  width: 100%;
}

.site-main {
  flex: 1;
  min-height: 0; /* lets the panels, not the page, do the scrolling */
}

/* ---------- Banner: site name and tabs over the top-left, no background ---------- */

.site-header {
  align-items: center;
  display: flex;
  /* The text scales with the window so the banner stays within the left half. */
  font-size: clamp(0.7rem, 0.92vw, 0.95rem);
  gap: 0.9em;
  left: var(--gutter);
  max-width: calc(50% - 2rem);
  position: fixed;
  /* Keeps the words readable where they sit over a photo. */
  text-shadow: 0 1px 8px rgba(16, 28, 58, 0.9);
  top: 1rem;
  z-index: 20;
}

.site-brand {
  font-size: 0.92em;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Phones only (see the end of this file). */
.menu-toggle,
.menu-languages {
  display: none;
}

/* On computers this wrapper does not exist as a box: the tabs sit directly in the banner's row. */
.site-menu {
  display: contents;
}

.site-nav {
  display: flex;
  flex-wrap: nowrap;
  min-width: 0;
  overflow-x: auto; /* only matters if many categories are added */
  scrollbar-width: none;
}

.site-nav::-webkit-scrollbar {
  display: none;
}

.nav-link {
  border-bottom: 2px solid transparent;
  color: var(--text-soft);
  font-weight: 500;
  margin: 0 0.6em;
  padding: 0.5em 0 0.3em;
  transition: border-color 0.3s ease, color 0.3s ease;
  white-space: nowrap;
}

.nav-link:hover {
  color: var(--text);
}

/* The tab of the panel on screen: just an underline. */
.nav-link.is-active {
  border-bottom-color: var(--orange);
  color: var(--text);
}

.language-toggle {
  align-items: center;
  display: inline-flex;
  font-size: 0.85rem;
  gap: 0.4rem;
  position: fixed;
  right: 1.25rem;
  text-shadow: 0 1px 8px rgba(16, 28, 58, 0.9);
  top: 1.25rem;
  z-index: 20;
}

.language-toggle a {
  color: var(--text-soft);
  padding: 0.2rem;
}

.language-toggle .separator {
  opacity: 0.45;
}

.language-toggle .is-active {
  color: var(--orange);
  font-weight: 700;
}

/* ---------- The sliding panels ---------- */

/* The pages sit side by side. Only site.js moves between them ("hidden"
   still lets a script scroll; it only stops the browser doing it by itself). */
.single-page-layout {
  display: flex;
  height: 100%;
  outline: none;
  overflow: hidden;
}

.single-page-layout::-webkit-scrollbar {
  display: none;
}

.panel-section {
  flex: 0 0 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* Each panel scrolls up and down on its own, and only when its content is
   taller than the screen. */
.panel-section-inner {
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  padding-bottom: 2rem;
  padding-top: var(--header-space);
  scrollbar-width: none; /* no scrollbar: the arrows below show there is more */
  /* The banner has no background, so content scrolling up fades out before
     it would run underneath the tabs. */
  -webkit-mask-image: linear-gradient(to bottom, transparent calc(var(--header-space) - 1.6rem), #000 var(--header-space));
  mask-image: linear-gradient(to bottom, transparent calc(var(--header-space) - 1.6rem), #000 var(--header-space));
}

.panel-section-inner::-webkit-scrollbar {
  display: none;
}

/* "There is more above / below": small round arrows at the top and bottom
   of a panel whose content is taller than the screen. Clicking one scrolls. */
.panel-arrow {
  align-items: center;
  background: transparent;
  border-radius: 50%;
  color: var(--text);
  filter: drop-shadow(0 1px 4px rgba(5, 12, 30, 0.9)); /* keeps the arrow visible over photos */
  display: flex;
  height: 40px;
  justify-content: center;
  left: calc(50% - 20px);
  position: absolute;
  transition: opacity 0.35s ease;
  width: 40px;
  z-index: 5;
}

.panel-arrow[hidden] {
  display: flex !important; /* stays in place, only fades */
  opacity: 0;
  pointer-events: none;
}

.panel-arrow-up {
  top: calc(var(--header-space) - 0.25rem);
}

.panel-arrow-down {
  animation: bob 1.6s ease-in-out infinite;
  bottom: 1rem;
}

/* Content fades in softly when its panel comes into view. The "js" class is
   added by a script in base.html, so without JavaScript nothing is hidden. */
.js .panel-section-inner > * {
  opacity: 0;
  transition: opacity 0.9s cubic-bezier(0.4, 0, 0.2, 1);
}

.js .panel-section.is-current .panel-section-inner > * {
  opacity: 1;
}

.single-page-heading {
  padding-top: 1.5rem;
}

.single-page-heading h2 {
  font-size: clamp(2.2rem, 4vw, 4rem);
  margin-bottom: 0.7rem;
}

.single-page-heading p {
  color: var(--text-soft);
  line-height: 1.7;
}

/* ---------- Home panel ---------- */

.panel-home .panel-section-inner {
  -webkit-mask-image: none;
  mask-image: none;
  overflow: hidden;
  padding: 0;
  position: relative;
}

/* The photo fills the right half, top to bottom. "luminosity" keeps its light
   and shadow but takes the colour from the blue behind it, and the mask
   fades its left edge away, so it melts into the background. */
.hero-photo {
  height: 100%;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 45%);
  mask-image: linear-gradient(to right, transparent, #000 45%);
  mix-blend-mode: luminosity;
  object-fit: cover;
  object-position: center 35%;
  position: absolute;
  right: 0;
  top: 0;
  width: 50%;
}

/* The text takes the left half, centred in the space under the banner. It
   only scrolls if the window is too short to show it all. */
.hero-text {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow-y: auto;
  padding: var(--header-space) 2.5rem 1.5rem clamp(1.25rem, 3vw, 3.5rem);
  scrollbar-width: thin;
  width: 50%;
}

.hero-description {
  color: var(--text);
  /* As large as fits: scales with the window's width and height. */
  font-size: clamp(1rem, min(0.55rem + 0.62vw, 2.45vh), 1.45rem);
  hyphens: auto;
  line-height: 1.62;
  margin: auto 0;
  text-align: justify;
}

.hero-description p + p {
  margin-top: 1em;
}

.eyebrow {
  color: var(--orange);
  display: inline-block;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  margin-bottom: 1rem;
  text-transform: uppercase;
}

/* ---------- Buttons ---------- */

.button-link,
button.primary {
  align-items: center;
  border-radius: 999px;
  display: inline-flex;
  font-weight: 700;
  justify-content: center;
  min-height: 50px;
  padding: 0.9rem 1.4rem;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.primary-link,
button.primary,
.floating-cta {
  background: var(--orange);
  box-shadow: 0 12px 28px rgba(242, 132, 47, 0.25);
  color: var(--on-orange);
}

.button-link:hover {
  transform: translateY(-1px);
}

.floating-cta {
  border-radius: 999px;
  bottom: 1.5rem;
  font-weight: 700;
  padding: 0.95rem 1.35rem;
  position: fixed;
  right: 1.5rem;
  transition: opacity 0.4s ease, transform 0.2s ease;
  z-index: 25;
}

.floating-cta:hover {
  transform: translateY(-2px);
}

/* Hidden while the contact panel is on screen. */
.floating-cta.is-hidden {
  opacity: 0;
  pointer-events: none;
}

/* ---------- Product cards (the Products panel) ---------- */

.catalog-section {
  padding: 1rem 0 2rem;
}

/* One group of products: its title and description, then its grid. */
.product-group + .product-group {
  margin-top: 1.5rem;
}

.product-group:last-child .catalog-section {
  padding-bottom: 4.5rem; /* room so the last row clears the contact button */
}

.product-group-heading {
  max-width: calc(52rem + 2 * var(--gutter));
  padding-top: 1rem;
}

.product-group-heading h3 {
  font-size: clamp(1.6rem, 2.6vw, 2.4rem);
  margin-bottom: 0.6rem;
}

.product-group-heading p {
  color: var(--text-soft);
  line-height: 1.7;
}

.product-group-heading p + p {
  margin-top: 0.8em;
}

.products-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(min(290px, 100%), 1fr));
}

.product-card {
  background: var(--navy-2);
  border: 1px solid var(--border);
  border-radius: 22px;
  display: block;
  -webkit-user-drag: none; /* a press-and-move on a phone swipes the photos, never drags the card away */
  overflow: hidden;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

/* Lift on mouse-over, on computers only: phones treat the first touch as a
   "hover" and keep it, which looked like a stuck highlight and nudged the
   card just as a swipe began. */
@media (hover: hover) {
  .product-card:hover {
    border-color: var(--navy-3);
    box-shadow: var(--shadow-soft);
    transform: translateY(-4px);
  }

  .corridor-item a:hover img {
    box-shadow: var(--shadow-soft);
    transform: translateY(-3px);
  }
}

.product-media {
  display: block;
  padding: 0.4rem 0.4rem 0; /* a thin frame, so the picture takes nearly the whole card */
  position: relative;
}

/* "This product has more photos": a small badge in the corner of its picture. */
.photo-count {
  align-items: center;
  backdrop-filter: blur(6px);
  background: rgba(22, 38, 74, 0.72);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  display: inline-flex;
  font-size: 0.8rem;
  font-weight: 600;
  gap: 0.3rem;
  padding: 0.25rem 0.6rem;
  position: absolute;
  right: 0.6rem;
  top: 0.6rem;
}

.product-media .photo-count {
  right: 1.6rem;
  top: 1.6rem;
}

.product-image {
  border-radius: 24px;
  display: block;
  height: auto;
  width: 100%;
}

.product-card .product-image {
  aspect-ratio: 4 / 3;
  background: transparent; /* around a photo of another shape, the card itself shows */
  border-radius: 18px;
  object-fit: contain; /* the whole photo, never cropped */
}

/* A card's photos in a row that can be swiped, one at a time. */
.card-carousel {
  border-radius: 18px;
  display: flex;
  overflow-x: auto;
  overscroll-behavior-x: none; /* a swipe here never moves the page, nor goes "back" */
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.card-carousel::-webkit-scrollbar {
  display: none;
}

.card-carousel .product-image {
  border-radius: 0;
  flex: 0 0 100%;
  scroll-snap-align: start;
  width: 100%;
}

/* Small round arrows, shown when the pointer is over the card (computers). */
.carousel-arrow {
  align-items: center;
  background: rgba(22, 38, 74, 0.72);
  border-radius: 50%;
  color: var(--text);
  display: flex;
  height: 34px;
  justify-content: center;
  opacity: 0;
  position: absolute;
  top: calc(50% - 9px);
  transition: opacity 0.2s ease;
  width: 34px;
}

.carousel-prev {
  left: 0.9rem;
}

.carousel-next {
  right: 0.9rem;
}

.product-card:hover .carousel-arrow {
  opacity: 1;
}

@media (hover: none) {
  .carousel-arrow {
    display: none;
  }
}

/* One dot per photo; the current one is brighter. */
.carousel-dots {
  bottom: 0.7rem;
  display: flex;
  gap: 5px;
  justify-content: center;
  left: 0;
  pointer-events: none;
  position: absolute;
  right: 0;
}

.carousel-dots span {
  background: rgba(255, 255, 255, 0.45);
  border-radius: 50%;
  height: 6px;
  transition: background 0.2s ease, transform 0.2s ease;
  width: 6px;
}

.carousel-dots span.is-current {
  background: #fff;
  transform: scale(1.25);
}

.product-image-placeholder {
  align-items: center;
  background:
    linear-gradient(135deg, rgba(37, 60, 109, 0.85), rgba(69, 91, 138, 0.85)),
    repeating-linear-gradient(
      -45deg,
      rgba(255, 255, 255, 0.05),
      rgba(255, 255, 255, 0.05) 10px,
      rgba(255, 255, 255, 0.1) 10px,
      rgba(255, 255, 255, 0.1) 20px
    );
  color: var(--text-soft);
  display: flex;
  font-size: 1.1rem;
  justify-content: center;
  padding: 1rem;
  text-align: center;
}

.product-card-content {
  padding: 0.8rem 0.95rem 0.95rem;
}

.product-card h3 {
  font-size: 1rem;
  line-height: 1.3;
  margin-bottom: 0.3rem;
}

.product-card p {
  font-size: 0.85rem;
  line-height: 1.5;
}

.product-card p,
.empty-state p {
  color: var(--text-soft);
  line-height: 1.7;
}

.product-price {
  color: var(--orange);
  font-weight: 700;
}

.product-card .product-price {
  font-size: 0.92rem;
  margin-top: 0.5rem;
}

.empty-state {
  background: rgba(48, 73, 125, 0.6);
  border: 1px solid var(--border);
  border-radius: 28px;
  grid-column: 1 / -1;
  padding: 1.5rem;
  text-align: center;
}

.inline-link {
  color: var(--orange);
  display: inline-block;
  font-weight: 600;
  margin-top: 1rem;
}

/* ---------- Photos that size themselves ---------- */

/* Draws a photo as large as its area allows (--fit-h tall, --fit-w wide)
   without stretching it or going beyond its real size. --w and --h are the
   photo's pixel size, written into the page by _photo.html, so the right
   space is reserved before the photo has loaded. */
.fit-image {
  aspect-ratio: var(--w) / var(--h);
  display: block;
  height: min(var(--fit-h), calc(var(--fit-w) * var(--h) / var(--w)), calc(var(--h) * 1px));
  max-height: var(--fit-h);
  max-width: var(--fit-w);
  object-fit: contain;
  width: auto;
}

/* ---------- Corridors: each group is one row of pictures that scrolls sideways ---------- */

.panel-category .panel-section-inner {
  display: flex;
  flex-direction: column;
}

/* All the groups of a category, one under the other. A single group sits in
   the middle of the screen; several make the panel scroll up and down. */
.corridors {
  display: grid;
  gap: 1.25rem;
  margin: auto 0;
  padding: 0.25rem 0 1rem;
}

/* The box around one group. It hugs its content and is very lightly tinted,
   so it is clear where a swipe moves the pictures (inside) and where it moves
   to the next page (outside). */
.corridor-wrap {
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 22px;
  margin: 0 var(--gutter);
  min-width: 0;
  overflow: hidden;
  position: relative;
}

.corridor {
  overscroll-behavior-x: none; /* reaching the end of the pictures never slides the page, nor goes "back" */
  --fit-h: min(56dvh, 640px);
  --fit-w: min(78vw, 900px);
  align-items: center; /* shorter items sit in the middle of the tallest one's height */
  display: flex;
  gap: 1.25rem;
  outline: none;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.4rem; /* the same thin frame as the product cards */
  scrollbar-width: none; /* no scrollbar: the round arrows show there is more */
}

.corridor::-webkit-scrollbar {
  display: none;
}

/* While the row is being dragged with the mouse. */
.corridor.is-dragging {
  cursor: grabbing;
  user-select: none;
}

.corridor.is-dragging a {
  pointer-events: none;
}

/* One picture (or video) with its description underneath. The box is as
   wide as the picture, so a long description wraps under it. */
.corridor-item {
  display: flex;
  flex: none;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0;
  width: min-content;
}

.corridor-item a {
  display: block;
  position: relative;
}

.corridor-item a[data-zoom] {
  cursor: zoom-in;
}

.corridor-item img,
.corridor-placeholder {
  border-radius: 16px;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.corridor-placeholder {
  height: 14rem;
  width: 18rem;
}

.corridor-item figcaption {
  -webkit-box-orient: vertical;
  color: var(--text-soft);
  display: -webkit-box;
  font-size: 0.9rem;
  -webkit-line-clamp: 3; /* at most three lines; the rest is cut with "..." */
  line-clamp: 3;
  line-height: 1.45;
  overflow: hidden;
}

.corridor-item figcaption strong {
  color: var(--text);
  margin-right: 0.5em;
}

.corridor .empty-state {
  flex: 1;
}

/* The group's title and description: the first thing in the row, so they
   slide away as the pictures are scrolled. Narrow, so each line holds several
   words. The description shows at most 8 lines; a longer one scrolls in its
   own box, with a faint scrollbar on the left. */
.corridor-text {
  flex: none;
  padding: 0.5rem 0.5rem 0.5rem 0.6rem;
  width: min(17rem, 64vw);
}

.corridor-text h3 {
  font-size: clamp(1.15rem, 1.5vw, 1.45rem);
  line-height: 1.25;
  margin-bottom: 0.5rem;
}

.corridor-text-scroll {
  direction: rtl; /* puts the scrollbar on the left */
  font-size: 0.92rem;
  line-height: 1.55;
  max-height: calc(8 * 1.55em); /* 8 lines */
  overflow-y: auto;
  scrollbar-color: rgba(255, 255, 255, 0.16) transparent;
  scrollbar-width: thin;
}

.corridor-text-body {
  color: var(--text-soft);
  direction: ltr;
}

/* Room for the scrollbar, only when there is one (the box is full). */
.corridor-text-scroll.is-scrollable .corridor-text-body {
  padding-left: 0.6rem;
}

.corridor-text-body p + p {
  margin-top: 0.7em;
}

/* ---------- Videos in a corridor ---------- */

.video-box {
  position: relative;
}

.video-box video {
  background: var(--navy-2);
  border-radius: 18px;
}

/* A video whose size is not known yet (not an MP4): a sensible box until it loads. */
.video-box video:not([style]) {
  height: var(--fit-h);
  max-width: var(--fit-w);
}

/* The speaker button: crossed out while silent. */
.video-sound {
  align-items: center;
  backdrop-filter: blur(6px);
  background: rgba(22, 38, 74, 0.72);
  border: 1px solid var(--border);
  border-radius: 50%;
  bottom: 0.6rem;
  color: var(--text);
  display: flex;
  height: 40px;
  justify-content: center;
  position: absolute;
  right: 0.6rem;
  width: 40px;
}

.video-sound .sound-on,
.video-sound.is-on .sound-off {
  display: none;
}

.video-sound.is-on .sound-on {
  display: inline;
}

.video-sound.is-on {
  background: var(--orange);
  color: var(--on-orange);
}

.corridor-arrow {
  align-items: center;
  backdrop-filter: blur(6px);
  background: rgba(22, 38, 74, 0.7);
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text);
  display: flex;
  height: 46px;
  justify-content: center;
  position: absolute;
  top: calc(50% - 23px);
  width: 46px;
}

.corridor-prev {
  left: 0.5rem;
}

.corridor-next {
  right: 0.5rem;
}

/* Touch screens swipe instead. */
@media (hover: none) {
  .corridor-arrow {
    display: none;
  }
}

/* ---------- One product: in the pop-up and on its own page ---------- */

.product {
  display: grid;
  gap: 2rem;
  /* Photos as wide as the first photo; text as wide as it needs, up to a limit. */
  grid-template-columns: auto fit-content(22rem);
  justify-content: center;
}

.product-photos {
  display: grid;
  gap: 1rem;
  justify-items: center;
}

.product-photos a {
  cursor: zoom-in;
  display: block;
}

/* The first photo or video decides how wide the column (and so the pop-up)
   is. The others take that same width instead of stretching it: "width: 0"
   stops them from counting, "min-width: 100%" then fills the column. */
.product-photos > :not(:first-child):not(.more-photos),
.product-photos > :not(:first-child) :is(img, video) {
  min-width: 100%;
  width: 0;
}

.product-photos > :not(:first-child) :is(img, video) {
  height: auto;
  max-width: none;
}

.product-photos video {
  border-radius: 20px;
}

.product-photos img,
.product .product-image-placeholder {
  border-radius: 20px;
}

.product .product-image-placeholder {
  min-height: 320px;
  width: min(60vw, 420px);
}

.product-info {
  align-self: start;
  min-width: 14rem;
  position: sticky;
  top: 0;
}

.product-info h2 {
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  margin-bottom: 0.6rem;
}

.product-info .product-price {
  font-size: 1.3rem;
  margin-bottom: 1rem;
}

.product-description {
  color: var(--text-soft);
  line-height: 1.8;
  margin-bottom: 1.5rem;
}

.product-description p + p {
  margin-top: 1rem;
}

.product-page {
  --fit-h: calc(100dvh - var(--header-space) - 3rem);
  --fit-w: min(56vw, 820px);
  padding-bottom: 6rem;
  padding-top: calc(var(--header-space) + 1rem);
}

.product-page .product-info {
  top: calc(var(--header-space) + 1rem);
}

/* The pop-up is exactly as large as the product's photo and text need. */
.product-dialog {
  /* The first photo always fits whole inside the pop-up. */
  --fit-h: calc(100dvh - 5.5rem);
  --fit-w: min(56vw, 820px);
  background: var(--navy-2);
  border: 1px solid var(--navy-3);
  border-radius: 28px;
  box-shadow: 0 30px 80px rgba(5, 12, 30, 0.6);
  color: inherit;
  flex-direction: column;
  margin: auto;
  max-height: calc(100dvh - 2rem);
  max-width: calc(100vw - 2rem);
  outline: none;
  overflow: hidden;
  padding: 0;
  width: fit-content;
}

.product-dialog[open] {
  display: flex;
}

.dialog-body {
  min-height: 0;
  overflow-y: auto;
  padding: 1.5rem;
  scrollbar-width: thin;
}

.product-dialog .product-info {
  padding-top: 2.25rem; /* clears the close button */
}

.product-dialog::backdrop {
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  background: rgba(12, 22, 48, 0.55);
}

/* Opening: the photo that was clicked grows into the pop-up's photo (a "view
   transition", started in site.js) while the rest fades in. Browsers without
   that feature get a plain fade. */
.product-dialog .product-photos a:first-child img {
  view-transition-name: product-photo;
}

::view-transition-group(product-photo) {
  animation-duration: 0.5s;
  animation-timing-function: cubic-bezier(0.3, 0, 0.15, 1);
}

::view-transition-old(product-photo),
::view-transition-new(product-photo) {
  height: 100%;
  object-fit: cover;
  width: 100%;
}

/* "root" is everything else on the page, including the pop-up's own box,
   corners and shadow. Opening: it starts fading in when the photo is about
   70% grown (0.2s in, with this easing) and is fully there as the photo
   reaches its full size at 0.5s. ("both" keeps it invisible while it waits.) */
.vt-opening::view-transition-old(root),
.vt-opening::view-transition-new(root) {
  animation-delay: 0.2s;
  animation-duration: 0.3s;
  animation-fill-mode: both;
}

/* Closing: the box vanishes at once and the photo flies quickly back, landing
   in a card that is already there. */
.vt-closing::view-transition-old(root),
.vt-closing::view-transition-new(root) {
  animation-duration: 0.12s;
}

.vt-closing::view-transition-group(product-photo) {
  animation-duration: 0.3s;
}

html:not(.vt) .product-dialog[open],
html:not(.vt) .product-dialog::backdrop,
.photo-viewer[open],
.photo-viewer::backdrop {
  animation: fade-in 0.4s ease;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}

.dialog-close {
  align-items: center;
  background: rgba(22, 38, 74, 0.7);
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text);
  display: flex;
  height: 40px;
  justify-content: center;
  position: absolute;
  right: 0.75rem;
  top: 0.75rem;
  width: 40px;
  z-index: 2;
}

/* A small bobbing arrow at the bottom of the pop-up while more photos are
   waiting further down. */
.more-photos {
  align-items: center;
  animation: bob 1.6s ease-in-out infinite;
  backdrop-filter: blur(6px);
  background: rgba(22, 38, 74, 0.75);
  border: 1px solid var(--border);
  border-radius: 50%;
  bottom: 0.25rem;
  color: var(--text);
  display: flex;
  height: 44px;
  justify-content: center;
  margin-top: -3.75rem; /* sits over the photo rather than below it */
  position: sticky;
  width: 44px;
}

@keyframes bob {
  50% {
    transform: translateY(5px);
  }
}

/* ---------- Full-screen photo viewer ---------- */

.photo-viewer {
  background: rgba(10, 18, 40, 0.96);
  border: 0;
  color: inherit;
  height: 100dvh;
  max-height: none;
  max-width: none;
  outline: none;
  overflow: hidden;
  padding: 0;
  width: 100vw;
}

.viewer-stage {
  display: flex;
  height: 100%;
  overflow: auto;
  scrollbar-width: thin;
  width: 100%;
}

/* A video in the viewer: as big as fits, with its controls. */
.viewer-stage video {
  flex: none;
  margin: auto;
  max-height: 100%;
  max-width: 100%;
}

/* Clicking a video on the page opens it in the viewer. */
.video-box video {
  cursor: zoom-in;
}

.viewer-stage img {
  cursor: zoom-in;
  flex: none;
  margin: auto; /* centred, and still fully reachable by scrolling when zoomed */
  max-height: 100%;
  max-width: 100%;
}

.viewer-stage.is-zoomed img {
  cursor: grab;
  max-height: none;
  max-width: none;
}

.viewer-stage.is-dragging img {
  cursor: grabbing;
}

/* Previous / next photo in the full-screen viewer, and "3 / 12". */
.viewer-arrow {
  align-items: center;
  backdrop-filter: blur(6px);
  background: rgba(22, 38, 74, 0.72);
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text);
  display: flex;
  height: 48px;
  justify-content: center;
  position: absolute;
  top: calc(50% - 24px);
  width: 48px;
  z-index: 2;
}

.viewer-prev {
  left: 1rem;
}

.viewer-next {
  right: 1rem;
}

.viewer-count {
  background: rgba(22, 38, 74, 0.72);
  border-radius: 999px;
  bottom: 1rem;
  color: var(--text-soft);
  font-size: 0.85rem;
  left: 50%;
  padding: 0.25rem 0.75rem;
  position: absolute;
  transform: translateX(-50%);
}

/* A thin moving line at the top while the full-resolution file is loading. */
.viewer-stage.is-loading::before {
  animation: loading-line 1.1s ease-in-out infinite;
  background: var(--orange);
  content: '';
  height: 2px;
  left: 0;
  position: absolute;
  top: 0;
  width: 30%;
}

@keyframes loading-line {
  from {
    transform: translateX(-100%);
  }

  to {
    transform: translateX(334%);
  }
}

/* ---------- Contact form ---------- */

.contact-container {
  margin: 0 auto;
  max-width: calc(640px + 2 * var(--gutter));
  padding-bottom: 3.5rem;
  padding-top: 2rem;
}

.form-group {
  margin-bottom: 1rem;
}

.form-group label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.45rem;
}

.field-errors {
  color: var(--danger);
  font-size: 0.9rem;
  margin-top: 0.3rem;
}

.field-errors:empty {
  display: none;
}

/* Honeypot: off-screen for people, still filled in by bots. */
.hp {
  left: -9999px;
  position: absolute;
}

/* "You are asking about: ..." above the form. */
.asking {
  align-items: center;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border);
  border-radius: 14px;
  color: var(--text-soft);
  display: flex;
  gap: 0.75rem;
  justify-content: space-between;
  margin-bottom: 1rem;
  padding: 0.6rem 0.6rem 0.6rem 1rem;
}

.asking a {
  color: var(--orange);
  font-weight: 600;
}

.asking button {
  background: none;
  color: var(--text-soft);
  display: flex;
  padding: 0.3rem;
}

.contact-form .submit {
  width: 100%;
}

.contact-form .submit:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.message {
  border-radius: 18px;
  margin-bottom: 1rem;
  padding: 0.9rem 1rem;
}

.message.success {
  background: rgba(120, 210, 150, 0.14);
  color: #bdebc9;
}

.message.error {
  background: rgba(255, 110, 90, 0.14);
  color: var(--danger);
}

[hidden] {
  display: none !important;
}

/* ---------- Narrow windows ---------- */

/* Too narrow for the banner to fit in half the width: let it grow along the
   top, stopping short of the language switch. */
@media (max-width: 1150px) {
  .site-header {
    max-width: calc(100% - 7rem);
  }
}

/* ---------- Phones ---------- */

@media (max-width: 760px) {
  :root {
    --header-space: 3.4rem;
    --gutter: 0.6rem; /* the side margin of product grids and group boxes */
  }

  /* The banner shows the current page's name; tapping it opens a list of all
     pages and the language choice. */
  .site-header {
    font-size: 1rem;
    left: 0.75rem;
    max-width: none;
    right: 0.75rem;
    top: 0.45rem;
  }

  .language-toggle {
    display: none;
  }

  /* The site's name stays visible; the menu button sits next to it. */
  .site-header {
    gap: 0.6rem;
  }

  .site-brand {
    flex: none;
    font-size: 0.85rem;
  }

  .menu-toggle {
    min-width: 0;
  }

  .menu-current {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .menu-toggle {
    align-items: center;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    color: var(--text);
    display: inline-flex;
    font-size: 0.95rem;
    font-weight: 600;
    gap: 0.35rem;
    padding: 0.4rem 0.55rem 0.4rem 0.7rem;
  }

  .menu-toggle:hover {
    opacity: 1;
    transform: none;
  }

  .menu-toggle svg {
    transition: transform 0.25s ease;
  }

  .site-header.is-open .menu-toggle svg {
    transform: rotate(180deg);
  }

  .site-menu {
    backdrop-filter: blur(12px);
    background: rgba(30, 48, 92, 0.96);
    border: 1px solid var(--border);
    border-radius: 18px;
    box-shadow: 0 18px 40px rgba(5, 12, 30, 0.45);
    display: block;
    left: 0;
    max-height: calc(100dvh - 5rem);
    min-width: 15rem;
    opacity: 0;
    overflow-y: auto;
    padding: 0.4rem;
    pointer-events: none;
    position: absolute;
    text-shadow: none;
    top: calc(100% + 0.3rem);
    transform: translateY(-6px);
    transition: opacity 0.2s ease, transform 0.2s ease;
  }

  .site-header.is-open .site-menu {
    opacity: 1;
    pointer-events: auto;
    transform: none;
  }

  .site-nav {
    flex-direction: column;
    overflow: visible;
  }

  .nav-link {
    border-bottom: 0;
    border-left: 3px solid transparent;
    border-radius: 10px;
    display: block;
    margin: 0;
    padding: 0.7rem 0.8rem;
  }

  .nav-link.is-active {
    background: rgba(242, 132, 47, 0.14);
    border-left-color: var(--orange);
  }

  .menu-languages {
    border-top: 1px solid var(--border);
    display: flex;
    gap: 0.25rem;
    margin-top: 0.3rem;
    padding: 0.4rem 0.4rem 0.1rem;
  }

  .menu-languages a {
    border-radius: 8px;
    color: var(--text-soft);
    padding: 0.45rem 0.7rem;
  }

  .menu-languages a.is-active {
    background: rgba(242, 132, 47, 0.14);
    color: var(--orange);
    font-weight: 700;
  }

  .floating-cta {
    bottom: 1rem;
    right: 1rem;
  }  .floating-cta {
    bottom: 1rem;
    right: 1rem;
  }

  /* Home: the photo sits above the text and fades downwards. */
  .panel-home .panel-section-inner {
    overflow-y: auto;
  }

  .hero-photo {
    filter: grayscale(1) sepia(0.35) hue-rotate(185deg) saturate(1.6) brightness(0.85);
    mix-blend-mode: normal;
    height: 46dvh;
    margin-top: calc(var(--header-space) - 0.4rem); /* starts below the banner */
    -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent);
    mask-image: linear-gradient(to bottom, #000 40%, transparent);
    position: static;
    width: 100%;
  }

  .hero-text {
    height: auto;
    overflow: visible;
    padding: 0 1.25rem 5rem;
    width: 100%;
  }

  .hero-description {
    font-size: 1.05rem;
  }

  /* Each group box is nearly a full screen tall, with the top of the next
     one peeking in at the bottom so it is clear there is more below. */
  .corridors {
    gap: 1rem;
  }

  .corridor {
    /* Pictures nearly a screen tall, so a group box is about a screen high
       with the top of the next one peeking in, and the box fits closely
       around them. A wide photo is then wider than the screen; the row
       scrolls to show the rest, and tapping it shows it whole. */
    --fit-h: calc(100dvh - var(--header-space) - 7.5rem);
    --fit-w: 500vw; /* high enough that even a panorama is limited by height, not width */
    gap: 0.4rem;
  }

  /* One column. */
  .product {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The name and price come first, so they are seen without scrolling past every photo. */
  .product-info,
  .product-dialog .product-info {
    order: -1;
    padding-top: 0;
    position: static;
  }

  .product-dialog .product-info {
    padding-right: 2.75rem; /* clears the close button */
  }

  .product-dialog {
    --fit-h: 52dvh;
    --fit-w: calc(100vw - 4.25rem);
  }

  .dialog-body {
    padding: 1rem;
  }

  .product-page {
    --fit-h: 70dvh;
    --fit-w: calc(100vw - 2.5rem);
  }
}

/* People who ask their device for less motion get instant changes. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after,
  ::backdrop {
    animation: none !important;
    transition: none !important;
  }
}
