/* ==========================================================================
   Design system: content components
   Search Tool, Cards, Hero, CTA Banner, Project Editor, Contact, Mesh Selection,
   Section Heading (added for the shop, see the end of the file).
   Ported from the designer's export, same class names. Every selector is prefixed with :where(.ds): same specificity as the export, but no effect outside .ds containers.
   ========================================================================== */

/* ---- Search Tool ----
   Search Bar + filter Chips + sort (Ghost Button) + Summary.
   Logic: public/ds/js/components/search-tool.js */
:where(.ds) .search-tool {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2xl);
  width: 100%;
  max-width: var(--container-max-width);
}

:where(.ds) .search-tool__search {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

:where(.ds) .search-tool__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-md);
}

:where(.ds) .search-tool__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-sm);
}

/* Summary: counter, then active filters (accent Tags + Remove) and "Clear all" */
:where(.ds) .search-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-md) var(--spacing-lg);
}
:where(.ds) .search-summary__count {
  font-size: var(--type-display-h6);
  font-weight: var(--font-weight-heavy);
  line-height: var(--line-height-tight);
}
:where(.ds) .search-summary__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-sm);
}

/* ---- Cards ----
   Same anatomy everywhere: Media (Card / Image) · Hover overlay · Body.
   .card + --vertical / --horizontal / --profile · --filled · --zoom (image zoom on hover).
   Radius/lg, Shadow/MD (Hover: Shadow/LG). */
:where(.ds) .card {
  position: relative;
  display: flex;
  overflow: hidden;
  border: 1px solid var(--border-quaternary);
  border-radius: var(--radius-lg);
  background-color: var(--background-primary);
  color: var(--content-primary);
  box-shadow: var(--shadow-md);
  isolation: isolate; /* the overlay goes behind the content without leaving the card */
  transition: box-shadow var(--duration-base) var(--ease-standard);
}

:where(.ds) .card:hover,
:where(.ds) .card:focus-within {
  box-shadow: var(--shadow-lg);
}

/* Hover veil (absolute layer, first child): kept in the markup, but the background no longer
   changes on card hover (only the shadow and the image zoom react) */
:where(.ds) .card__overlay {
  position: absolute;
  z-index: -1;
  inset: -1px;
  pointer-events: none;
}

:where(.ds) .card__media {
  position: relative;
  flex-shrink: 0;
  overflow: hidden;
  background-color: var(--background-primary);
}
:where(.ds) .card__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--duration-slow) var(--ease-standard);
}
/* Hover Zoom: the image grows by 9 px on each side */
:where(.ds) .card--zoom:is(:hover, :focus-within) .card__media img {
  transform: scale(1.1);
}

:where(.ds) .card__body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
  min-width: 0;
  padding: var(--spacing-lg);
}

:where(.ds) .card__title {
  font-size: var(--type-display-h6);
  font-weight: var(--font-weight-heavy);
  line-height: var(--line-height-display);
}

:where(.ds) .card__text {
  color: var(--content-tertiary);
  font-size: var(--type-body-sm);
  line-height: var(--line-height-text);
}

:where(.ds) .card__actions {
  display: flex;
  justify-content: flex-end;
  margin-top: auto;
}

/* Card / Background: Secondary */
:where(.ds) .card--bg-secondary {
  background-color: var(--background-secondary);
}
/* Card without .card__link: no hover effect */
:where(.ds) .card:not(:has(.card__link)):is(:hover, :focus-within) {
  box-shadow: var(--shadow-md);
}

/* Showcase: project of the gallery, the image fills the height above the caption */
:where(.ds) .card--showcase {
  flex-direction: column;
}
:where(.ds) .card--showcase .card__media {
  flex: 1;
  width: 100%;
  min-height: 0;
}
:where(.ds) .card__caption {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  padding: var(--spacing-lg);
}
:where(.ds) .card--showcase .card__title {
  font-size: var(--type-label-lg);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
}
:where(.ds) .card__caption-meta {
  color: var(--content-tertiary);
  font-size: var(--type-label-sm);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}

