:root {
  /* phone layout: narrow screens, touch tablets in portrait and phones in
     landscape; touch tablets in landscape (iPad) get the desktop layout,
     see main.js */
  --font-serif: "IBM Plex Serif", serif;
  --font-mono: "Syne Mono", monospace;
  --font: var(--font-mono);
  --bg: #ffffff;
  --text: #000000;
  --floating-ui-color: #000000;
  --monochrome-logo-filter: brightness(0);
  --bicolor-logo-filter: none;
  --transparent-art-filter: none;
  --site-cursor: default;
  --site-cursor-pointer: pointer;
  --site-cursor-grab: grab;
  --site-cursor-grabbing: grabbing;
  --site-cursor-crosshair: crosshair;
  --site-cursor-resize-x: ew-resize;
  --site-cursor-text: text;
  --ui-margin: 13px;
  --logo-h: 0.852rem;
  --brand-swatch-size: 22px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  cursor: var(--site-cursor);
  font-size: 16px;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-tap-highlight-color: transparent;
}

html::-webkit-scrollbar,
body::-webkit-scrollbar {
  display: none;
}

/* Every interaction keeps its familiar state while sharing the same
   black/white contrast logic as the interface text. */
#logo,
#sort-options li,
#settings-color,
#settings-font,
#settings-home,
#contact-home,
#sort-home,
#contact-panel a,
#contact-panel button,
#font-picker-panel button,
#projects-home,
#project-list li,
#subcategories li[data-section],
.book-progress-jump,
.scrapbook-censor-overlay,
#detail .pluralia-swatch,
#detail .niolajet-swatch,
#detail .soundliz-swatch,
#detail .zingaltrip-swatch,
#detail li.colors .swatch,
.color-switch-btn,
.censored-label,
#lang-toggle button,
#back-to-top,
#lang-home,
#contact-layer a,
#mobile-crumbs [data-drop],
#mobile-back span,
/* catch-all: any link or button added later gets the custom hand too */
a[href],
button,
[role="button"] {
  cursor: var(--site-cursor-pointer) !important;
}

#color-field-wrap {
  cursor: var(--site-cursor-crosshair) !important;
}

#color-hue,
.book-progress-value {
  cursor: var(--site-cursor-resize-x) !important;
}

#detail li.gallery.slide,
.model-viewer-wrap,
.model-viewer-wrap canvas {
  cursor: var(--site-cursor-grab) !important;
}

#detail li.gallery.slide.dragging,
.book-progress.scrubbing,
.book-progress.scrubbing .book-progress-value,
.model-viewer-wrap:active,
.model-viewer-wrap:active canvas {
  cursor: var(--site-cursor-grabbing) !important;
}

input[type="number"],
input[type="text"],
textarea,
[contenteditable="true"] {
  cursor: var(--site-cursor-text) !important;
}

body {
  padding: var(--ui-margin);
}

a {
  color: inherit;
  text-decoration: none;
}

/* Fixed and floating over content on every breakpoint. The logo keeps the
   regular interface color and does not use pixel blending. */
#logo {
  position: fixed;
  top: calc(var(--ui-margin) + 0.17rem);
  left: var(--ui-margin);
  width: 2.72rem;
  z-index: 90;
  cursor: pointer;
  mix-blend-mode: normal;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

#logo svg {
  width: 100%;
  height: auto;
  display: block;
}

#logo svg path {
  fill: var(--text);
}

#info {
  position: static;
  display: none;
  margin-top: 0;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

#info.visible {
  display: block;
}

#contact-panel {
  display: none;
  flex: 0 0 auto;
  width: auto;
  align-self: flex-start;
  font-size: 0.85rem;
  line-height: 1.4;
}

#contact-panel.visible {
  display: grid;
  gap: 0.1rem;
}

/* contact sits at the bottom of the settings panel, always shown with it */
#info #contact-panel {
  display: grid;
  gap: 0.1rem;
  margin-top: 0.6rem;
}

.contact-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.75rem;
}

#contact-panel a {
  text-decoration: none;
  overflow-wrap: anywhere;
}

#contact-panel button {
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  appearance: none;
  padding: 0;
  border: 0;
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

#projects.hidden {
  display: none;
}

#sort-control {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin-top: 0;
  white-space: nowrap;
}

#settings-sort {
  padding: 0.1rem 0;
  font-size: 0.85rem;
  line-height: 1.4;
  cursor: var(--site-cursor);
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

#sort-options {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

#sort-options li {
  padding: 0.1rem 0;
  font-size: 0.85rem;
  line-height: 1.4;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

#settings-color,
#settings-font {
  appearance: none;
  margin-top: 0.6rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.1rem 0;
  border: 0;
  background: none;
  color: inherit;
  font-family: var(--font);
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

#font-picker-panel {
  display: none;
  flex: 0 0 auto;
  width: max-content;
  align-self: flex-start;
  user-select: none;
}

#font-picker-panel.visible {
  display: grid;
  gap: 0.1rem;
}

/* fonts sit under the colors inside the theme panel; the separate
   "fonts" button is no longer shown */
#settings-color[hidden],
#contact-panel button[hidden],
#font-picker-panel[hidden] {
  display: none !important;
}

#color-picker-panel #font-picker-panel {
  position: static;
  left: auto;
  display: grid;
  gap: 0.1rem;
  flex: none;
  width: auto;
  max-width: none;
  margin-top: 1rem;
}

#info #settings-font {
  display: none;
}

#font-picker-panel button {
  appearance: none;
  display: block;
  padding: 0.1rem 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: left;
}

#font-picker-panel button[data-font="syne-mono"] {
  font-family: var(--font-mono);
}

#font-picker-panel button[data-font="ibm-plex-serif"] {
  font-family: var(--font-serif);
}

#font-picker-panel button[aria-checked="true"] {
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

/* kept in the DOM and functional (the "color" label still opens the
   native picker), just visually hidden — no swatch dot shown */
#bg-color-picker {
  display: none;
}

#color-picker-panel {
  display: none;
  flex: 1 1 0; /* fills the rest of the row (0 basis: the canvas's pixel size must not push it to a new line) */
  width: auto;
  min-width: 0;
  align-self: flex-start;
  user-select: none;
}

#color-picker-panel.visible {
  display: block;
}

/* no project open: the empty detail column gives its room to the picker */
#color-picker-panel.visible ~ #detail:not(:has(*)) {
  display: none;
}

#color-field-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 1.72;
  border: 1px solid currentColor;
  overflow: hidden;
  cursor: crosshair;
  touch-action: none;
}

#color-field {
  display: block;
  width: 100%;
  height: 100%;
}

#color-field-cursor {
  position: absolute;
  width: 12px;
  height: 12px;
  border: 2px solid #ffffff;
  border-radius: 50%;
  box-shadow: 0 0 0 1px #000000;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

#color-picker-controls {
  display: block;
  margin-top: 0.65rem;
}

#color-hue {
  appearance: none;
  width: 100%;
  height: 9px;
  border: 1px solid var(--text);
  border-radius: 0;
  background: linear-gradient(90deg, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);
  color: var(--text);
  cursor: ew-resize;
  touch-action: none; /* horizontal drags set the hue instead of scrolling */
  box-sizing: border-box;
  margin: 0;
}

#color-hue::-webkit-slider-thumb {
  appearance: none;
  width: 9px;
  height: 17px;
  border: 1px solid var(--text);
  border-radius: 0;
  background: var(--bg);
  box-shadow: none;
}

#color-hue::-moz-range-thumb {
  width: 8px;
  height: 16px;
  border: 1px solid var(--text);
  border-radius: 0;
  background: var(--bg);
  box-shadow: none;
}

#projects {
  position: fixed;
  top: var(--ui-margin);
  bottom: var(--ui-margin);
  /* the logo moved to the bottom left: the index takes the top left corner */
  left: var(--ui-margin);
  right: var(--ui-margin);
  display: flex;
  flex-wrap: wrap;
  gap: 4rem;
}

#projects-menu {
  flex: 0 0 auto;
  align-self: flex-start;
}

/* settings layer: replaces the project list in place, floats over the rest
   of the page without pushing it */

#settings-layer {
  display: none;
  position: fixed;
  left: var(--ui-margin);
  bottom: calc(var(--ui-margin) + 0.85rem * 1.4 + 1rem);
  z-index: 80;
  width: 18rem;
  max-height: calc(100vh - var(--ui-margin) * 2 - 3rem);
  overflow-y: auto;
  background: var(--bg);
}

#settings-layer.visible {
  display: block;
}

/* desktop: logo in the bottom left corner, the settings icon right of it;
   the logo opens the contact layer above it */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #logo {
    top: auto;
    bottom: calc(var(--ui-margin) + (0.85rem * 1.4 - 2.72rem * 375 / 1198) / 2);
    left: var(--ui-margin);
  }

  /* (body: beats the base #settings-home rule further down) */
  body #settings-home {
    left: calc(var(--ui-margin) + 2.72rem + 1rem);
  }

  /* contact now lives behind the logo, not in settings */
  #info #contact-panel {
    display: none;
  }
}

#contact-layer {
  display: none;
  position: fixed;
  left: var(--ui-margin);
  bottom: calc(var(--ui-margin) + 0.85rem * 1.4 + 1rem);
  z-index: 80;
  font-size: 0.85rem;
  line-height: 1.4;
  overflow-wrap: anywhere;
  background: var(--bg);
}

#contact-layer.visible {
  display: block;
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  #contact-layer.visible {
    display: none;
  }
}

#settings-layer #color-picker-panel {
  position: static;
  left: auto;
  flex: none;
  width: auto;
  max-width: none;
  margin-top: 1rem;
}

#settings-home,
#contact-home,
#sort-home {
  margin-top: 0;
  padding: 0;
  text-align: left;
  font-size: 0.85rem;
  line-height: 1.4;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

#settings-home {
  position: fixed;
  left: var(--ui-margin);
  bottom: var(--ui-margin);
  z-index: 90;
  margin-bottom: 0;
  width: max-content;
  height: calc(0.85rem * 1.4);
}

#settings-home svg {
  display: block;
  height: 100%;
  width: auto;
}

#settings-home svg path {
  fill: var(--text);
}

#contact-home {
  margin-bottom: 1rem;
}

/* mobile only: "back" line of the cascade navigation and the breadcrumb
   path (see main.js) */
#mobile-back,
#mobile-crumbs {
  display: none;
}

/* sort is the first line of the settings panel */
#sort-home {
  margin-bottom: 0;
}

#info #sort-home {
  margin-top: 0.6rem;
}

/* sort switch: a thin frame cut in two halves; the knob slides from one
   half to the other and names the current view (filled on "case", hollow
   with just its edge line on "category") */
.sort-switch {
  position: relative;
  display: inline-block;
  vertical-align: top;
  width: calc((9ch + 1rem) * 2);
  height: calc(0.85rem * 1.4 + 0.3rem);
  border: 1px solid var(--text);
}

.sort-knob {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--text);
  color: var(--bg);
  border-left: 1px solid transparent;
  white-space: nowrap;
  transition:
    transform 0.28s cubic-bezier(0.22, 0.8, 0.24, 1),
    background-color 0.28s ease,
    color 0.28s ease,
    border-color 0.28s ease;
}

.sort-switch.is-category .sort-knob {
  transform: translateX(100%);
  background: transparent;
  color: var(--text);
  border-left-color: var(--text);
}

@media (prefers-reduced-motion: reduce) {
  .sort-knob {
    transition: none;
  }
}

/* sort moved to the main column (#sort-home) */
#info #sort-control {
  display: none;
}

#projects ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

#projects li {
  padding: 0.1rem 0;
  font-size: 0.85rem;
  line-height: 1.4;
}

#projects li:first-child {
  padding-top: 0;
}

#project-list li.filtered-out {
  display: none;
}

#projects-home {
  display: none;
  align-self: flex-start;
  font-size: 0.85rem;
  line-height: 1.4;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

/* the project list itself only appears once "projects" is clicked, same
   as subcategories only appearing once a project is clicked */
#project-list {
  display: none;
}

#project-list.visible {
  display: block;
}

#project-list li,
#subcategories li[data-section] {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

#subcategories:empty {
  display: none;
}

#detail .project-section-anchor {
  display: block;
  height: 0;
  margin: 0;
  padding: 0;
  scroll-margin-top: var(--ui-margin);
}

#detail .project-section-anchor:not(:first-child) {
  margin-top: clamp(1.5rem, 4vh, 3rem);
}

#detail .discipline-brand {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.5rem;
  margin-top: 1.75rem;
  padding-top: 0.275rem;
  border-top: 1px solid currentColor;
  text-transform: lowercase;
}

#detail .discipline-brand:first-child {
  margin-top: 0;
}

#detail .discipline-brand a {
  color: inherit;
}

/* imagery: each brand is wrapped in a group so its name stays pinned
   only while that brand's images scroll past */
#detail .sticky-group {
  margin-top: 1.75rem;
  padding: 0;
}

#detail .sticky-group .discipline-brand {
  position: sticky;
  top: 0;
  z-index: 2;
  margin-top: 0;
  padding-bottom: 0.275rem;
  background: var(--bg);
}

#detail {
  flex: 1 1 0;
  min-width: 0;
  max-width: 90vw;
  height: calc(100vh - var(--ui-margin) * 2);
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  container-type: inline-size;
}

#detail.dragging-v {
  user-select: none;
}

#detail::-webkit-scrollbar {
  display: none;
}

#detail li:not(.media) {
  max-width: 100%;
}

#detail .section-intro-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  gap: 1.5rem;
}

#detail .section-intro-row > span:first-child {
  min-width: 0;
}

#detail .section-medium {
  flex: none;
  text-align: right;
}