/* Social (Figma Card / Social 11182:2112): the whole card opens the network in a new tab */
:where(.ds) .card--social {
  flex-direction: column;
  gap: var(--spacing-md);
  min-height: 234px;
  padding: var(--spacing-lg);
  box-shadow: none;
}
:where(.ds) .card--social:is(:hover, :focus-within) {
  box-shadow: var(--shadow-sm);
}
:where(.ds) .card__social-icon {
  width: 32px;
  height: 32px;
}
:where(.ds) .card__social-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--spacing-sm);
}
:where(.ds) .card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: var(--spacing-sm);
}
:where(.ds) .card__count {
  color: var(--content-tertiary);
  font-size: var(--type-label-sm);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
:where(.ds) .card__social-arrow {
  display: inline-flex;
}
:where(.ds) .card__social-arrow .icon {
  width: 20px;
  height: 20px;
}

/* Card / Action: text (Label/MD Strong). The whole card stays clickable through .card__link */
:where(.ds) .card__action {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-xs);
  padding-top: 2px;
  color: var(--content-primary);
  font-size: var(--type-label-md);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-tight);
  text-decoration: none;
}

/* The title link stretches its clickable area over the whole card */
:where(.ds) .card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
:where(.ds) .card__link:focus-visible {
  outline: none;
}
:where(.ds) .card:has(.card__link:focus-visible) {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}

/* ---- Media Slideshow: several photos sliding by themselves in a card's media ----
   .card__media.media-slideshow[data-slideshow] > ul.media-slideshow__track > li.media-slideshow__slide > img.
   Continuous loop, one photo every 3 to 5 s (2 to 3.5 s on mobile, random); direction set by
   data-slideshow-direction (left · up · right · down, set by public/ds/js/components/media-slideshow.js).
   No controls. Reduced motion: no automatic sliding. */
:where(.ds) .media-slideshow__track {
  position: absolute;
  inset: 0;
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* The next photos wait on the side they come from. The track is as long as all its photos
   (--slides, set by the JS) and anchored on the side of the first one: with a reversed flex
   direction, photos overflowing a 100% track to the top or left were painted with glitches
   in Safari while sliding */
:where(.ds) .media-slideshow__track[style*="--slides"] { right: auto; width: calc(var(--slides) * 100%); }
:where(.ds) [data-slideshow-direction="right"] > .media-slideshow__track[style*="--slides"] { flex-direction: row-reverse; left: auto; right: 0; }
:where(.ds) :is([data-slideshow-direction="up"], [data-slideshow-direction="down"]) > .media-slideshow__track[style*="--slides"] { right: 0; width: auto; height: calc(var(--slides) * 100%); }
:where(.ds) [data-slideshow-direction="up"] > .media-slideshow__track[style*="--slides"] { flex-direction: column; bottom: auto; }
:where(.ds) [data-slideshow-direction="down"] > .media-slideshow__track[style*="--slides"] { flex-direction: column-reverse; top: auto; }
:where(.ds) .media-slideshow__track.is-moving {
  transition: transform 0.7s cubic-bezier(0.45, 0, 0.2, 1); /* gentle start and arrival */
}
:where(.ds) .media-slideshow__slide {
  position: relative;
  flex: 0 0 calc(100% / var(--slides, 1));
}

/* Vertical: M 384 (media 180) · L 577 (media 280) */
:where(.ds) .card--vertical {
  flex-direction: column;
  width: 100%;
  max-width: 384px;
}
:where(.ds) .card--vertical .card__media {
  height: 180px;
}
/* The body fills the card: the action stays at the bottom whatever the title length */
:where(.ds) .card--vertical .card__body {
  flex: 1;
}
:where(.ds) .card--vertical .card__text {
  min-height: calc(var(--type-body-sm) * var(--line-height-text) * 4);
}
:where(.ds) .card--vertical-l {
  max-width: 577px;
}
:where(.ds) .card--vertical-l .card__media {
  height: 280px;
}
:where(.ds) .card--vertical-l .card__title {
  font-size: var(--type-display-h5);
}
:where(.ds) .card--vertical-l .card__text {
  font-size: var(--type-body-md);
}

/* Mobile (Figma Card / Vertical, Mobile mode): 8 px between the title and the text,
   16 px before the action */
@media (max-width: 767px) {
  :where(.ds) .card--vertical .card__body { gap: var(--spacing-sm); }
  :where(.ds) .card--vertical .card__actions { padding-top: var(--spacing-sm); }
}

/* Horizontal: 180 square media on the left, span-6 */
:where(.ds) .card--horizontal {
  width: 100%;
  max-width: 708px;
  min-height: 180px;
}
:where(.ds) .card--horizontal .card__media {
  width: 180px;
  min-height: 180px;
}
:where(.ds) .card--horizontal .card__body {
  flex: 1;
}
:where(.ds) .card--filled {
  background-color: var(--background-primary-hover); /* fixed background, no change on hover */
}

@media (max-width: 767px) {
  :where(.ds) .card--horizontal {
    flex-direction: column;
  }
  :where(.ds) .card--horizontal .card__media {
    width: 100%;
    height: 180px;
    min-height: 0;
  }
}

/* Profile: 180 cover, 2XL avatar straddling it (16 / -34), name + verified, meta, tags */
:where(.ds) .card--profile {
  --card-cover-height: 180px;
  flex-direction: column;
  width: 100%;
  max-width: 708px;
}
:where(.ds) .card--profile .card__media {
  height: var(--card-cover-height);
}
:where(.ds) .card--profile .card__body {
  padding: var(--spacing-md);
}
:where(.ds) .card--profile .avatar {
  position: absolute;
  top: calc(var(--card-cover-height) - 34px); /* straddling the cover */
  left: var(--spacing-md);
}
:where(.ds) .card__header {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
  padding-left: 112px;
  min-height: 62px;
}
:where(.ds) .card__name {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  font-size: var(--type-display-h6);
  font-weight: var(--font-weight-heavy);
  line-height: var(--line-height-tight);
}
:where(.ds) .card__name .icon {
  width: 20px;
  height: 20px;
}
:where(.ds) .card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-xs) var(--spacing-sm);
  color: var(--content-tertiary);
  font-size: var(--type-label-sm);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
}
:where(.ds) .card__location {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-xs);
  color: var(--content-secondary);
  font-size: var(--type-body-sm);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-text);
}
:where(.ds) .card__location .icon {
  width: 16px;
  height: 16px;
}
:where(.ds) .card__divider {
  width: 1px;
  height: 12px;
  background-color: var(--border-tertiary);
}
:where(.ds) .card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-sm);
}