/* proportions known before download (main.js reserveImageSpace) */
#detail img {
  aspect-ratio: var(--img-ar, auto);
}

#detail li.gallery {
  column-width: 260px;
  column-gap: 0;
}

#detail li.gallery.row {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
}

#detail li.gallery.row img,
#detail li.gallery.row video {
  flex: 1 1 0;
  min-width: 0;
  width: auto;
  height: auto;
}

#detail li.gallery.row-wrap {
  display: grid;
  grid-template-columns: repeat(var(--row-count), minmax(0, var(--cell-size, 1fr)));
  justify-content: center;
  gap: 0;
}

#detail li.gallery.row-wrap.fixed-cell {
  grid-template-columns: repeat(var(--row-count), var(--cell-size, 170px));
}

#detail li.gallery.row-wrap.fixed-cell .model-viewer-wrap {
  width: var(--cell-size, 170px);
}

#detail li.gallery.row-wrap img {
  width: 100%;
  height: auto;
  max-height: none;
  aspect-ratio: var(--cell-aspect, 1);
  object-fit: contain;
  justify-self: center;
  align-self: var(--cell-align, center);
}

#detail li.gallery.coastline-grid {
  gap: 0;
  line-height: 0;
}

#detail li.gallery.coastline-grid img {
  display: block;
  height: 100%;
  object-fit: cover;
}

#detail li.gallery.row-wrap .model-viewer-wrap {
  width: 100%;
  aspect-ratio: var(--cell-aspect, 1);
  justify-self: center;
  align-self: var(--cell-align, center);
}

#detail li.media.columns {
  display: flex;
  gap: clamp(0.4rem, 3cqw, 3rem);
  align-items: flex-start;
  flex-wrap: nowrap;
  max-width: 100%;
  overflow-x: auto;
}

#detail li.media.columns.full-width {
  width: 100%;
  justify-content: space-between;
}

.collection-col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  flex: none;
  min-width: 0;
}

.collection-col-label {
  font-size: 0.85rem;
  line-height: 1.4;
  padding: 0.1rem 0;
  display: block;
}

#detail li.media.columns > .collection-col:first-child {
  align-items: flex-start;
}

#detail li.gallery.slide {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  gap: 0;
  overflow-x: auto;
  cursor: grab;
  scrollbar-width: none;
  -ms-overflow-style: none;
  touch-action: pan-x;
  --slide-height: calc(100vh - 90px);
  --slide-height: calc(100dvh - 90px);
}

#detail li.gallery.slide.soundliz-book {
  gap: var(--ui-margin);
}

#detail li.gallery.slide::-webkit-scrollbar {
  display: none;
}

#detail li.gallery.slide.dragging {
  cursor: grabbing;
  user-select: none;
}

#detail li.gallery.slide img {
  flex: none;
  width: auto;
  height: var(--slide-height);
  max-height: var(--slide-height);
  -webkit-user-drag: none;
  user-select: none;
}

.book-progress {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  min-height: 2rem;
  margin: -0.3rem 0;
  padding: 0.3rem 0 !important;
  text-align: left;
  font-size: 0.75rem !important;
  line-height: 1.4 !important;
  cursor: var(--site-cursor);
  user-select: none;
  -webkit-user-select: none;
  box-sizing: border-box;
}

.book-progress-value {
  white-space: nowrap;
  cursor: ew-resize;
  padding: 0.35rem 0;
}

.book-progress-jump {
  appearance: none;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  min-width: auto;
  min-height: 1.75rem;
  font-size: 0.85rem;
  line-height: 1;
  padding: 0.25rem 0.4rem;
  cursor: pointer;
}

.book-progress-edge-start {
  margin-left: auto;
}

.book-progress-jump:hover {
  opacity: 0.45;
}

.book-progress-jump:disabled {
  opacity: 0.22;
  cursor: var(--site-cursor);
}

.book-progress.scrubbing {
  cursor: grabbing;
}

.book-progress.scrubbing .book-progress-value {
  cursor: grabbing;
}

.book-progress.hidden {
  display: none;
}

#detail li.gallery.line {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  gap: 0;
  overflow: hidden;
  --line-height: 220px;
}

#detail li.gallery.line img {
  flex: none;
  width: auto;
  height: var(--line-height);
  max-height: min(var(--line-height), 42vh);
}

/* tablets and small laptops: the content column is too narrow for a single
   fixed-height line, so it wraps instead of clipping the last items */
@media (min-width: 701px) and (max-width: 1100px) and (hover: hover), (min-width: 701px) and (max-width: 1100px) and (pointer: fine), (min-width: 701px) and (max-width: 1100px) and (orientation: landscape) and (min-height: 601px) {
  #detail li.gallery.line {
    flex-wrap: wrap;
  }
}

#detail li.gallery.shelf {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: clamp(0.4rem, 2.5cqw, 1.75rem);
}

#detail li.gallery.shelf img {
  flex: none;
  width: auto;
  max-width: 100%;
  -webkit-user-drag: none;
}

#detail li.gallery.shelf.slide {
  flex-wrap: nowrap;
  overflow-x: auto;
  align-items: flex-end;
}

#detail li.gallery.shelf.slide img {
  height: auto;
  max-height: none;
}

#detail li.gallery.scrapbook {
  position: relative;
}

#detail li.gallery.scrapbook .scrapbook-images {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1.75rem 1.25rem;
  padding: 0.75rem 0 1.5rem;
}

#detail li.gallery.scrapbook.scrapbook-censored .scrapbook-images {
  filter: blur(13px);
}

#detail li.gallery.scrapbook img {
  flex: none;
  width: auto;
  height: clamp(85px, 11cqw, 155px);
  -webkit-user-drag: none;
  transition: transform 0.18s ease;
  cursor: var(--site-cursor);
}

#detail li.gallery.scrapbook img:nth-child(9n+1) { height: clamp(105px, 13.5cqw, 195px); }
#detail li.gallery.scrapbook img:nth-child(11n+2) { height: clamp(65px, 8.5cqw, 110px); }

#detail li.gallery.scrapbook img:nth-child(8n+1) { transform: rotate(-4deg); }
#detail li.gallery.scrapbook img:nth-child(8n+2) { transform: rotate(3deg); }
#detail li.gallery.scrapbook img:nth-child(8n+3) { transform: rotate(-2deg); }
#detail li.gallery.scrapbook img:nth-child(8n+4) { transform: rotate(5deg); }
#detail li.gallery.scrapbook img:nth-child(8n+5) { transform: rotate(-5deg); }
#detail li.gallery.scrapbook img:nth-child(8n+6) { transform: rotate(2deg); }
#detail li.gallery.scrapbook img:nth-child(8n+7) { transform: rotate(-3deg); }
#detail li.gallery.scrapbook img:nth-child(8n) { transform: rotate(4deg); }

#detail li.gallery.scrapbook.scrapbook-censored img:hover {
  transform: inherit;
}

#detail li.gallery.scrapbook:not(.scrapbook-censored) img:hover {
  transform: rotate(0deg) scale(1.12);
  position: relative;
  z-index: 5;
}

.scrapbook-censor-overlay {
  position: absolute;
  inset: 0;
  cursor: pointer;
  z-index: 6;
}

.scrapbook-censor-overlay .censored-label {
  position: sticky;
  top: 45vh;
  transform: none;
  display: block;
  width: fit-content;
  margin: 0 auto;
  font-size: 1rem;
  padding: 0.6rem 1.4rem;
}

#detail img.wide {
  column-span: all;
}

#detail li.gallery.filtralife-environment img {
  max-height: none;
}

#detail li.gallery.pair-row {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  column-width: auto;
  gap: 0;
}

/* stacked pair rows touch: no gap between the photos */
#detail li.gallery.pair-row + li.gallery.pair-row {
  margin-top: 0;
}

#detail li.gallery.pair-row img {
  flex: none;
  width: calc(var(--pair-share, 0.5) * 100%);
  min-width: 0;
  height: auto;
  max-height: none;
}

#detail li.gallery.niolajet-operations-single {
  display: grid;
  grid-template-columns: 1fr;
  column-width: auto;
}

#detail li.gallery.niolajet-operations-single img {
  width: 100%;
  height: auto;
  max-height: none;
}

/* the wave illustration gets its own row so it isn't squeezed into a
   260px gallery column next to the square mascots */
#detail li.gallery.zingaltrip-illustration {
  column-width: auto;
}

#detail li.gallery.zingaltrip-illustration img {
  width: 100%;
  object-fit: contain;
  object-position: left center;
}

#detail img.dark-bg {
  background: #000;
}

#detail li.media.brandpanel {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ui-margin);
}

#detail li.brandpanel .brandpanel-logo,
#detail li.brandpanel .brandpanel-mark {
  height: 56px;
  width: auto;
  flex: none;
  object-fit: contain;
}

#detail li.brandpanel .brandpanel-mark.large {
  height: 220px;
}

#detail li.brandpanel.logo-strip {
  --logo-strip-gap: clamp(1.25rem, 4cqw, 4rem);
  flex-wrap: nowrap;
  justify-content: flex-start;
  gap: var(--logo-strip-gap);
}

#detail li.brandpanel.logo-strip .brandpanel-mark {
  height: clamp(64px, 8cqw, 105px);
  max-width: 30%;
}

#detail li.brandpanel.logo-strip .brandpanel-mark.rotate-90 {
  transform: rotate(90deg);
}

#detail li.brandpanel.logo-strip .brandpanel-mark.attach-previous {
  margin-left: calc(-1 * var(--logo-strip-gap) + 0.6rem);
}

#detail li.media.pluralia-overview {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.72fr) auto;
  align-items: center;
  gap: clamp(1.5rem, 4cqw, 4rem);
  min-height: clamp(112px, 13cqw, 155px);
}

#detail .pluralia-main-logo {
  width: min(100%, 470px);
  height: auto;
  max-height: 132px;
  object-fit: contain;
  object-position: left center;
}

#detail .pluralia-marks {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: clamp(1.5rem, 3cqw, 3.5rem);
}

#detail .pluralia-marks img {
  width: auto;
  height: clamp(45px, 6cqw, 70px);
  max-width: 42%;
  object-fit: contain;
}

#detail .pluralia-palette {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

#detail .pluralia-swatch {
  display: block;
  width: var(--brand-swatch-size);
  height: var(--brand-swatch-size);
  padding: 0;
  border: 1px solid var(--text);
  cursor: pointer;
}

#detail .pluralia-manifesto {
  margin-top: 0.25rem;
  max-width: 100%;
}

#detail li.media.niolajet-overview {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.7fr) auto;
  align-items: center;
  gap: clamp(2rem, 5cqw, 5rem);
  min-height: clamp(145px, 16cqw, 190px);
}

#detail .niolajet-main-logo {
  width: min(100%, 560px);
  height: auto;
  max-height: 150px;
  object-fit: contain;
  object-position: left center;
}

#detail .niolajet-marks {
  position: relative;
  justify-self: end;
  width: 151px;
  height: 80px;
  aspect-ratio: 1419 / 752;
  overflow: hidden;
}

#detail .niolajet-marks img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: auto;
  max-height: none;
  transform: none;
}

#detail .niolajet-palette {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

#detail .niolajet-swatch {
  display: block;
  width: var(--brand-swatch-size);
  height: var(--brand-swatch-size);
  padding: 0;
  border: 1px solid var(--text);
  cursor: pointer;
}

#detail .niolajet-research-copy {
  margin-top: 0.2rem;
  max-width: 100%;
}

#detail li.media.soundliz-overview {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr) auto;
  align-items: center;
  gap: clamp(1.5rem, 4cqw, 4rem);
  min-height: clamp(100px, 12cqw, 145px);
}

#detail .soundliz-main-logo {
  width: min(100%, 430px);
  height: auto;
  max-height: 104px;
  object-fit: contain;
  object-position: left center;
}

#detail .soundliz-marks {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: clamp(0.8rem, 1.5cqw, 1.6rem);
}

#detail .soundliz-marks img {
  width: auto;
  height: clamp(34px, 4cqw, 51px);
  max-width: 52%;
  object-fit: contain;
}

/* Monochrome identity assets follow the same foreground contrast system as
   the interface. The Zingaltrip wordmark and symbols are one-colour
   line versions of the artwork, so they follow the theme too. */
#detail .pluralia-main-logo,
#detail .zingaltrip-main-logo,
#detail .zingaltrip-marks img,
#detail .soundliz-main-logo,
#detail .soundliz-marks img,
#detail .pluralia-marks img,
#detail .niolajet-main-logo,
#detail .niolajet-marks img,
#detail li.brandpanel.logo-strip .brandpanel-mark {
  filter: var(--monochrome-logo-filter);
}

/* Soundliz artwork used to be black + white and was inverted as a whole;
   its white parts are now transparent (…-knockout.webp), so it follows the
   one-colour filter above and the background shows through the letters. */

#detail .soundliz-palette {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

#detail .soundliz-swatch {
  display: block;
  width: var(--brand-swatch-size);
  height: var(--brand-swatch-size);
  padding: 0;
  border: 1px solid var(--text);
  cursor: pointer;
}

#detail li.media.zingaltrip-overview {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.26fr) auto;
  align-items: center;
  gap: clamp(2rem, 5cqw, 5rem);
  min-height: clamp(210px, 25cqw, 310px);
}

#detail .zingaltrip-main-logo {
  width: min(100%, 570px);
  height: auto;
  max-height: 300px;
  object-fit: contain;
  object-position: left center;
}

#detail .zingaltrip-marks {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  gap: clamp(0.8rem, 1.8cqw, 1.8rem);
  min-width: 0;
}

#detail .zingaltrip-marks img {
  width: auto;
  height: clamp(46px, 5.3cqw, 72px);
  max-width: 48%;
  object-fit: contain;
  object-position: top center;
}

#detail .zingaltrip-palette {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

#detail .zingaltrip-swatch {
  display: block;
  width: var(--brand-swatch-size);
  height: var(--brand-swatch-size);
  padding: 0;
  border: 1px solid var(--text);
  cursor: pointer;
}

#detail .lostvenom-marks {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  gap: clamp(0.8rem, 1.8cqw, 1.8rem);
  min-width: 0;
}

#detail .lostvenom-marks img {
  width: auto;
  height: clamp(70px, 8cqw, 110px);
  max-width: 48%;
  object-fit: contain;
  object-position: top center;
  filter: var(--monochrome-logo-filter);
}

#detail .lostvenom-palette {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

#detail .lostvenom-swatch {
  display: block;
  width: var(--brand-swatch-size);
  height: var(--brand-swatch-size);
  padding: 0;
  border: 1px solid var(--text);
  cursor: pointer;
}

/* Shared identity composition: main logo, secondary marks and palette use
   the same top-aligned grid and proportional logo area in every case. */
#detail li.media.pluralia-overview,
#detail li.media.niolajet-overview,
#detail li.media.soundliz-overview,
#detail li.media.zingaltrip-overview,
#detail li.media.lostvenom-overview {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.42fr) auto;
  align-items: start;
  gap: clamp(1.5rem, 4cqw, 4rem);
  min-height: 0;
}

#detail .pluralia-main-logo,
#detail .niolajet-main-logo,
#detail .soundliz-main-logo,
#detail .zingaltrip-main-logo,
#detail .lostvenom-main-logo {
  align-self: start;
  justify-self: start;
  width: 100%;
  height: clamp(90px, 10cqw, 130px);
  max-height: none;
  object-fit: contain;
  object-position: left top;
}

#detail .lostvenom-main-logo {
  filter: var(--monochrome-logo-filter);
}

/* Soundliz and Zingaltrip are very wide, heavy wordmarks: a shorter box keeps
   their visual weight in line with the other brands */
#detail .soundliz-main-logo,
#detail .zingaltrip-main-logo {
  height: clamp(68px, 7.5cqw, 98px);
}

#detail .pluralia-marks,
#detail .niolajet-marks,
#detail .soundliz-marks,
#detail .zingaltrip-marks,
#detail .lostvenom-marks,
#detail .pluralia-palette,
#detail .niolajet-palette,
#detail .soundliz-palette,
#detail .zingaltrip-palette,
#detail .lostvenom-palette {
  align-self: start;
}

#detail .identity-section-copy {
  margin-top: var(--ui-margin);
}

#detail li.media {
  margin: 0;
  margin-top: var(--ui-margin);
  padding: 0;
}

#detail li.models {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ui-margin);
}

#detail li.media.homeboxmini-showcase {
  display: grid;
  /* desktop: model 1/3, views 2/3 */
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: var(--ui-margin);
  width: 100%;
  height: min(calc(100dvh - 170px), 820px);
  min-height: 520px;
}

#detail .homeboxmini-viewer {
  width: 100%;
  height: 100%;
  max-width: none;
  aspect-ratio: auto;
}

#detail .homeboxmini-media {
  display: grid;
  grid-template-rows: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: var(--ui-margin);
  min-width: 0;
  min-height: 0;
}

#detail .homeboxmini-media-top,
#detail .homeboxmini-media-bottom {
  display: grid;
  align-items: stretch;
  min-width: 0;
  min-height: 0;
  gap: var(--ui-margin);
}

#detail .homeboxmini-media-top {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

#detail .filtrahome-showcase .homeboxmini-media-top {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

#detail .homeboxmini-media-bottom {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

#detail .agriculture-showcase .homeboxmini-media-bottom {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

#detail .soundliz-product-showcase .homeboxmini-media-bottom {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

#detail .zingaltrip-product-showcase .homeboxmini-media-top {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

#detail .zingaltrip-product-showcase .homeboxmini-media-bottom {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

#detail .multi-model-viewer {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: var(--ui-margin);
  overflow: hidden;
}

#detail .multi-model-cell {
  width: 100%;
  height: 100%;
  min-height: 0;
  aspect-ratio: auto;
}

#detail .vanhoa-bag-showcase .homeboxmini-media-top,
#detail .vanhoa-bag-showcase .homeboxmini-media-bottom {
  grid-template-columns: 1fr;
}

#detail .vanhoa-ring-showcase .homeboxmini-media-bottom {
  grid-template-columns: 1fr;
}

#detail .showcase-variant-swatches {
  position: absolute;
  left: 50%;
  bottom: var(--ui-margin);
  z-index: 4;
  display: flex;
  gap: 12px;
  transform: translateX(-50%);
}

#detail .showcase-variant-swatches .color-switch-btn.active {
  outline: 1px solid var(--text);
  outline-offset: 3px;
}

#detail .homeboxmini-media img {
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  object-fit: contain;
}

/* fit-rows (Filtralife): renders are cropped to one shared height per row,
   so a flex row with widths proportional to each image's aspect ratio shows
   every view at the same scale, bottom-aligned, without empty margins */
#detail .fit-rows .homeboxmini-media-top,
#detail .fit-rows .homeboxmini-media-bottom {
  display: flex;
  align-items: flex-end;
}

#detail .homeboxmini-media.single-row {
  grid-template-rows: minmax(0, 1fr);
}

#detail .fit-rows .homeboxmini-media.single-row .homeboxmini-media-top {
  align-items: center;
}

#detail .fit-rows .homeboxmini-media.single-row img {
  object-position: center;
}

#detail .fit-rows .homeboxmini-media img {
  object-position: center bottom;
}

/* desktop: explicit width shares (set in main.js) instead of flex-grow on
   0-width images, which Safari collapses to nothing */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail .fit-rows .homeboxmini-media-top > *,
  #detail .fit-rows .homeboxmini-media-bottom > * {
    flex: none;
    /* shares apply to the width left once the gaps between items are removed */
    width: calc(var(--fit-share, calc(1 / var(--fit-count, 1))) * (100% - (var(--fit-count, 1) - 1) * var(--ui-margin)));
    min-width: 0;
  }
}

#detail li.models.model-layout-pair {
  display: grid;
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr);
  align-items: stretch;
  gap: var(--ui-margin);
  height: min(calc(100dvh - 190px), 820px);
  max-height: calc(100dvh - 190px);
  min-height: 0;
}

#detail.lost-venom-detail {
  overflow-y: auto;
}

#detail li.models.model-layout-pair .model-viewer-wrap {
  width: 100%;
  height: 100%;
  max-width: none;
  aspect-ratio: auto;
  justify-self: center;
}

#detail li.models.model-layout-pair .model-layout-stack {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  min-width: 0;
}

#detail li.models.model-layout-pair .model-layout-rotator {
  display: grid;
  grid-template-rows: repeat(5, minmax(0, 1fr));
  width: 100%;
  height: 100%;
  gap: clamp(0.45rem, 0.8vh, 0.7rem);
  transform: rotate(180deg);
  transform-origin: center center;
}

#detail li.models.model-layout-pair .model-layout-frame {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow: visible;
}

#detail li.models.model-layout-pair .model-layout-frame img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: auto;
  height: min(32cqw, 520px);
  min-width: 0;
  max-height: none;
  object-fit: contain;
  transform: translate(-50%, -50%) rotate(90deg);
}

#detail li.models.model-layout-pair .model-layout-art {
  width: 100%;
  max-height: none;
  aspect-ratio: 1;
  object-fit: contain;
  background: transparent;
  transform: scale(0.8);
  transform-origin: center center;
}

#detail li.colors {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ui-margin);
}

#detail li.colors .swatch {
  flex: none;
  width: var(--brand-swatch-size);
  height: var(--brand-swatch-size);
  display: flex;
  align-items: flex-end;
  padding: 6px;
  cursor: pointer;
  position: relative;
  border: 1px solid var(--text);
}

#detail li.colors .swatch-hex {
  display: none;
}

#detail li.colors .swatch-copied {
  position: absolute;
  top: 6px;
  right: 6px;
  font-size: 0.6rem;
  display: none !important;
}

.color-switch {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 20px;
}

.color-switch-images {
  display: flex;
  align-items: center;
  gap: 14px;
}

#detail .color-switch-images img {
  width: auto;
  height: var(--cell-size, 220px);
  max-height: none;
  max-width: none;
}

.color-switch-stack {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: calc(var(--cell-size, 220px) * 0.283);
}

#detail .color-switch-images .color-switch-stack img {
  width: 100%;
  height: auto;
  max-height: none;
  max-width: none;
}

.color-switch-swatches {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
}

.color-switch-btn {
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  cursor: pointer;
}

#detail li.colors .swatch.copied-show .swatch-copied {
  display: block;
}

.model-viewer-wrap {
  position: relative;
  flex: 1 1 260px;
  min-width: 0;
  aspect-ratio: 1;
  background: transparent;
  overflow: hidden;
  touch-action: pan-y;
  cursor: grab;
}

.model-viewer-wrap:active {
  cursor: grabbing;
}

.model-viewer-wrap canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
  touch-action: pan-y;
}

/* "loading" sits in the middle of its 3D frame */
.model-viewer-loader {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  pointer-events: none;
  font-family: var(--font);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  color: var(--text);
}

.model-viewer-hint {
  position: absolute;
  top: var(--ui-margin);
  left: var(--ui-margin);
  font-family: var(--font);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
}

.model-viewer-hint.hidden {
  display: none;
}

.censored-wrap {
  position: relative;
  display: inline-block;
  line-height: 0;
}

#detail li.gallery.row .censored-wrap {
  flex: 1 1 0;
  min-width: 0;
}

#detail li.gallery.row-wrap .censored-wrap {
  display: block;
  width: 100%;
}

#detail li.gallery:not(.row):not(.row-wrap):not(.slide):not(.line) .censored-wrap {
  display: block;
  width: 100%;
}

#detail img[src*="ZINGALTRIP/editorial/"]:not(.censored) {
  filter: var(--transparent-art-filter);
}

#detail img.censored,
#detail video.censored {
  filter: blur(4px);
  transform: scale(1.02);
}

.censored-wrap::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: overlay;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.censored-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  font-family: var(--font);
  letter-spacing: 0.1em;
  font-size: 0.8rem;
  color: var(--bg);
  background: var(--text);
  padding: 0.4rem 1rem;
  white-space: nowrap;
  pointer-events: auto;
  cursor: pointer;
}

#detail img,
#detail video {
  width: 100%;
  height: auto;
  max-height: 60vh;
  display: block;
  margin: 0;
  padding: 0;
  border: none;
  break-inside: avoid;
}

/* Lives in the settings panel now, styled like the other settings rows. */
#lang-toggle {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.7rem;
  margin-top: 0.6rem;
}

#lang-toggle button {
  background: none;
  border: none;
  padding: 0.1rem 0;
  color: var(--text);
  font-family: var(--font);
  font-size: 0.85rem;
  line-height: 1.4;
  cursor: pointer;
}

#back-to-top {
  position: fixed;
  bottom: calc(var(--ui-margin) + 1.5rem);
  left: 50%;
  z-index: 90;
  line-height: 1;
  background: none;
  border: none;
  padding: 0;
  color: var(--floating-ui-color);
  mix-blend-mode: normal;
  font-family: var(--font);
  font-size: 0.85rem;
  cursor: pointer;
  opacity: 0;
  transform: translate(-50%, 0.5rem);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

#back-to-top.visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}

/* Slightly overlap Coastline cells on every viewport so fractional-pixel
   grid sizing can never reveal the page background between images. */
#detail.coastline-detail li.gallery.row-wrap {
  overflow: hidden;
}