@media (max-width: 767px) {
  :where(.ds) .card__header {
    padding-left: 0;
    padding-top: 52px; /* below the overflowing avatar */
  }
}

/* ---- Hero ----
   <section class="hero" data-theme="dark"> + <img|video> with object-fit: cover, gradient scrim,
   content aligned to the bottom on the grid. Video: autoplay muted loop playsinline + poster. */
:where(.ds) .hero {
  position: relative;
  display: flex;
  min-height: 640px;
  overflow: hidden;
  background-color: var(--background-primary);
}
:where(.ds) .hero--video {
  min-height: 900px;
}
:where(.ds) .hero__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

:where(.ds) .hero__scrim {
  position: relative;
  display: flex;
  flex: 1;
  align-items: flex-end;
  justify-content: center;
  padding-inline: var(--grid-margin);
  background: linear-gradient(to bottom, transparent 47.42%, var(--black-alpha-50));
}
:where(.ds) .hero--video .hero__scrim {
  background: none;
}

:where(.ds) .hero__container {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--spacing-lg);
  max-width: var(--container-max-width);
  padding-block: var(--spacing-section);
  color: var(--content-primary);
}

:where(.ds) .hero__headline {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  width: 100%;
}
:where(.ds) .hero__title {
  flex: 1;
  min-width: 0;
  color: var(--content-primary);
  font-size: var(--type-display-h1);
  font-weight: var(--font-weight-heavy);
  line-height: var(--line-height-tight);
  text-shadow: var(--shadow-text);
}
:where(.ds) .hero__credit {
  padding-bottom: 18px;
  color: var(--content-primary);
  font-size: var(--type-label-sm);
  font-weight: var(--font-weight-semibold);
  line-height: var(--line-height-tight);
  white-space: nowrap;
}
:where(.ds) .hero__description {
  max-width: 100%;
  color: var(--content-primary);
  font-size: var(--type-body-md);
  line-height: var(--line-height-text);
  text-shadow: var(--shadow-text);
}