#detail.coastline-detail li.gallery.row-wrap img {
  transform: scale(1.002);
  transform-origin: center;
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail .discipline-brand {
    border-top: none;
  }
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  #detail .discipline-brand {
    border-top: none;
  }

  /* phones: the pinned name floats over the images with no background; its
     color follows the picture underneath, like the "top" button (main.js) */
  #detail .sticky-group .discipline-brand {
    top: env(safe-area-inset-top);
    background: transparent;
  }

  html {
    overflow-x: hidden;
    overflow-y: auto;
  }

  /* body used to be its own fixed-height (100vh) scroll container, which
     stops the actual document from ever scrolling — mobile browsers only
     collapse their address bar / toolbar chrome when the real document
     scrolls, so that also silently broke it. Let body flow to its natural
     height and let the document scroll instead. */
  body {
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    overflow-x: hidden;
    /* same clipping as hidden, but body no longer becomes a scroll container,
       so sticky elements (imagery brand names) pin to the page scroll */
    overflow: clip;
    display: flex;
    flex-direction: column;
    /* logo is positioned out of flow (and no longer reserves flow space),
       so this has to clear it manually or the content underneath starts
       right under/behind it */
    padding-top: calc(2.6rem + env(safe-area-inset-top));
    padding-bottom: 0;
    padding-left: calc(var(--ui-margin) + env(safe-area-inset-left));
    padding-right: calc(var(--ui-margin) + env(safe-area-inset-right));
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
  }

  #logo {
    position: absolute;
    top: calc(var(--ui-margin) + env(safe-area-inset-top) + 0.17rem);
    left: calc(var(--ui-margin) + env(safe-area-inset-left));
  }

  #projects {
    position: static;
    order: 2;
    height: auto;
    width: calc(100% - 2.72rem - 1.25rem);
    max-width: calc(100% - 2.72rem - 1.25rem);
    margin-top: calc(var(--ui-margin) - 2.6rem);
    margin-left: calc(2.72rem + 1.25rem);
    gap: 1.25rem;
  }

  #info {
    position: static;
    order: 0;
    flex: 0 0 auto;
    width: auto;
    max-width: none;
    align-self: flex-start;
    margin-left: 0;
    margin-top: 0;
    padding-top: 0;
  }

  #contact-panel {
    position: static;
    left: auto;
    order: 0;
    flex: 0 0 100%;
    width: 100%;
    max-width: 100%;
    align-self: flex-start;
  }

  .contact-row {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  #color-picker-panel,
  #font-picker-panel {
    position: relative;
    left: calc(-2.72rem - 1.25rem);
    flex: 0 0 calc(100vw - var(--ui-margin) - var(--ui-margin));
    width: calc(100vw - var(--ui-margin) - var(--ui-margin));
    max-width: calc(100vw - var(--ui-margin) - var(--ui-margin));
  }

  /* the layer covers the top of the page on mobile, so the index hides
     under it; on desktop it stays visible */
  #projects.settings-mode #projects-menu,
  #projects.settings-mode #subcategories {
    visibility: hidden;
  }

  /* cascade navigation: one level per screen. index -> the project's
     sections -> content, with a back line on top of the deeper screens */
  /* the back line stays on screen: a thin fixed band with the logo, the
     page scrolls underneath */
  html.m-level-sections,
  html.m-level-content {
    --m-bar-height: calc(var(--ui-margin) + env(safe-area-inset-top) + 0.85rem * 1.4 + 0.7rem);
  }

  /* cascade only (archived, see MOBILE_CASCADE_ENABLED): no logo, the
     index is the home screen */
  html.m-cascade #logo {
    display: none;
  }

  html.m-cascade #projects {
    width: 100%;
    max-width: 100%;
    margin-left: 0;
  }

  /* (html: beats the later rule that shifted it left to clear the logo) */
  html.m-cascade #detail {
    left: 0;
  }

  /* menu screens (index, sections): centered horizontally, from the top */
  html.m-level-index #projects,
  html.m-level-sections #projects {
    position: fixed;
    inset: 0;
    z-index: 1;
    width: auto;
    max-width: none;
    margin: 0;
    padding: calc(var(--ui-margin) + env(safe-area-inset-top)) var(--ui-margin) calc(var(--ui-margin) + env(safe-area-inset-bottom) + 2rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow-y: auto;
    text-align: center;
  }

  html.m-level-index #projects-menu,
  html.m-level-sections #subcategories {
    margin: 0;
    align-self: center;
  }

  /* sections start under the back line */
  html.m-level-sections #projects {
    padding-top: calc(var(--m-bar-height) + 1rem);
  }

  html.m-level-content #projects {
    padding-top: calc(0.85rem * 1.4 + 1.25rem);
  }

  html.m-level-content #detail .sticky-group .discipline-brand {
    top: var(--m-bar-height);
  }

  html.m-level-sections #mobile-back,
  html.m-level-content #mobile-back {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 85;
    height: var(--m-bar-height);
    padding:
      calc(var(--ui-margin) + env(safe-area-inset-top))
      calc(var(--ui-margin) + env(safe-area-inset-right))
      0
      calc(var(--ui-margin) + env(safe-area-inset-left));
    /* no band behind it: the text floats over the images and takes the
       color that reads on them, like the "top" button (main.js) */
    background: none;
    pointer-events: none;
    text-align: left;
  }

  /* a bare arrow is a small target: pad it out for a thumb */
  #mobile-back span {
    display: inline-block;
    padding: 0.4rem 1.2rem 0.4rem 0;
    margin: -0.4rem 0;
    pointer-events: auto;
    font-size: 0.85rem;
    line-height: 1.4;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    user-select: none;
  }

  html.m-level-sections #projects-menu,
  html.m-level-content #projects-menu,
  html.m-level-index #subcategories,
  html.m-level-content #subcategories,
  html.m-level-index #detail,
  html.m-level-sections #detail {
    display: none;
  }

  /* breadcrumb navigation: once a project (or category) is open, a path
     "case / niolajet / identity" sits next to the logo at the top of the
     page. Tapping a step goes back to it. */
  html.m-crumbs {
    --m-bar-height: calc(var(--ui-margin) + env(safe-area-inset-top) + 0.85rem * 1.4 + 0.7rem);
  }

  html.m-crumbs.m-selected #projects-menu,
  html.m-crumbs #subcategories {
    display: none;
  }

  html.m-crumbs.m-selected #projects {
    padding-top: calc(0.85rem * 1.4 + 1.25rem);
  }

  /* sits at the top of the page next to the logo and scrolls away with it */
  html.m-crumbs.m-selected #mobile-crumbs {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 85;
    padding:
      calc(var(--ui-margin) + env(safe-area-inset-top))
      calc(var(--ui-margin) + env(safe-area-inset-right))
      0
      calc(var(--ui-margin) + env(safe-area-inset-left) + 2.72rem + 1.25rem);
    /* no band: the path floats over the images in a color that reads on
       them, like the "top" button (main.js) */
    pointer-events: none;
    font-size: 0.85rem;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  #mobile-crumbs [data-drop] {
    pointer-events: auto;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    user-select: none;
  }

  #mobile-crumbs [data-drop].open {
    text-decoration: underline;
    text-underline-offset: 0.12em;
  }

  html.m-crumbs.m-selected.m-drop-works #projects-menu,
  html.m-crumbs.m-selected.m-drop-sections #subcategories {
    display: block;
    position: fixed;
    top: var(--m-bar-height);
    left: 0;
    right: 0;
    z-index: 84;
    margin: 0;
    padding:
      0.6rem
      calc(var(--ui-margin) + env(safe-area-inset-right))
      1.25rem
      calc(var(--ui-margin) + env(safe-area-inset-left) + 2.72rem + 1.25rem);
    max-height: calc(100svh - var(--m-bar-height) - 4rem);
    overflow-y: auto;
    background: var(--bg);
  }

  html.m-drop-works #project-list {
    display: block;
  }

  html.settings-open #mobile-crumbs,
  html.settings-open #logo {
    display: none;
  }

  /* mobile: the icon stays fixed bottom left like on desktop, and the
     layer opens above it */
  #settings-home {
    bottom: calc(var(--ui-margin) + env(safe-area-inset-bottom));
    left: calc(var(--ui-margin) + env(safe-area-inset-left));
  }

  /* mobile: settings take the whole screen, one layer from top to bottom.
     The logo stays on top of it, the icon at the bottom closes it. */
  #settings-layer.visible {
    display: flex;
  }

  /* a real page, not a fixed overlay: Safari tints its bars from fixed
     elements touching the screen edges and never re-samples them, so the
     bars kept the old color while the layer was open */
  #settings-layer {
    position: absolute;
    flex-direction: column;
    inset: 0 0 auto 0;
    height: 100vh;
    height: 100svh;
    width: auto;
    max-height: none;
    overflow: hidden;
    overscroll-behavior: contain;
    padding:
      calc(2.6rem + env(safe-area-inset-top))
      calc(var(--ui-margin) + env(safe-area-inset-right))
      calc(var(--ui-margin) + env(safe-area-inset-bottom) + 0.85rem * 1.4 + 1.25rem)
      calc(var(--ui-margin) + env(safe-area-inset-left));
  }

  #settings-layer #info {
    flex: 0 0 auto;
  }

  #settings-layer #color-picker-panel.visible {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    margin-top: 1.25rem;
  }

  #settings-layer #color-field-wrap {
    flex: 1 1 auto;
    min-height: 0;
    aspect-ratio: auto;
  }

  #settings-layer #color-picker-controls {
    flex: 0 0 auto;
    margin-top: 1rem;
  }

  html.settings-open,
  html.settings-open body {
    overflow: hidden;
  }

  html.settings-open #projects,
  html.settings-open #back-to-top {
    display: none;
  }

  #back-to-top {
    bottom: calc(var(--ui-margin) + 1.5rem + env(safe-area-inset-bottom));
  }

  #detail {
    position: relative;
    left: calc(-2.72rem - 1.25rem);
    flex: 0 0 calc(100vw - var(--ui-margin) - var(--ui-margin));
    width: calc(100vw - var(--ui-margin) - var(--ui-margin));
    max-width: calc(100vw - var(--ui-margin) - var(--ui-margin));
    margin-left: 0;
    height: auto;
    overflow-y: visible;
  }

  #detail.lost-venom-detail {
    overflow-y: visible;
  }

  #detail li.media {
    margin-left: calc(0px - var(--ui-margin));
    margin-right: calc(0px - var(--ui-margin));
    width: calc(100% + var(--ui-margin) * 2);
  }

  #detail li.models.model-layout-pair {
    grid-template-columns: 1fr;
    height: auto;
    max-height: none;
    min-height: 0;
  }

  #detail li.models.model-layout-pair .model-viewer-wrap {
    width: 100%;
    height: min(calc(100svh - 80px), 920px);
    max-height: calc(100svh - 80px);
    min-height: 0;
    justify-self: center;
  }

  /* phones: each board lies across the full width (rotated like on desktop),
     rows sized to the board so there is no empty band between them */
  #detail li.models.model-layout-pair .model-layout-stack {
    height: auto;
    max-height: none;
    width: 100%;
    justify-self: center;
  }

  #detail li.models.model-layout-pair .model-layout-rotator {
    grid-template-rows: none;
    grid-auto-rows: 31cqw;
    width: 100%;
    height: auto;
    gap: 1rem;
  }

  #detail li.models.model-layout-pair .model-layout-frame img {
    width: auto;
    height: 96cqw;
  }

  #detail li.media.brandpanel,
  #detail li.media.colors,
  #detail li.media.columns,
  #detail li.media.homeboxmini-showcase {
    margin-left: 0;
    margin-right: 0;
    width: 100%;
  }

  /* one element at a time, full width and large, stacked like a slide
     show — instead of small side-by-side marks sharing the row */
  #detail li.media.brandpanel {
    flex-direction: column;
    align-items: stretch;
    gap: 2rem;
  }

  #detail li.media.brandpanel.logo-strip {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2.4fr);
    align-items: center;
  }

  #detail li.media.pluralia-overview {
    grid-template-columns: 1fr auto;
    gap: 1.25rem;
    padding: 0 var(--ui-margin);
  }

  #detail .pluralia-main-logo {
    grid-column: 1 / -1;
    width: min(100%, 480px);
  }

  #detail .pluralia-marks {
    justify-content: flex-start;
  }

  #detail .pluralia-marks img {
    height: clamp(42px, 15vw, 67px);
  }

  #detail .pluralia-manifesto {
    padding: 0;
  }

  #detail li.media.niolajet-overview {
    grid-template-columns: 1fr auto;
    gap: 1.25rem;
    padding: 0 var(--ui-margin);
  }

  #detail .niolajet-main-logo {
    grid-column: 1 / -1;
    width: min(100%, 560px);
  }

  #detail .niolajet-marks {
    justify-self: start;
    width: 151px;
    height: 80px;
  }

  #detail .niolajet-marks img {
    width: 100%;
  }

  #detail .niolajet-research-copy {
    padding: 0;
  }

  #detail li.media.soundliz-overview {
    grid-template-columns: 1fr auto;
    gap: 1.25rem;
    padding: 0 var(--ui-margin);
  }

  #detail .soundliz-main-logo {
    grid-column: 1 / -1;
    width: min(100%, 430px);
  }

  #detail .soundliz-marks {
    justify-content: flex-start;
    flex-wrap: wrap;
  }

  #detail .soundliz-marks img {
    height: clamp(32px, 11vw, 50px);
  }

  #detail li.media.zingaltrip-overview {
    grid-template-columns: 1fr auto;
    gap: 1.25rem;
    padding: 0 var(--ui-margin);
  }

  #detail li.media.lostvenom-overview {
    grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 0.75rem;
    padding: 0 var(--ui-margin);
  }

  #detail .lostvenom-main-logo {
    width: 100%;
  }

  #detail .lostvenom-marks {
    justify-content: flex-start;
    gap: 0.5rem;
  }

  #detail .lostvenom-marks img {
    height: 72px;
  }

  #detail .zingaltrip-main-logo {
    grid-column: 1 / -1;
    width: min(100%, 570px);
  }

  #detail .zingaltrip-marks {
    justify-content: flex-start;
    gap: 0.5rem;
  }

  #detail li.media.pluralia-overview,
  #detail li.media.niolajet-overview,
  #detail li.media.soundliz-overview,
  #detail li.media.zingaltrip-overview,
  #detail li.media.lostvenom-overview {
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: start;
    gap: 0.75rem;
  }

  #detail .pluralia-main-logo,
  #detail .niolajet-main-logo,
  #detail .soundliz-main-logo,
  #detail .zingaltrip-main-logo,
  #detail .lostvenom-main-logo {
    grid-column: auto;
    width: 100%;
    height: 72px;
    max-height: none;
  }

  #detail .pluralia-marks {
    flex-wrap: nowrap;
    gap: 0.5rem;
  }

  #detail .pluralia-marks img {
    height: clamp(32px, 10vw, 44px);
  }

  #detail .niolajet-marks {
    width: 104px;
    height: 55px;
  }

  #detail .soundliz-marks {
    flex-wrap: nowrap;
    gap: 0.4rem;
  }

  #detail .soundliz-marks img {
    height: clamp(28px, 8vw, 36px);
  }

  #detail .zingaltrip-marks img {
    height: 48px;
  }

  /* the Zingaltrip wordmark is very wide: give it the full row on phones,
     symbols and colors sit underneath */
  #detail li.media.zingaltrip-overview .zingaltrip-main-logo {
    grid-column: 1 / -1;
    height: auto;
    max-height: 54px;
  }

  #detail li.media.soundliz-overview .soundliz-main-logo {
    height: 54px;
  }

  #detail li.brandpanel.logo-strip .brandpanel-mark {
    width: 100%;
    height: auto;
    max-width: 100%;
  }

  #detail li.brandpanel .brandpanel-logo,
  #detail li.brandpanel .brandpanel-mark,
  #detail li.brandpanel .brandpanel-mark.large {
    width: 100%;
    height: auto;
    max-height: 55vh;
  }

  #detail li.media.columns {
    justify-content: center;
    flex-wrap: wrap;
    row-gap: 1.5rem;
    overflow-x: hidden;
  }

  #detail li.media.columns > .collection-col {
    flex: 1 1 100%;
    align-items: center;
  }

  #detail li.gallery {
    column-width: auto;
    column-count: 1;
  }

  #detail li.gallery.row,
  #detail li.gallery.line {
    flex-wrap: wrap;
  }

  #detail li.gallery.row-wrap {
    grid-template-columns: 1fr;
  }

  #detail li.media.columns li.gallery.row-wrap {
    grid-template-columns: repeat(var(--row-count), minmax(0, min(var(--cell-size, 1fr), calc((100% - (var(--row-count) - 1) * clamp(0.2rem, 1.5cqw, 0.5rem)) / var(--row-count)))));
    gap: clamp(0.2rem, 1.5cqw, 0.5rem);
    justify-content: center;
    width: 100%;
  }

  /* opt-in per-section (see main.js's columnsMobileFill): the cellSize
     values here were tuned for several columns sharing width side by
     side on desktop, which left a lot of dead space once each column
     wraps onto its own full-width line on mobile — ignore that cap and
     just divide the column's own full width evenly instead */
  #detail li.media.columns.mobile-fill li.gallery.row-wrap {
    grid-template-columns: repeat(var(--row-count), minmax(0, calc((100% - (var(--row-count) - 1) * clamp(0.2rem, 1.5cqw, 0.5rem)) / var(--row-count))));
  }

  #detail li.media.columns li.gallery.row-wrap:has(.model-viewer-wrap) {
    grid-template-columns: 1fr;
  }

  #detail li.media.columns li.gallery.row-wrap.fixed-cell .model-viewer-wrap {
    width: 100%;
    max-width: 100%;
    margin: 0;
  }

  .color-switch {
    --cell-size: clamp(200px, 65cqw, 320px) !important;
  }

  #detail li.media.columns .model-viewer-wrap {
    flex: none;
    aspect-ratio: 1;
    max-width: 82%;
    margin: 0 auto;
  }

  #detail li.media.columns .model-viewer-wrap.model-viewer-fabric {
    width: 100%;
    max-width: 100%;
    height: 125vw;
    aspect-ratio: auto;
  }


  #detail li.gallery.row img,
  #detail li.gallery.row video,
  #detail li.gallery.line img {
    flex: 1 1 100%;
    width: 100%;
    height: auto;
    max-height: none;
  }

  /* opt-in per-section override (see main.js's mobileRow) for a gallery
     that should keep its own desktop layout (row/row-wrap/etc.) but show
     a fixed N-per-line grid on mobile specifically, full width, ratio
     preserved by each image's own intrinsic aspect ratio */
  #detail li.gallery.mobile-row-override {
    display: grid;
    grid-template-columns: repeat(var(--mobile-row-count), 1fr);
    gap: 0;
  }

  #detail li.gallery.row-wrap.fixed-cell.mobile-row-override {
    grid-template-columns: repeat(var(--mobile-row-count), minmax(0, 1fr));
  }

  #detail li.gallery.mobile-row-override img,
  #detail li.gallery.mobile-row-override video {
    flex: none;
    width: 100%;
    height: auto;
    max-height: none;
  }

  #detail li.gallery.row .censored-wrap,
  #detail li.gallery.line .censored-wrap {
    display: block;
    flex: 1 1 100%;
    width: 100%;
  }

  #detail img {
    width: 100%;
    max-width: 100%;
  }

  #detail.niolajet-detail li.gallery:not(.slide) img {
    height: auto;
    max-height: none;
    aspect-ratio: var(--img-ar, auto); /* natural proportions, known before download */
    object-fit: contain;
  }

  /* fleet silhouettes sit in wide transparent canvases: a 2.6:1 frame trims
     only empty space (every aircraft is centred and under 31% of the width tall) */
  #detail.niolajet-detail li.gallery.line img {
    aspect-ratio: 2.6 / 1;
    object-fit: cover;
    object-position: center;
  }

  #detail li.gallery.slide {
    --slide-height: var(--slide-height-mobile, 50vh);
    touch-action: pan-x pan-y;
  }

  .book-progress {
    display: flex;
    font-size: 0.7rem !important;
    line-height: 1.2 !important;
    cursor: var(--site-cursor);
  }

  .book-progress-jump {
    min-width: auto;
    min-height: 2rem;
    font-size: 0.9rem;
    padding: 0.3rem 0.5rem;
    touch-action: manipulation;
  }

  #detail li.gallery.slide img {
    width: auto;
    max-width: none;
    height: var(--slide-height);
    max-height: var(--slide-height);
  }
}

/* tablets (iPad): finger scrolling like on phones — a book no longer traps
   the vertical scroll, and its page buttons get finger-sized targets */
@media (min-width: 701px) and (pointer: coarse) {
  #detail li.gallery.slide {
    touch-action: pan-x pan-y;
    cursor: auto;
  }

  .book-progress {
    cursor: var(--site-cursor);
  }

  .book-progress-jump {
    min-width: auto;
    min-height: 2rem;
    font-size: 0.9rem;
    padding: 0.3rem 0.5rem;
    touch-action: manipulation;
  }
}

.embed-frame {
  overflow: hidden;
  position: relative;
}

.embed-frame iframe {
  border: none;
  display: block;
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  /* a plain, standard embed: sized generously by CSS, fully interactive.
     touch it to use the site; touch beside it to scroll this page — same
     as any embedded youtube/maps widget anywhere else on the web. */
  .embed-frame {
    width: 100%;
    height: 80vh;
  }

  .embed-frame iframe {
    width: 100%;
    height: 100%;
  }

  #detail li.media.homeboxmini-showcase {
    grid-template-columns: 1fr;
    height: auto;
    min-height: 0;
  }

  #detail .homeboxmini-viewer {
    height: min(78svh, 680px);
  }

  #detail .homeboxmini-media {
    grid-template-rows: auto auto;
  }

  #detail .homeboxmini-media-top {
    min-height: 42svh;
  }

  #detail .homeboxmini-media-bottom {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    min-height: 72svh;
  }

  /* fit-rows on phones: rows take the height of their images (same scale,
     no fixed minimum leaving an empty band above bottom-aligned views) */
  #detail .fit-rows .homeboxmini-media-top,
  #detail .fit-rows .homeboxmini-media-bottom {
    min-height: 0;
  }

  #detail .fit-rows .homeboxmini-media img {
    height: auto;
  }
}

.active {
  text-decoration: underline;
}

/* inline link after a project status (e.g. linery merch → linerymerch.com) */
#detail .project-status a {
  text-decoration: underline;
  text-underline-offset: 0.12em;
}

/* stacked views inside a fit-rows showcase row (Vanhoa ring side + top) */
#detail .fit-rows .showcase-stack {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

#detail .fit-rows .homeboxmini-media .showcase-stack img {
  width: 100%;
  height: auto;
  flex: none;
}



/* products: pinned title row (see product-group in main.js) */
#detail .product-group {
  margin-top: 0;
  padding: 0;
}

#detail .product-group > ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

#detail .product-group .section-intro-row {
  position: sticky;
  top: 0;
  z-index: 3;
  padding: 0.3rem 0;
  background: var(--bg);
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  #detail .product-group .section-intro-row {
    top: env(safe-area-inset-top);
    background: transparent;
  }

  /* phones: one view per line, full width */
  #detail .homeboxmini-media,
  #detail .fit-rows .homeboxmini-media-top,
  #detail .fit-rows .homeboxmini-media-bottom,
  #detail .homeboxmini-media-top,
  #detail .homeboxmini-media-bottom,
  #detail .fit-rows .showcase-stack {
    display: flex;
    flex-direction: column;
    width: 100%;
    min-height: 0;
    gap: var(--ui-margin);
  }

  #detail .homeboxmini-media img,
  #detail .fit-rows .homeboxmini-media img,
  #detail .fit-rows .homeboxmini-media .showcase-stack img {
    flex: none;
    width: 100%;
    height: auto;
    max-height: 85svh;
    object-fit: contain;
    object-position: center;
  }

  /* one scale per row: widths follow --row-share, narrow views wrap side by side */
  #detail .fit-rows .homeboxmini-media-top,
  #detail .fit-rows .homeboxmini-media-bottom {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-end;
  }

  #detail .fit-rows .homeboxmini-media-top > img,
  #detail .fit-rows .homeboxmini-media-bottom > img {
    width: calc(var(--row-share, 1) * 100%);
    max-height: none;
    flex-grow: 0 !important; /* desktop sets flex-grow inline */
  }

  #detail .fit-rows .homeboxmini-media-top:has(.showcase-stack) {
    flex-direction: column;
  }

  /* Filtralife: the frame takes the turning product's shape (viewer3d.js
     tight fit), so the model fills it instead of floating small in a tall box */
  #detail li.media.homeboxmini-showcase.mobile-tight-fit .homeboxmini-viewer {
    height: auto;
    aspect-ratio: var(--viewer-aspect, 1);
    max-height: 78svh;
  }

  /* Lost Venom: the board is long and thin, its frame may take more of the
     screen height */
  #detail li.media.lostvenom-showcase.mobile-tight-fit .homeboxmini-viewer {
    max-height: 90svh;
  }

  /* the views first, the 3D closes the product (as on desktop) */
  #detail li.media.homeboxmini-showcase.product-line .homeboxmini-viewer {
    order: 1;
  }

  /* mobileGrid (main.js): groups of views, each group on one line at one height */
  #detail .fit-rows .homeboxmini-media-bottom.mobile-grid {
    flex-wrap: wrap;
    gap: var(--ui-margin);
  }

  #detail .fit-rows .homeboxmini-media-bottom.mobile-grid > img {
    order: var(--grid-order, 0);
    width: calc(var(--grid-share, 0.5) * (100% - var(--grid-gaps, var(--ui-margin))) - 0.5px);
  }

  /* Vanhoa bag: front and narrow side view side by side, one common height */
  #detail .vanhoa-bag-showcase.fit-rows .homeboxmini-media-top {
    flex-wrap: nowrap;
    gap: var(--ui-margin);
  }

  #detail .vanhoa-bag-showcase.fit-rows .homeboxmini-media-top > img {
    width: calc(var(--row-share, 1) / var(--row-sum, 2) * (100% - var(--row-gaps, 0px)));
  }

  /* Vanhoa ring: the side and top views share one line, one common height */
  #detail .vanhoa-ring-showcase.fit-rows .showcase-stack {
    flex-direction: row;
    align-items: flex-end;
  }

  #detail .vanhoa-ring-showcase.fit-rows .homeboxmini-media .showcase-stack img {
    width: calc(var(--stack-share, 0.5) * (100% - var(--ui-margin)));
  }

  /* Lost Venom: the boards lie flat, stacked one under the other. The line
     of standing views is turned a quarter: its height becomes the page width
     and its length (sum of aspects x width + gaps) the block height. */
  #detail .lostvenom-showcase.fit-rows .homeboxmini-media {
    position: relative;
    container-type: inline-size;
    height: calc(var(--row-aspect-sum, 1.3) * 100cqw + var(--ui-margin) * 4);
  }

  #detail .lostvenom-showcase.fit-rows .homeboxmini-media-top {
    position: absolute;
    top: 50%;
    left: 50%;
    width: calc(var(--row-aspect-sum, 1.3) * 100cqw + var(--row-gaps, 0px));
    flex-direction: row-reverse; /* first view on top once turned */
    flex-wrap: nowrap;
    gap: var(--ui-margin);
    transform: translate(-50%, -50%) rotate(-90deg); /* nose to the left */
  }

  #detail .lostvenom-showcase.fit-rows .homeboxmini-media-top > img {
    width: calc(var(--row-share, 1) / var(--row-sum, 5) * (100% - var(--row-gaps, 0px)));
  }
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  /* phones: identity = main logo full width on top; underneath, the colors
     stacked vertically on the left and the symbols on the right, sized to
     the height of the color column */
  #detail li.media.pluralia-overview,
  #detail li.media.niolajet-overview,
  #detail li.media.soundliz-overview,
  #detail li.media.zingaltrip-overview,
  #detail li.media.lostvenom-overview {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    row-gap: 1.1rem;
    column-gap: 1rem;
    padding: 0 var(--ui-margin);
    --identity-row: calc(var(--brand-swatch-size) * 3 + 14px);
  }

  #detail li.media.pluralia-overview .pluralia-main-logo,
  #detail li.media.niolajet-overview .niolajet-main-logo,
  #detail li.media.soundliz-overview .soundliz-main-logo,
  #detail li.media.zingaltrip-overview .zingaltrip-main-logo,
  #detail li.media.lostvenom-overview .lostvenom-main-logo {
    grid-column: 1 / -1;
    grid-row: 1;
    justify-self: stretch;
    width: 100%;
    height: auto;
    max-height: none;
    object-position: center;
  }

  #detail li.media.pluralia-overview .pluralia-palette,
  #detail li.media.niolajet-overview .niolajet-palette,
  #detail li.media.soundliz-overview .soundliz-palette,
  #detail li.media.zingaltrip-overview .zingaltrip-palette,
  #detail li.media.lostvenom-overview .lostvenom-palette {
    grid-column: 1;
    grid-row: 2;
    flex-direction: column;
    justify-self: start;
    align-self: center;
  }

  #detail li.media.pluralia-overview .pluralia-marks,
  #detail li.media.niolajet-overview .niolajet-marks,
  #detail li.media.soundliz-overview .soundliz-marks,
  #detail li.media.zingaltrip-overview .zingaltrip-marks,
  #detail li.media.lostvenom-overview .lostvenom-marks {
    grid-column: 2;
    grid-row: 2;
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-self: end;
    justify-content: flex-end;
    align-self: center;
    gap: 0.8rem;
    width: auto;
    height: var(--identity-row);
  }

  #detail li.media.pluralia-overview .pluralia-marks img,
  #detail li.media.niolajet-overview .niolajet-marks img,
  #detail li.media.soundliz-overview .soundliz-marks img,
  #detail li.media.zingaltrip-overview .zingaltrip-marks img,
  #detail li.media.lostvenom-overview .lostvenom-marks img {
    width: auto;
    max-width: none;
    height: var(--identity-row);
    max-height: none;
    object-fit: contain;
  }
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  /* wide, heavy symbols (SZ, ZT) read too big at the full color-column height */
  #detail li.media.soundliz-overview .soundliz-marks img,
  #detail li.media.zingaltrip-overview .zingaltrip-marks img {
    height: calc(var(--identity-row) * 0.55);
  }
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  /* phones: imagery pairs become one full-width picture per line */
  #detail li.gallery.pair-row {
    flex-direction: column;
  }

  #detail li.gallery.pair-row img {
    width: 100%;
  }

  /* pair-row-keep: the pair stays side by side on phones */
  #detail li.gallery.pair-row.pair-row-keep {
    flex-direction: row;
  }

  #detail li.gallery.pair-row.pair-row-keep img {
    width: calc(var(--pair-share, 0.5) * 100%);
  }

  /* Filtralife imagery: the pictures touch, no margin between them */
  #detail li.gallery.filtralife-imagery + li.gallery.filtralife-imagery {
    margin-top: 0;
  }

  #detail li.gallery.render-plate.filtralife-imagery {
    gap: 0;
  }
}