@media (max-width: 767px) {
  :where(.ds) .hero {
    min-height: 480px;
  }
  :where(.ds) .hero--video {
    min-height: 560px;
  }
  :where(.ds) .hero__headline {
    flex-direction: column;
    align-items: flex-start;
  }
  :where(.ds) .hero__credit {
    padding-bottom: 0;
  }
}

/* ---- CTA Banner ----
   <section class="cta-banner" data-theme="dark">: full-width banner, background/tertiary background,
   Display H2 title, Body LG content/secondary description (6 columns), Accent button (LG).
   96 px at the top and bottom (spacing/section), 24 px between elements. */
:where(.ds) .cta-banner {
  padding-block: var(--spacing-section);
  background-color: var(--background-tertiary);
  color: var(--content-primary);
}
:where(.ds) .cta-banner__container {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--spacing-lg);
}
:where(.ds) .cta-banner__description {
  max-width: 708px; /* grid/span-6 */
  color: var(--content-secondary);
}

/* ---- Project Editor ----
   Project block of the public profile form. States: empty ("New post"), menu open,
   image, video. Built with Field, Textarea, Image Field, Tag Field, Icon Button and Menu. */
:where(.ds) .project-editor {
  position: relative;
  width: 100%;
  max-width: 994px;
  border: 1px solid var(--border-secondary);
  border-radius: var(--radius-lg);
  background-color: var(--background-primary);
}

:where(.ds) .project-editor--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 112px;
  padding: var(--spacing-lg);
  transition: background-color var(--duration-fast) var(--ease-standard);
}
:where(.ds) .project-editor--empty:hover {
  background-color: var(--background-primary-hover);
}
:where(.ds) .project-editor__new {
  z-index: 2;
}

:where(.ds) .project-editor__content {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
  padding: var(--spacing-lg);
}

:where(.ds) .project-editor__header {
  display: flex;
  align-items: flex-end;
  gap: var(--spacing-md);
}
:where(.ds) .project-editor__fields {
  display: flex;
  flex: 1;
  gap: var(--spacing-md);
  min-width: 0;
}
:where(.ds) .project-editor__fields > .field {
  flex: 1;
  min-width: 0;
}

:where(.ds) .project-editor__media {
  display: flex;
  gap: var(--spacing-lg);
}
:where(.ds) .project-editor__media .image-field {
  width: 200px;
  height: 200px;
  flex-shrink: 0;
  margin-top: 8px;
}
:where(.ds) .project-editor__media .field--textarea {
  flex: 1;
  min-width: 0;
}
:where(.ds) .project-editor__media .field--textarea .field__control {
  min-height: 0;
  height: 200px;
}

:where(.ds) .project-editor .dropdown > .menu {
  min-width: 301px;
}

@media (max-width: 767px) {
  :where(.ds) .project-editor__fields,
  :where(.ds) .project-editor__media {
    flex-direction: column;
  }
  :where(.ds) .project-editor__media .image-field {
    width: 100%;
  }
}

/* ---- Contact ----
   200 px Secondary button that opens a Menu of external links (forum, Instagram, Discord),
   or "Edit profile" for the profile owner. */
:where(.ds) .contact {
  position: relative;
  display: inline-flex;
  width: 200px;
}
:where(.ds) .contact .button {
  width: 100%;
}
:where(.ds) .contact .button[aria-expanded="true"] {
  background-color: var(--background-primary-hover);
}
:where(.ds) .contact > .menu {
  position: absolute;
  top: calc(100% + var(--spacing-xs));
  left: 0;
  z-index: 20;
  width: 301px;
}

/* ---- Mesh Selection (Video Mapping illustration) ----
   Fills its container; the SVG is redrawn by public/ds/js/components/mesh-selection.js.
   Stretchable lines, fixed-size handles (smaller on mobile).
   Colors: --mesh-accent (frame, points, handles) · --mesh-line (mesh). */
:where(.ds) .mesh-selection {
  --mesh-accent: var(--border-accent);
  --mesh-line: rgb(255 255 255 / 0.8);
  --mesh-knob-icon: var(--grey-1000);
  --mesh-handle-scale: 1;
  position: relative;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
:where(.ds) .mesh-selection__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  overflow: visible; /* handles and corners overflow the frame */
}
:where(.ds) .mesh-selection__lattice {
  fill: none;
  stroke: var(--mesh-line);
  stroke-width: 1.5;
  stroke-linejoin: round;
}
:where(.ds) .mesh-selection__frame {
  fill: none;
  stroke: var(--mesh-accent);
  stroke-width: 1;
}
:where(.ds) .mesh-selection__point {
  fill: none;
  stroke: var(--mesh-accent);
  stroke-width: 1.25;
}
:where(.ds) .mesh-selection__knob circle {
  fill: var(--mesh-accent);
}
:where(.ds) .mesh-selection__knob-icon {
  fill: var(--mesh-knob-icon);
}
/* On a light background (like the Figma preview) */
:where(.ds) .mesh-selection--light {
  --mesh-line: rgb(0 0 0 / 0.45);
}
@media (max-width: 767px) {
  :where(.ds) .mesh-selection { --mesh-handle-scale: 0.75; }
}

/* ---- Section Heading ----
   Figma "Section Heading": optional overline, Display H2 title, Body LG description
   (content/secondary, 6 columns), optional action on the right.
   Not a class in the export (each home section had its own); factored out here.
   Partial: views/partials/ds/section-heading.handlebars */
:where(.ds) .section-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--spacing-md);
}
:where(.ds) .section-heading__text {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--spacing-md);
  min-width: 0;
}
:where(.ds) .section-heading__overline {
  color: var(--content-quaternary);
}
:where(.ds) .section-heading__title-group {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
}
:where(.ds) .section-heading__description {
  color: var(--content-secondary);
}
:where(.ds) .section-heading__action {
  flex-shrink: 0;
}

@media (max-width: 1023px) {
  :where(.ds) .section-heading {
    flex-direction: column;
    gap: var(--spacing-lg);
  }
}
:where(.ds) .section-heading--inline {
  flex-direction: row;
  align-items: flex-end;
}
@media (max-width: 767px) {
  :where(.ds) .section-heading--inline {
    flex-direction: column;
    align-items: flex-start;
  }
}


/* ---- Section (Figma: Content > Section) ----
   96 px above and below, 48 px between the heading and the content.
   Background: primary by default, --secondary / --tertiary.
   --split: 2 equal columns, stacked under 768 px. */