/* desktop "product line" (option 1): 3D square + all views on one row, one
   common height; widths come from --line-share (main.js) */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail li.media.homeboxmini-showcase.product-line {
    display: flex;
    flex-wrap: nowrap;
    align-items: flex-end;
    gap: var(--line-gap, var(--ui-margin));
    height: auto;
    min-height: 0;
  }

  #detail .product-line .homeboxmini-media,
  #detail .product-line .homeboxmini-media-top,
  #detail .product-line .homeboxmini-media-bottom {
    display: contents;
  }

  #detail .product-line .homeboxmini-viewer,
  #detail .product-line .homeboxmini-media-top > *,
  #detail .product-line .homeboxmini-media-bottom > * {
    flex: none;
    /* shares sum to 1: the 3D viewer and every view fill one line */
    width: calc(var(--line-share, 0.2) * (100% - var(--line-gaps, 0px)));
    min-width: 0;
  }

  #detail .product-line .homeboxmini-viewer {
    height: auto;
    aspect-ratio: var(--viewer-aspect, 1);
    order: 1; /* the views first, the 3D closes the line */
  }

  #detail .product-line .homeboxmini-media img {
    height: auto;
    max-height: none;
  }
}

/* Filtralife imagery plate: identical cells, every render centred on one
   ground line, read together as a single image */
#detail li.gallery.render-plate {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--ui-margin);
  column-width: auto;
}

#detail li.gallery.render-plate img {
  width: 100%;
  height: auto;
  max-height: none;
  aspect-ratio: 4 / 5;
  object-fit: contain;
  object-position: center bottom;
  padding: 6%;
  box-sizing: border-box;
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  #detail li.gallery.render-plate {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  #detail li.gallery.render-plate img {
    width: 100%;
  }

  /* two columns: one product per row, its two renders side by side */
  #detail li.gallery.render-plate img:nth-child(1) { order: 1; }
  #detail li.gallery.render-plate img:nth-child(5) { order: 2; }
  #detail li.gallery.render-plate img:nth-child(2) { order: 3; }
  #detail li.gallery.render-plate img:nth-child(6) { order: 4; }
  #detail li.gallery.render-plate img:nth-child(3) { order: 5; }
  #detail li.gallery.render-plate img:nth-child(7) { order: 6; }
  #detail li.gallery.render-plate img:nth-child(4) { order: 7; }
  #detail li.gallery.render-plate img:nth-child(8) { order: 8; }
}

/* Lost Venom: airier line, so the boards stand less tall */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail li.media.lostvenom-showcase.product-line {
    --line-gap: calc(var(--ui-margin) * 5);
  }
}

/* height-line gallery (main.js): every image at one common height */
#detail li.gallery.height-line {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--ui-margin);
  column-width: auto;
}

#detail li.gallery.height-line img {
  flex: none;
  width: calc(var(--hl-share, 0.2) * (100% - var(--hl-gaps, 0px)) - 0.5px);
  min-width: 0;
  height: auto;
  max-height: none;
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  #detail li.gallery.height-line img {
    width: calc(var(--hl-pair, 0.5) * (100% - var(--hl-pair-gaps, 0px)) - 0.5px);
  }

  #detail li.gallery.height-line.hl-mobile-stack img {
    width: 100%;
    margin-left: 0;
  }

  /* hl-join-last: no gap between the last two images */
  #detail li.gallery.height-line.hl-join-last img:last-child {
    margin-top: calc(-1 * var(--ui-margin));
  }

  /* a lone last image takes the full width */
  #detail li.gallery.height-line img:last-child:nth-child(odd) {
    width: 100%;
  }
}


/* desktop identity: one row (main logo, symbols, colors) with every piece
   centered on the same horizontal axis instead of hanging from the top */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail li.media.pluralia-overview,
  #detail li.media.niolajet-overview,
  #detail li.media.soundliz-overview,
  #detail li.media.zingaltrip-overview,
  #detail li.media.lostvenom-overview {
    align-items: center;
  }

  #detail li.media.pluralia-overview .pluralia-main-logo,
  #detail li.media.niolajet-overview .niolajet-main-logo,
  #detail li.media.soundliz-overview .soundliz-main-logo,
  #detail li.media.zingaltrip-overview .zingaltrip-main-logo,
  #detail li.media.lostvenom-overview .lostvenom-main-logo {
    align-self: center;
    object-position: left center;
  }

  #detail li.media.pluralia-overview .pluralia-marks,
  #detail li.media.niolajet-overview .niolajet-marks,
  #detail li.media.soundliz-overview .soundliz-marks,
  #detail li.media.zingaltrip-overview .zingaltrip-marks,
  #detail li.media.lostvenom-overview .lostvenom-marks,
  #detail li.media.pluralia-overview .pluralia-palette,
  #detail li.media.niolajet-overview .niolajet-palette,
  #detail li.media.soundliz-overview .soundliz-palette,
  #detail li.media.zingaltrip-overview .zingaltrip-palette,
  #detail li.media.lostvenom-overview .lostvenom-palette {
    align-self: center;
  }
}

/* the first section sits close under the project title line; the full
   section spacing stays between the following sections */
#detail .project-summary + .project-section-anchor {
  margin-top: 0.75rem;
}

/* brand anchors in the category view only mark a jump target; they add no
   space of their own */
#detail li.project-section-anchor.brand-anchor {
  margin-top: 0;
}

#subcategories.no-active li.active {
  text-decoration: none;
}

/* desktop category view: the second column already names each brand, so
   the name above its media goes; the heading keeps only its spacing */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail .discipline-brand > * {
    display: none;
  }

  /* the first brand starts right at the top, no leftover spacing */
  #detail > .brand-anchor:first-child + .discipline-brand,
  #detail > .brand-anchor:first-child + .sticky-group .discipline-brand {
    display: none;
  }

  #detail > .brand-anchor:first-child + .sticky-group {
    margin-top: 0;
  }
}

/* desktop: sections (and brands in the category view) are spaced by the
   regular ui margin, not the larger section gap */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail .project-section-anchor:not(.brand-anchor) {
    margin-top: var(--ui-margin);
  }

  #detail .discipline-brand {
    margin-top: var(--ui-margin);
  }

  /* media of the same section follow each other with no gap; the gap
     stays between sections (anchors) and brands (headings) */
  #detail li.media + li.media {
    margin-top: 0;
  }
}

/* product titles scroll with their media on every brand, not pinned */
#detail .product-group .section-intro-row,
#detail .product-group[data-project] .section-intro-row {
  position: static;
  background: none;
}

/* desktop identity category: one brand per band, spread from the top to the
   bottom of the screen (space-between); the jump anchors and empty headings
   step aside since the whole category fits on one screen */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail.identity-fill {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }

  #detail.identity-fill > .project-section-anchor,
  #detail.identity-fill > .discipline-brand {
    display: none;
  }

  #detail.identity-fill > li.media {
    flex: 0 0 auto;
    margin: 0;
  }
}

/* product titles: brand and status sit on the left, right after the name */
#detail .product-group .section-intro-row {
  justify-content: flex-start;
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  /* bag colors: a vertical column on the right, like the identity palettes,
     with no outline on the selected one */
  #detail .showcase-variant-swatches {
    left: auto;
    right: 0;
    top: 50%;
    bottom: auto;
    flex-direction: column;
    gap: 6px;
    transform: translateY(-50%);
  }

  #detail .showcase-variant-swatches .color-switch-btn.active {
    outline: none;
  }

  /* category view: the first brand starts at the regular margin, not that
     margin twice (its hidden heading used to leave the media's own gap) */
  #detail > .brand-anchor:first-child + .discipline-brand + li,
  #detail > .brand-anchor:first-child + .sticky-group .discipline-brand + li {
    margin-top: 0;
  }

  /* logo and settings icon share one height, bottom aligned */
  #logo {
    bottom: var(--ui-margin);
  }

  body #settings-home {
    height: calc(2.72rem * 375 / 1198);
  }
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  /* section titles: the status follows the title on the left,
     "editorial brand book / service brochure - printed" */
  #detail .section-intro-row {
    justify-content: flex-start;
    gap: 1ch;
  }

  #detail .section-intro-row .section-medium {
    text-align: left;
  }

  #detail .section-intro-row .section-medium::before {
    content: "- ";
  }
}

/* menu lines: a whole-pixel height at 100% and 125% zoom (22.4px), so the
   lines no longer round to uneven gaps */
#projects li {
  line-height: 1.2rem;
}

/* vanhoa ring: the front view (last photo) read a bit big next to the
   others; shrink it inside its own slot, sitting on the same baseline */
#detail .vanhoa-ring-showcase img[src*="/4-realistic-row2"] {
  transform: scale(0.84);
  transform-origin: center bottom;
}

/* desktop: media fade in once loaded (main.js adds .media-in, viewer3d.js
   adds .model-in) so pictures and 3D models appear smoothly */
@media (min-width: 701px) and (hover: hover) and (prefers-reduced-motion: no-preference), (min-width: 701px) and (pointer: fine) and (prefers-reduced-motion: no-preference), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) and (prefers-reduced-motion: no-preference) {
  #detail img,
  #detail video {
    opacity: 0;
    transition: opacity 0.7s cubic-bezier(0.22, 0.8, 0.24, 1);
  }

  #detail img.media-in,
  #detail video.media-in {
    opacity: 1;
  }

  #detail .model-pending > canvas {
    opacity: 0;
  }

  #detail .model-in > canvas {
    animation: model-fade-in 0.9s cubic-bezier(0.22, 0.8, 0.24, 1);
  }
}

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

/* language button: right of the settings icon, same height as the logo;
   opens english / français in a layer above it (desktop only) */
#lang-home,
#lang-layer {
  display: none;
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #lang-home {
    display: block;
    position: fixed;
    left: calc(var(--ui-margin) + 2.72rem + 1rem + 0.8rem + 1rem);
    bottom: var(--ui-margin);
    z-index: 90;
    width: max-content;
    height: calc(2.72rem * 375 / 1198);
    -webkit-tap-highlight-color: transparent;
  }

  #lang-home svg {
    display: block;
    height: 100%;
    width: auto;
  }

  #lang-home svg path {
    fill: var(--text);
  }

  #lang-layer {
    position: fixed;
    left: var(--ui-margin);
    bottom: calc(var(--ui-margin) + 0.85rem * 1.4 + 1rem);
    z-index: 80;
    background: var(--bg);
  }

  #lang-layer.visible {
    display: block;
  }

  #lang-layer #lang-toggle {
    margin-top: 0;
  }
}

/* desktop bottom left, left to right: logo, language, settings icon
   (icons ~0.85rem square, --d-icon-gap between each) */
:root {
  --d-icon-gap: 1.5rem;
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  /* order: logo, language, settings */
  #logo {
    left: var(--ui-margin);
  }

  #lang-home {
    left: calc(var(--ui-margin) + 2.72rem + var(--d-icon-gap));
  }

  body #settings-home {
    left: calc(var(--ui-margin) + 2.72rem + var(--d-icon-gap) + 0.85rem + var(--d-icon-gap));
  }

  #lang-layer #sort-home {
    margin-top: 0;
  }

  #lang-layer #lang-toggle {
    margin-top: 0.6rem;
  }
}

/* desktop: each layer sits one regular margin above the icons (icons are
   as tall as the logo) */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #settings-layer,
  #contact-layer,
  #lang-layer {
    bottom: calc(var(--ui-margin) * 2 + 2.72rem * 375 / 1198);
  }
}

/* language layer: sort and languages read as two lines of the project
   list (same 22.4px line: 1.2rem + 0.1rem above and below) */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #lang-layer #sort-home,
  #lang-layer #lang-toggle button {
    padding: 0.1rem 0;
    line-height: 1.2rem;
  }

  #lang-layer #lang-toggle {
    margin-top: 0;
  }
}