:where(.ds) .section {
  padding: var(--spacing-section) var(--grid-margin);
  background-color: var(--background-primary);
  color: var(--content-primary);
}
:where(.ds) .section--secondary { background-color: var(--background-secondary); }
:where(.ds) .section--tertiary { background-color: var(--background-tertiary); }
:where(.ds) .section__container {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2xl);
  max-width: var(--container-max-width);
  margin-inline: auto;
}
:where(.ds) .section__content {
  min-width: 0;
}
:where(.ds) .section--split .section__container {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center;
}
:where(.ds) .section__column {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
  min-width: 0;
}
:where(.ds) .section__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-md);
}
@media (max-width: 767px) {
  :where(.ds) .section--split .section__container {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---- Image Viewer (Figma: Content > Image Viewer) ----
   <dialog class="image-viewer" data-theme="dark">, opened by image-viewer.js: the image on the left,
   the info panel (360 px) on the right, below the image under 768 px.
   Relative to the screen: image at most 80% of its height, image + panel at most 75% of its width
   (the image keeps at least 480 px of width when the screen allows it).
   image-viewer.js sets --iv-w / --iv-h to the real ratio of the image. */
:where(.ds) .image-viewer {
  max-width: none;
  max-height: none;
  margin: auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--content-primary);
}
:where(.ds) .image-viewer::backdrop {
  background-color: var(--background-scrim-dark-strong);
}
:where(.ds) .image-viewer__box {
  --iv-w: 936;
  --iv-h: 600;
  --iv-panel: 360px;
  /* Image width: 75% of the screen minus the panel, but at least 480 px when the screen allows it
     (otherwise portrait images get very small on tablets) */
  --iv-image-h: min(
    80svh,
    calc(min(max(75vw - var(--iv-panel), 480px), 100vw - 2 * var(--grid-margin) - var(--iv-panel)) * var(--iv-h) / var(--iv-w))
  );
  display: flex;
  width: max-content;
  max-height: calc(100svh - 2 * var(--grid-margin));
  overflow-y: auto; /* last resort on very short screens */
  border: 1px solid var(--border-quaternary);
  background-color: var(--background-secondary);
  color: var(--content-primary);
}
/* Full image on its ratio; if the panel is taller, bands above and below rather than a scrollbar */
:where(.ds) .image-viewer__image {
  display: block;
  flex-shrink: 0;
  width: calc(var(--iv-image-h) * var(--iv-w) / var(--iv-h));
  min-height: var(--iv-image-h);
  object-fit: contain;
}
:where(.ds) .image-viewer__info {
  display: flex;
  flex: 0 0 var(--iv-panel);
  flex-direction: column;
  justify-content: space-between;
  gap: var(--spacing-lg);
  width: var(--iv-panel);
  padding: var(--spacing-xl);
}
:where(.ds) .image-viewer__details {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
}
:where(.ds) .image-viewer__title-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}
:where(.ds) .image-viewer__title {
  flex: 1;
  min-width: 0;
}
:where(.ds) .image-viewer__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-sm);
  color: var(--content-secondary);
}
:where(.ds) .image-viewer__description {
  color: var(--content-tertiary);
}
:where(.ds) .image-viewer__nav {
  display: flex;
  justify-content: flex-end;
  gap: var(--spacing-sm);
}
@media (max-width: 767px) {
  :where(.ds) .image-viewer__box {
    flex-direction: column;
    width: calc(100vw - 2 * var(--grid-margin));
  }
  /* At most 60% of the screen height (portrait images), centered with bands on the sides,
     so the title stays visible without scrolling */
  :where(.ds) .image-viewer__image {
    width: 100%;
    min-height: 0;
    max-height: 60svh;
    aspect-ratio: var(--iv-w) / var(--iv-h);
  }
  :where(.ds) .image-viewer__info {
    flex-basis: auto;
    width: auto;
    padding: var(--spacing-lg);
  }
}

/* ---- Dialog (Figma: Home > Get Demo Popup, 11167:5392) ----
   <dialog class="dialog">, 640 px box on a strong scrim.
   Footer: Cancel, then the main button takes the remaining width.
   Partial: views/partials/ds/demo-dialog.handlebars */
:where(.ds) .dialog {
  width: min(640px, 100vw - 2 * var(--grid-margin));
  max-width: none;
  max-height: calc(100svh - 2 * var(--grid-margin));
  margin: auto;
  padding: var(--spacing-2xl);
  overflow-y: auto;
  border: 1px solid var(--border-quaternary);
  border-radius: var(--radius-lg);
  background-color: var(--background-primary);
  color: var(--content-primary);
  box-shadow: 0 16px 48px var(--shadow-strong);
}
:where(.ds) .dialog::backdrop {
  background-color: var(--background-scrim-strong);
}
:where(.ds) .dialog__body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}
:where(.ds) .dialog__header {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
}
:where(.ds) .dialog__description {
  color: var(--content-secondary);
}
:where(.ds) .dialog__form {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}
/* Not in the export: platform choice and error messages */
:where(.ds) .dialog__platform {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-sm) var(--spacing-md);
}
:where(.ds) .dialog__error {
  color: var(--content-error);
}
:where(.ds) .dialog__footer {
  display: flex;
  align-items: center;
  gap: var(--spacing-lg);
  margin-top: var(--spacing-md); /* 32 px from the form, with the gap of .dialog__body */
}
:where(.ds) .dialog__footer > :last-child {
  flex: 1;
}
@media (max-width: 767px) {
  :where(.ds) .dialog {
    padding: var(--spacing-lg);
  }
  :where(.ds) .dialog__footer {
    flex-direction: column-reverse;
    align-items: stretch;
    gap: var(--spacing-md);
  }
  :where(.ds) .dialog__footer > :last-child {
    flex: none;
  }
}