/* zingaltrip uniform: the overshirt (views only, no 3D) keeps the same
   line height as the other pieces (52vh; its two views are ~0.6 wide) */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail li.gallery.zingaltrip-overshirt {
    max-width: calc(52vh * 1.21 + var(--ui-margin));
  }
}

/* zingaltrip uniform on phones: a single view (the cap) does not stretch
   over the whole width */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  #detail .zingaltrip-uniform-showcase .homeboxmini-media-bottom.mobile-grid > img:only-child {
    max-width: 55%;
  }
}

/* zingaltrip uniform board: 2 x 2 on desktop (tee | cap, long sleeve |
   pants); phones keep one piece after the other */
#detail li.showcase-grid > ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #detail li.zingaltrip-uniform-grid > ul {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: calc(var(--ui-margin) * 4);
    row-gap: calc(var(--ui-margin) * 4);
    align-items: center;
  }

  #detail li.zingaltrip-uniform-grid > ul > li.media {
    margin: 0;
    min-width: 0;
  }
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  /* tee and long sleeve: the back view overlaps the front a little */
  #detail li.zingaltrip-uniform-grid > ul > li:nth-child(-n+2) .homeboxmini-media-bottom > img + img {
    position: relative;
    z-index: 1;
    transform: translateX(-14%);
  }

  #detail li.zingaltrip-uniform-grid > ul > li.media {
    justify-self: start;
  }
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  /* one piece per line, left aligned, regular spacing between lines */
  #detail li.zingaltrip-uniform-grid > ul {
    grid-template-columns: minmax(0, 1fr);
    row-gap: calc(var(--ui-margin) * 4);
  }
}

/* phones: same icon row as desktop at the bottom left, language (sort and
   english / français) then settings; the logo stays on top for the works.
   html.m-lang-button follows MOBILE_LANG_BUTTON_ENABLED (main.js) */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-lang-button #lang-home {
    display: block;
    position: fixed;
    left: calc(var(--ui-margin) + env(safe-area-inset-left));
    bottom: calc(var(--ui-margin) + env(safe-area-inset-bottom));
    z-index: 90;
    width: max-content;
    height: calc(0.85rem * 1.4);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  html.m-lang-button #lang-home svg {
    display: block;
    height: 100%;
    width: auto;
  }

  html.m-lang-button #lang-home svg path {
    fill: var(--text);
  }

  html.m-lang-button #settings-home {
    left: calc(var(--ui-margin) + env(safe-area-inset-left) + 0.85rem * 1.4 + 1.25rem);
  }

  html.m-lang-button #lang-layer.visible {
    display: block;
    position: fixed;
    left: calc(var(--ui-margin) + env(safe-area-inset-left));
    bottom: calc(var(--ui-margin) * 2 + env(safe-area-inset-bottom) + 0.85rem * 1.4);
    z-index: 80;
    background: var(--bg);
    font-size: 0.85rem;
    line-height: 1.4;
  }

  html.m-lang-button #lang-layer #sort-home {
    margin-top: 0;
  }

  html.m-lang-button #lang-layer #lang-toggle {
    margin-top: 0.6rem;
  }
}

/* phones: the logo joins the bottom row like on desktop, language, logo,
   settings; it opens the mail above the row. The works list takes the left
   edge it leaves free. html.m-bottom-logo follows MOBILE_BOTTOM_LOGO_ENABLED */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #logo,
  html.m-bottom-logo.settings-open #logo {
    display: block;
    position: fixed;
    top: auto;
    bottom: calc(var(--ui-margin) + env(safe-area-inset-bottom) + (0.85rem * 1.4 - 2.72rem * 375 / 1198) / 2);
    left: calc(var(--ui-margin) + env(safe-area-inset-left) + 0.85rem * 1.4 + 1.25rem);
    z-index: 90;
  }

  html.m-bottom-logo #settings-home {
    left: calc(var(--ui-margin) + env(safe-area-inset-left) + 0.85rem * 1.4 + 1.25rem + 2.72rem + 1.25rem);
  }

  html.m-bottom-logo #projects {
    width: 100%;
    max-width: 100%;
    margin-left: 0;
  }

  html.m-bottom-logo #detail {
    left: 0;
  }

  html.m-bottom-logo #contact-layer.visible {
    display: block;
    left: calc(var(--ui-margin) + env(safe-area-inset-left));
    bottom: calc(var(--ui-margin) * 2 + env(safe-area-inset-bottom) + 0.85rem * 1.4);
  }

  /* the mail moved behind the logo, out of the settings page */
  html.m-bottom-logo #info #contact-panel {
    display: none;
  }
}

/* phones: the icon row takes the color that reads on the picture
   underneath, like the "top" button (main.js sets --icon-color) */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #lang-home svg path,
  html.m-bottom-logo #logo svg path,
  html.m-bottom-logo #settings-home svg path {
    fill: var(--icon-color, var(--text));
  }
}

/* phones: the icon row (language, logo, settings) is centered at the
   bottom; its layers open centered above it */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo {
    --m-icon: calc(0.85rem * 1.4);
    --m-gap: 2rem;
    --m-row-start: calc(50% - (var(--m-icon) * 2 + 2.72rem + var(--m-gap) * 2) / 2);
  }

  html.m-bottom-logo #lang-home {
    left: var(--m-row-start);
  }

  html.m-bottom-logo #logo,
  html.m-bottom-logo.settings-open #logo {
    left: calc(var(--m-row-start) + var(--m-icon) + var(--m-gap));
  }

  html.m-bottom-logo #settings-home {
    left: calc(var(--m-row-start) + var(--m-icon) + var(--m-gap) + 2.72rem + var(--m-gap));
  }

  html.m-bottom-logo #lang-layer.visible,
  html.m-bottom-logo #contact-layer.visible {
    left: 50%;
    transform: translateX(-50%);
    text-align: center;
  }
}

/* phones: "top" is an arrow, centered a bit higher above the icon row so
   the two no longer crowd each other */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #back-to-top {
    bottom: calc(var(--ui-margin) + env(safe-area-inset-bottom) + 0.85rem * 1.4 + 2rem);
    padding: 0.4rem 0.8rem;
    font-size: 1.3rem;
    margin-bottom: -0.4rem;
    -webkit-tap-highlight-color: transparent;
  }

  html.m-bottom-logo #back-to-top span {
    display: none;
  }

  html.m-bottom-logo #back-to-top::before {
    content: "↑";
  }
}

/* phones: the theme is a small layer above the icon row (colors only), the
   page stays visible and scrollable underneath so the change shows live.
   html.m-compact-theme follows MOBILE_COMPACT_THEME_ENABLED (main.js) */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-compact-theme #settings-layer {
    position: fixed;
    inset: auto calc(var(--ui-margin) + env(safe-area-inset-right)) calc(var(--ui-margin) * 2 + env(safe-area-inset-bottom) + 0.85rem * 1.4) calc(var(--ui-margin) + env(safe-area-inset-left));
    z-index: 80;
    /* (!important: the desktop width, 18rem, and the width main.js fits
       to the content column must not narrow it here) */
    width: auto !important;
    height: auto;
    padding: 0;
    background: var(--bg);
  }

  html.m-compact-theme #settings-layer #info {
    display: none;
  }

  html.m-compact-theme #settings-layer #color-picker-panel.visible {
    flex: none;
    position: static;
    left: auto;
    width: 100%;
    max-width: none;
    margin-top: 0;
  }

  /* a square field, centered, small enough for the page to stay in view
     above it; the hue bar takes the same width */
  html.m-compact-theme {
    --theme-square: min(100%, 34svh);
  }

  html.m-compact-theme #settings-layer #color-picker-panel.visible {
    align-items: center;
  }

  html.m-compact-theme #settings-layer #color-field-wrap,
  html.m-compact-theme #settings-layer #color-picker-controls {
    width: var(--theme-square);
    align-self: center;
  }

  html.m-compact-theme #settings-layer #color-field-wrap {
    flex: none;
    height: auto;
    aspect-ratio: 1;
  }

  html.m-compact-theme.settings-open {
    overflow-x: hidden;
    overflow-y: auto;
  }

  html.m-compact-theme.settings-open body {
    overflow: clip;
  }

  html.m-compact-theme.settings-open #projects {
    display: flex;
  }

  html.m-compact-theme #projects.settings-mode #projects-menu,
  html.m-compact-theme #projects.settings-mode #subcategories {
    visibility: visible;
  }

  /* the arrow would sit under the layer */
  html.m-compact-theme.settings-open #back-to-top {
    display: none;
  }
}

/* phones: an open layer (language, contact, theme) has no block behind
   it any more; instead the bottom of the screen fades into a blurred veil
   of the page color, like iOS behind the clock, so the page still shows
   through and the layer stays readable */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #lang-layer.visible,
  html.m-bottom-logo #contact-layer.visible {
    background: none;
  }

  /* (!important: main.js also paints the theme color inline on the layer,
     a fix for the old full-screen page) */
  html.m-compact-theme #settings-layer {
    background: none !important;
  }

  /* the arrow would sit in the open layer */
  html.m-bottom-logo:has(#lang-layer.visible, #contact-layer.visible) #back-to-top {
    display: none;
  }

  /* Safari on iPhone never draws fixed elements under its floating
     toolbar: it fills that area itself with the color of a fixed element
     touching the bottom edge, which did not happen here; see #m-veil */
  /* --veil-content: how high the veil stays dense (the icon row, plus
     the open layer); --veil-fade: the soft fade above it, so the gradient
     always ends above the content, never across it */
  html.m-bottom-logo {
    --veil-row: calc(var(--ui-margin) * 2 + env(safe-area-inset-bottom) + 0.85rem * 1.4);
    --veil-fade: 8rem;
    --veil-content: var(--veil-row);
    /* room left under the last content: up to where the closed veil gets
       light (its top fade may still pass over it) */
    --veil-closed-h: calc(var(--veil-row) + 2rem);
    --veil-h: calc(var(--veil-content) + var(--veil-fade));
  }

  /* closed: a lighter, shorter veil behind the icon row */
  html.m-bottom-logo:not(:has(#lang-layer.visible, #contact-layer.visible, #settings-layer.visible)) {
    --veil-fade: 5rem;
  }

  /* language: sort + languages, two lines above the row */
  html.m-bottom-logo:has(#lang-layer.visible) {
    --veil-content: calc(var(--veil-row) + 1.4rem * 2 + 0.6rem + 0.6rem);
  }

  /* contact: the mail, one line */
  html.m-bottom-logo:has(#contact-layer.visible) {
    --veil-content: calc(var(--veil-row) + 1.4rem + 0.6rem);
  }

  /* theme: color field + hue bar */
  html.m-compact-theme.settings-open {
    --veil-content: calc(var(--veil-row) + 34svh + 1rem + 1.2rem + 0.6rem);
  }

  /* the end of the page can scroll clear of the veil and the icon row:
     the last pictures and colors are no longer hidden under them */
  /* (on the content, not on body: the sticky veil comes after the content
     and would otherwise rise with the space) */
  html.m-bottom-logo #projects {
    padding-bottom: var(--veil-closed-h);
  }

  /* the veil itself (#m-veil, main.js). Safari on iPhone never draws a
     fixed element under its floating toolbar, but it does draw the page
     there: so the veil is part of the page, stuck to the bottom of the
     screen (sticky), and runs on under the toolbar to fill it */
  html.m-bottom-logo #m-veil {
    display: block;
    position: sticky;
    bottom: 0;
    order: 999;
    flex: 0 0 auto;
    /* a short page (home): pushed down to the bottom of the screen */
    margin-top: auto;
    height: 0;
    width: 100vw;
    margin-left: calc(-1 * (var(--ui-margin) + env(safe-area-inset-left)));
    z-index: 70;
    pointer-events: none;
  }

  html.m-bottom-logo #m-veil::before {
    content: "";
    position: absolute;
    /* wider than the screen: the blur's soft side edges stay off screen */
    left: -2rem;
    right: -2rem;
    bottom: -12rem;
    height: calc(var(--veil-h) + 12rem);
    /* one eased curve over the whole height (no dense band, then a fade):
       strong at the screen edge, melting away smoothly to nothing at the
       top, which still ends above the open layer */
    background: linear-gradient(
      to top,
      var(--bg) 0,
      var(--bg) 12rem,
      color-mix(in srgb, var(--bg) 90%, transparent) calc(12rem + var(--veil-h) * 0.1),
      color-mix(in srgb, var(--bg) 80%, transparent) calc(12rem + var(--veil-h) * 0.22),
      color-mix(in srgb, var(--bg) 68%, transparent) calc(12rem + var(--veil-h) * 0.34),
      color-mix(in srgb, var(--bg) 55%, transparent) calc(12rem + var(--veil-h) * 0.46),
      color-mix(in srgb, var(--bg) 42%, transparent) calc(12rem + var(--veil-h) * 0.58),
      color-mix(in srgb, var(--bg) 30%, transparent) calc(12rem + var(--veil-h) * 0.69),
      color-mix(in srgb, var(--bg) 19%, transparent) calc(12rem + var(--veil-h) * 0.79),
      color-mix(in srgb, var(--bg) 10%, transparent) calc(12rem + var(--veil-h) * 0.88),
      color-mix(in srgb, var(--bg) 4%, transparent) calc(12rem + var(--veil-h) * 0.95),
      transparent 100%
    );
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    -webkit-mask-image: linear-gradient(
      to top,
      #000 calc(12rem + var(--veil-h) * 0.35),
      rgba(0, 0, 0, 0.85) calc(12rem + var(--veil-h) * 0.48),
      rgba(0, 0, 0, 0.65) calc(12rem + var(--veil-h) * 0.6),
      rgba(0, 0, 0, 0.44) calc(12rem + var(--veil-h) * 0.71),
      rgba(0, 0, 0, 0.25) calc(12rem + var(--veil-h) * 0.81),
      rgba(0, 0, 0, 0.1) calc(12rem + var(--veil-h) * 0.9),
      transparent 100%
    );
    mask-image: linear-gradient(
      to top,
      #000 calc(12rem + var(--veil-h) * 0.35),
      rgba(0, 0, 0, 0.85) calc(12rem + var(--veil-h) * 0.48),
      rgba(0, 0, 0, 0.65) calc(12rem + var(--veil-h) * 0.6),
      rgba(0, 0, 0, 0.44) calc(12rem + var(--veil-h) * 0.71),
      rgba(0, 0, 0, 0.25) calc(12rem + var(--veil-h) * 0.81),
      rgba(0, 0, 0, 0.1) calc(12rem + var(--veil-h) * 0.9),
      transparent 100%
    );
  }

  /* the row always sits on the veil: icons read in the page's text color
     (main.js would otherwise tint them from the picture); the arrow sits
     above the veil and keeps its tint */
  html.m-bottom-logo :is(#lang-home, #logo, #settings-home) svg path {
    fill: var(--text);
  }
}

#m-veil {
  display: none;
}

/* phones: the lines inside the layers are centered too, on the icon row */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #lang-layer #sort-home {
    text-align: center;
  }

  html.m-bottom-logo #lang-layer #lang-toggle {
    justify-content: center;
  }

  html.m-bottom-logo #contact-layer {
    text-align: center;
  }
}

/* phones: the arrow joins the icon row, on its line to the right (the
   three icons stay centered); it shows once the page is scrolled. It sits
   on the veil like the icons, so it reads in the text color */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #back-to-top {
    /* centered in the free space between the settings icon and the
       screen edge, not pushed against the edge */
    left: calc(75% + (var(--m-icon) * 2 + 2.72rem + var(--m-gap) * 2) / 4);
    right: auto;
    /* (+2px: the arrow's ink sits on the icons' optical center) */
    bottom: calc(var(--ui-margin) + env(safe-area-inset-bottom) - 0.4rem + 2px);
    height: calc(0.85rem * 1.4 + 0.8rem);
    padding: 0.4rem 0.8rem;
    margin: 0;
    font-size: 1.15rem;
    line-height: calc(0.85rem * 1.4);
    color: var(--text) !important;
    transform: translate(-50%, 0.5rem);
  }

  html.m-bottom-logo #back-to-top.visible {
    transform: translate(-50%, 0);
  }
}

/* phones and tablets: the usual 13px margin above the list, except under
   a notch (iPhone), where the status bar area already leaves the room: there
   the list sits right under it (body's padding-top is 2.6rem + the safe
   area) */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #projects {
    margin-top: calc(max(0px, var(--ui-margin) - env(safe-area-inset-top)) - 2.6rem);
  }
}

/* desktop: the "top" button is an arrow in the bottom right, as far from
   the right edge as from the bottom edge */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #back-to-top {
    /* one site margin inside the picture's edge (the pictures already stop
       a margin short of the window; the 0.3rem padding is the tap area) */
    --top-arrow-gap: calc(var(--ui-margin) * 2 - 0.3rem);
    left: auto;
    right: var(--top-arrow-gap);
    bottom: var(--top-arrow-gap);
    padding: 0.3rem;
    font-size: 1rem;
    transform: translateY(0.5rem);
  }

  #back-to-top.visible {
    transform: translateY(0);
  }

  #back-to-top span {
    display: none;
  }

  #back-to-top::before {
    content: "↑";
  }
}

/* the arrow is drawn like the book's arrows (← →): Syne Mono has no ← →,
   so those fall back to the system monospace; ↑ exists in Syne Mono and
   looked different, so it takes the same fallback font */
#back-to-top::before {
  font-family: monospace;
}

/* the arrow is the books' "go to the end" arrow (→|) turned to point up:
   arrow + bar, "to the very top"; same glyphs, rotated a quarter turn */
#back-to-top::before {
  content: "→|" !important;
  display: inline-block;
  transform: rotate(-90deg);
  /* same fonts as the books: the bar from the site font, the arrow from
     the fallback (overrides the monospace set for the old ↑ above) */
  font-family: var(--font);
}

/* and the books' size: 0.9rem on phones, 0.85rem on desktop */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #back-to-top {
    font-size: 0.9rem;
  }
}

@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #back-to-top {
    font-size: 0.85rem;
  }
}

/* phones: section and product titles like desktop, the status follows the
   title on the left, "editorial brand book / service brochure - printed";
   a title too long for the line sends the status to the next one */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  #detail .section-intro-row {
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 0 1ch;
  }

  #detail .section-intro-row .section-medium {
    text-align: left;
  }

  #detail .section-intro-row .section-medium::before {
    content: "- ";
  }
}

/* phones: bag colors stay centered under the bag, but read like desktop:
   the same 6px between them, no frame around the selected one */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  #detail .showcase-variant-swatches {
    gap: 6px;
  }

  #detail .showcase-variant-swatches .color-switch-btn.active {
    outline: none;
  }
}

/* phones, category view (not identity): no brand names in the
   page (imagery titles, "niolajet - " before a status); the brand being
   looked at shows in the veil instead (#m-brand), left of the icons.
   html.m-brand-row is set by main.js */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-brand-row #detail .sticky-group:not(.product-group) .discipline-brand,
  html.m-brand-row #detail .section-brand,
  html.m-brand-row #detail .discipline-brand > a:not(.brand-visit) {
    display: none;
  }

  /* web: the brand heading keeps only "visit site ↗" */
  html.m-brand-row #detail .discipline-brand > .brand-visit {
    display: inline;
  }

  /* left of the icon row, mirroring the arrow on the right: centered in
     the free space between the screen edge and the language icon */
  html.m-bottom-logo #m-brand {
    display: block;
    position: fixed;
    left: calc(25% - (var(--m-icon) * 2 + 2.72rem + var(--m-gap) * 2) / 4);
    /* (+1px: the letters' optical center on the icons') */
    bottom: calc(var(--ui-margin) + env(safe-area-inset-bottom) + 1px);
    z-index: 90;
    max-width: calc(50% - (var(--m-icon) * 2 + 2.72rem + var(--m-gap) * 2) / 2 - 0.5rem);
    font-size: 0.85rem;
    line-height: calc(0.85rem * 1.4);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--text);
    pointer-events: none;
    opacity: 0;
    transform: translate(-50%, 0.5rem);
    transition: opacity 0.2s ease, transform 0.2s ease;
  }

  html.m-bottom-logo #m-brand.visible {
    opacity: 1;
    transform: translate(-50%, 0);
  }

  /* like the arrow: steps aside while a layer is open */
  html.m-bottom-logo:has(#lang-layer.visible, #contact-layer.visible, #settings-layer.visible) #m-brand {
    opacity: 0;
  }
}

#m-brand {
  display: none;
}

/* "visit site" in a brand heading only shows on phones in category view */
#detail .discipline-brand > .brand-visit {
  display: none;
}

/* phones, category view: the first brand starts at the same 20px under the
   menu as a project does (not that plus the 28px space kept between brands
   and the empty brand title); the space between brands stays */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-brand-row #detail > .brand-anchor:first-child + .discipline-brand,
  html.m-brand-row #detail > .brand-anchor:first-child + .sticky-group {
    margin-top: 0;
  }

  html.m-brand-row #detail > .brand-anchor:first-child + .discipline-brand:empty {
    display: none;
  }

  /* imagery: its brand title is hidden, so the first picture drops its own
     gap too */
  html.m-brand-row #detail > .brand-anchor:first-child + .sticky-group > ul > .discipline-brand + li {
    margin-top: 0;
  }
}

/* phones: until the embedded site shows in full, a clear shield lies over
   it so a swipe there scrolls this page (main.js setupEmbedFrame); once it
   shows in full the shield goes and the site scrolls under the finger */
.embed-shield {
  display: none;
}

.embed-frame.embed-locked .embed-shield {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 1;
  background: transparent;
}

.embed-frame.embed-locked iframe {
  pointer-events: none;
}

/* first arrival (inline script in index.html): the page waits for its font
   (0.3s at most), then fades in when html.entrance-fade is set */
html.fonts-pending body {
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  html.entrance-fade body {
    transition: opacity 0.25s ease;
  }
}

/* introduction (main.js INTRO_SORT_ENABLED): "sort by" and its two choices
   in the middle of the screen; the menu waits behind until one is picked,
   the bottom icons (language, contact, theme) stay */
#intro-sort {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: center;
  pointer-events: none;
}

#intro-sort p {
  margin: 0;
}

/* phones and tablets: "browse by" in the middle, right above the choices
   (desktop puts the whole list top left, below) */
#intro-sort {
  /* one space everywhere: between "browse by" and the choices as between
   the two choices; the block sits a little above the middle (optical
   center), not the exact one */
  --intro-gap: 1.25rem;
  /* (the lines' own height already adds ~10px of air between them) */
  gap: calc(var(--intro-gap) - 10px);
  padding-bottom: 14svh;
}

#intro-sort .intro-sort-title {
  padding: 0.1rem 0;
  line-height: 1.2rem;
}

/* case, category: the middle of the screen, apart like the bottom icons */
#intro-sort .intro-sort-choices {
  display: flex;
  justify-content: center;
  gap: var(--intro-gap);
  line-height: 1.2rem;
}

#intro-sort button {
  appearance: none;
  border: 0;
  padding: 0.4rem 0;
  margin: -0.4rem 0;
  text-decoration: underline;
  text-underline-offset: 0.12em;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}

/* (!important: the theme layer brings the menu back into view on phones) */
html.intro-open #projects,
html.intro-open #projects *,
html.intro-open #m-brand {
  visibility: hidden !important;
}

/* while the introduction asks for the order, the language layer doesn't
   offer it a second time: just the languages */
html.intro-open #lang-layer #sort-home {
  display: none;
}

html.intro-open #lang-layer #lang-toggle {
  margin-top: 0;
}

/* sort in the language layer: "case  category" laid out like the languages
   under it (same gap, the current one underlined by .active) */
#sort-home {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.7rem;
}

#sort-home button {
  background: none;
  border: none;
  padding: 0.1rem 0;
  color: var(--text);
  font: inherit;
  line-height: inherit;
  cursor: pointer;
}

/* phones: centered like the languages in the centered layer; desktop keeps
   the layer's left edge */
@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  html.m-bottom-logo #lang-layer #sort-home {
    justify-content: center;
  }
}

/* desktop: the introduction sits where the menu starts, top left, as a
   list: "browse by", then case and category under it */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  #intro-sort {
    align-items: flex-start;
    justify-content: flex-start;
    gap: 0;
    padding: var(--ui-margin);
    padding-bottom: var(--ui-margin);
    text-align: left;
  }

  #intro-sort .intro-sort-title {
    position: static;
  }

  #intro-sort .intro-sort-choices {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }

  #intro-sort .intro-sort-title,
  #intro-sort button {
    padding: 0.1rem 0;
    margin: 0;
    line-height: 1.2rem;
  }
}

/* 3D models off (main.js MODELS_ENABLED): the spot keeps its size, a line of
   text in its middle */
.model-off {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 12rem;
}

.model-off-note {
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: center;
}

/* archived (the row is back): desktop icons in a column against the left
   edge, bottom left, from the top language, logo, settings; their layers
   open above it. Only with html.d-icon-column, which nothing sets now */
@media (min-width: 701px) and (hover: hover), (min-width: 701px) and (pointer: fine), (min-width: 701px) and (orientation: landscape) and (min-height: 601px) {
  html.d-icon-column {
    --d-icon-h: calc(2.72rem * 375 / 1198);
    --d-icon-vgap: 1rem;
  }

  html.d-icon-column body #settings-home,
  html.d-icon-column #logo,
  html.d-icon-column #lang-home {
    left: var(--ui-margin);
    top: auto;
  }

  html.d-icon-column body #settings-home {
    bottom: var(--ui-margin);
  }

  html.d-icon-column #logo {
    bottom: calc(var(--ui-margin) + var(--d-icon-h) + var(--d-icon-vgap));
  }

  html.d-icon-column #lang-home {
    bottom: calc(var(--ui-margin) + (var(--d-icon-h) + var(--d-icon-vgap)) * 2);
  }

  html.d-icon-column #settings-layer,
  html.d-icon-column #contact-layer,
  html.d-icon-column #lang-layer {
    bottom: calc(var(--ui-margin) * 2 + var(--d-icon-h) * 3 + var(--d-icon-vgap) * 2);
  }
}

/* loading: a photo shows its tiny blurred copy (main.js applyImagePreview)
   right away and the sharp picture lands on top of it, so it never shows as
   an empty gap and doesn't need to fade; transparent art has no copy and
   fades in, now on phones and tablets too */
#detail img.has-preview {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

#detail img.has-preview,
#detail img.preview-shown {
  opacity: 1 !important;
}

@media (max-width: 700px), (hover: none) and (pointer: coarse) and (orientation: portrait), (hover: none) and (pointer: coarse) and (max-height: 600px) {
  @media (prefers-reduced-motion: no-preference) {
    /* (only what hasn't faded in yet: a stronger hide rule kept even faded-in
       pictures invisible on phones) */
    #detail img:not(.media-in):not(.has-preview):not(.preview-shown),
    #detail video:not(.media-in) {
      opacity: 0;
    }

    #detail img,
    #detail video {
      transition: opacity 0.6s cubic-bezier(0.22, 0.8, 0.24, 1);
    }

    #detail img.media-in,
    #detail video.media-in {
      opacity: 1;
    }
  }
}
