:root {
  --black: #000;
  --white: #fff;
  --font-serif: "Times New Roman", Times, serif;
  --font-sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --text-size: 12pt;
  --line-height: 1.2;
  --letter-spacing: 0.07em; /* tracking +20 in design software (1/1000 em) */
  --text-size-label: 10pt; /* temporary placeholder labels */
  /* Small type: footer and text pages (currently the same as the standard). */
  --text-size-small: 12pt;
  --line-height-small: 1.2;
  --letter-spacing-small: 0.04em; /* tracking +20 */
  --gutter: clamp(1rem, 1.6vw, 1.75rem);
  --columns: 3;
  /* The grid keeps this width on wide screens; only the side margins change.
     Below 1060px wide (the grid plus small margins) it becomes 2 columns. */
  --grid-width: 980px;
  --grid-gap: 3rem; /* between grid rows (columns: double on desktop) */
  --page-padding: calc((100% - var(--grid-width)) / 2); /* side margins of the grid and footer */
  --logo-height: calc(var(--text-size) * 1.2);
  --header-padding: calc(var(--gutter) * 1.5); /* above and below the logo */
  --header-height: calc(var(--logo-height) + var(--header-padding));
  /* Visible space above the header text (top of the screen to the top of the
     capitals), and the side padding of the header, bag and lightbox rows,
     which matches it (on phones it's one gutter instead, like the grid). */
  --header-top: calc(var(--header-height) / 2 - 0.5cap);
  --header-side: var(--header-top);
  --popup-bg: var(--white); /* shared by all popups (cart, …) */
  --placeholder-bg: #e6e6e6; /* grey rectangles standing in for images */
  --image-ratio: 7 / 10; /* general image proportion (portrait), width / height */
  --space-xs: 0.25em;
  --space-s: 0.5em;
  --space-m: 1em;
  --space-l: 2em;
  --line: 0.07em; /* underlines and dividers share this thickness */
  /* Sliding motion (bag), close to the browser's smooth scroll used by the carousels. */
  --slide-duration: 0.5s;
  --slide-easing: ease-in-out;
}

/* No overscroll bounce anywhere: the page, the carousels and the bag stop
   at their edges (and don't pass the scroll on, e.g. to the browser's
   swipe-back gesture). */
html,
body,
.carousel-track,
.popup {
  overscroll-behavior: none;
}

/* No page scrolling behind an open modal (the cart). */
html:has(dialog[open]:modal) {
  overflow: hidden;
}

body {
  background: var(--white);
  color: var(--black);
  font-family: var(--font-serif);
  font-size: var(--text-size);
  line-height: var(--line-height);
  letter-spacing: var(--letter-spacing);
  padding-top: var(--header-height) !important; /* overrides the reset's padding: 0 !important */
}

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

button {
  all: unset;
  cursor: pointer;
}

a:hover,
button:hover {
  text-decoration: underline;
  text-decoration-thickness: var(--line);
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* The page content fills at least the screen below the header, so on short
   pages the footer starts right below the fold instead of mid-screen. */
main {
  min-height: calc(100svh - var(--header-height));
}

/* The hidden attribute always hides, even on elements given a display value. */
[hidden] {
  display: none !important;
}

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

/* Header */

/* Fixed, not sticky: the reset gives body height: 100%, which would end
   a sticky header's run after one screen of scrolling. */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: var(--header-height);
  padding: 0 var(--header-side); /* same as the visible space above the nav text */
  background: var(--white);
}

.site-nav {
  display: flex;
  gap: 1.25em;
}

.site-nav--right {
  justify-content: flex-end;
}

.logo img {
  display: block;
  height: var(--logo-height);
  width: auto;
}

/* Grid: at most 3 columns, inside wide side margins (--page-padding).
   Columns are two gaps apart on desktop, one on phones. */

.grid {
  --caption-gap: 0.6em;

  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  grid-auto-flow: row dense;
  gap: var(--grid-gap) calc(var(--grid-gap) * 2);
  padding: 0 var(--page-padding) var(--grid-gap);
}

/* Lightboxes (and the video) from Sanity: the full width of the columns.
   Their height follows the image's proportions (--ratio = width / height,
   set on the item), at most --image-ratio tall (7:10, portrait). */
.look {
  grid-column: 1 / -1;
}

.look .image {
  aspect-ratio: max(var(--ratio, var(--image-ratio)), var(--image-ratio));
}

/* Full-width video: edge to edge across the screen, out of the grid's side
   margins, in the video's own shape but never taller than the screen under
   the header (cropped then). Clicking it plays/pauses (video.js). */
.look--video-full {
  margin-inline: calc(50% - 50vw);
}

.look--video-full figure {
  position: relative;
}

.look--video-full .image {
  aspect-ratio: var(--ratio);
  max-height: calc(100svh - var(--header-height)*2);
  cursor: pointer;
}

/* Buttons over the video, in one row in the bottom-left corner (Pause/Play,
   Unmute/Mute, Full screen), as far in from the edges as the header's text,
   inverted to read on any frame. */
.look--video-full .video-controls {
  position: absolute;
  left: var(--header-side);
  bottom: var(--header-top);
  margin: 0;
  color: var(--white);
  mix-blend-mode: difference;
  text-box: trim-both cap alphabetic;
}

/* With a mouse, the buttons show while the pointer is on the video (or a
   button has keyboard focus: :focus-visible, which a click doesn't set, so
   they still hide after clicking one); on touch screens they stay visible,
   like the carousel arrows. */
@media (hover: hover) and (pointer: fine) {
  .look--video-full .video-controls {
    opacity: 0;
  }

  .look--video-full figure:hover .video-controls,
  .look--video-full .video-controls:has(:focus-visible) {
    opacity: 1;
  }
}

/* Full screen (the whole block, so the buttons stay): the video shown whole
   on black, the buttons in the same places. */
.look--video-full figure:fullscreen {
  background: var(--black);
}

/* Pinned to the screen's edges (sized from the width alone, a 4:3 film on a
   wide screen would be taller than the screen and get cropped). */
.look--video-full figure:fullscreen .image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-height: none;
  aspect-ratio: auto;
  object-fit: contain;
}

/* Homepage images (one image post, each image on its own): two columns, one
   gap apart, so 4 and 6 images fill their rows. */
.grid--images {
  --columns: 2;
  column-gap: var(--grid-gap);
}

/* Homepage text block: centred title, the text pages' column. */
.home-text {
  padding: var(--grid-gap) var(--gutter) calc(var(--grid-gap) * 2);
}

/* Lookbook: every image in its own cell, no captions. */
.lookbook-item figure {
  cursor: pointer;
}

/* Temporary labels on the placeholders, to tell the items apart. */
.label {
  color: var(--black);
  font: normal var(--text-size-label) / 1 var(--font-sans);
}

.image {
  display: block;
  width: 100%;
  height: auto; /* the <img> height attribute must not override the ratio */
  aspect-ratio: var(--image-ratio);
  object-fit: cover;
}

/* No alt text flashing up while an image loads (screen readers still read it). */
img.image,
img.lightbox-image {
  color: transparent;
}

/* After .image, so the grid display (centring the label) wins over display: block. */
.placeholder {
  display: grid;
  place-items: center;
  background: var(--placeholder-bg);
}

/* Carousel: a horizontal strip of images, one visible at a time. It swipes on
   touch screens (scroll snap); the arrows sit a gutter in from the image edges. */
.carousel {
  position: relative;
}

.carousel-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

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

.carousel-track > * {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

.carousel-button {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  font-family: var(--font-serif);
  font-size: 10pt;
  /* White, inverted against the image: readable on light and dark photos. */
  color: var(--white);
  mix-blend-mode: difference;
}

.carousel-prev {
  left: var(--gutter);
}

.carousel-next {
  right: var(--gutter);
}

/* Lightboxes and the video open full screen, from the image or the title. */
.look .carousel-track,
.look .look-title {
  cursor: pointer;
}

/* With a mouse, arrows appear on hover; on touch screens (no fine pointer,
   including touch laptops' and tablets' hover emulation) they stay visible. */
@media (hover: hover) and (pointer: fine) {
  .carousel-button {
    opacity: 0;
  }

  .carousel:hover .carousel-button,
  .carousel-button:focus-visible {
    opacity: 1;
  }
}

/* Product cards (shop, homepage, recommendations): text centred. */
.product article {
  text-align: center;
}

/* Always one line, so every caption has the same height and the
   Sanity images (whose heights assume that) stay aligned. A Sanity image's
   title sits in the caption space under it, like a product name. */
.product-title,
.look-title,
.video-controls {
  margin-top: var(--caption-gap);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Sanity carousel titles centred, like the product info. */
.look-title {
  text-align: center;
}

/* Video buttons in a row, where the title would be. */
.video-controls {
  display: flex;
  justify-content: center;
  gap: var(--space-m);
}

.lightbox-controls {
  white-space: nowrap;
}

/* Sizes under the price; sold-out ones struck through. With a mouse they
   appear on hover (their line is always reserved, so nothing moves);
   on touch screens they're always shown. */
.product-sizes {
  white-space: nowrap;
  word-spacing: 0.3em;
}

.product-sizes s {
  text-decoration-thickness: var(--line);
}

@media (hover: hover) {
  .product-sizes {
    visibility: hidden;
  }

  .product:hover .product-sizes,
  .product:focus-within .product-sizes {
    visibility: visible;
  }
}

/* Product page */

/* Standalone product page (no header, footer or extras): the image carousel
   centred, the info centred below it, together always fitting the screen.
   The image takes the height the info leaves (--form-height, measured by
   product.js); Close sits top right, where the bag's Close is. */
body:has(.product-page) {
  padding-top: 0 !important; /* no site header on this page */
}

body:has(.product-page) main {
  min-height: 0;
}

.product-page {
  --margin: var(--gutter); /* above the image and below the info */
  --info-gap: var(--gutter); /* between the image and the product name */
  --image-height: calc(100svh - var(--margin) * 2 - var(--info-gap) - var(--form-height, 6rem));

  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--info-gap);
  padding: var(--margin) var(--gutter);
  text-align: center;
}

.product-images {
  width: min(var(--image-height) * var(--image-ratio), 100%);
  height: var(--image-height);
}

.product-images .carousel-track,
.product-images .image {
  height: 100%;
}

.product-images .image {
  aspect-ratio: auto;
}

.product-close {
  position: fixed;
  top: var(--header-top);
  right: var(--header-side);
  z-index: 1;
  text-box: trim-both cap alphabetic;
}

.product-info {
  width: min(calc(28rem * 2 / 3), 100%);
}

/* Name above price, both centred. */
.product-form .price {
  display: block;
}

.product-form .price data {
  display: block;
}

/* Options centred as one line each ("Colour: ■ Black ■ Ox"): the fieldset is
   a flex row, so its floated legend sits inline with the choices. */
.product-form .options {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.product-form .options legend,
.product-form .options label {
  margin: 0 0.15em;
}

/* Add to bag (underlined text, no box), and after adding, "Go to bag" on
   the same line. */
.product-form .add-to-cart,
.product-form .go-to-bag {
  text-decoration: underline;
  text-decoration-thickness: var(--line);
}

.product-form .go-to-bag {
  margin-left: var(--space-m);
}

/* Options read as plain text on one line, "Size: S M L XL", wrapping when
   needed; the chosen one is underlined. Floating the legend lets it sit
   inline with the choices. */
.options legend {
  float: left;
  padding: 0;
  margin-right: 0.3em;
}

.options legend::after {
  content: ":";
}

.options label {
  cursor: pointer;
  margin-right: 0.3em;
}

.options input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.options label:hover,
.options label:has(:checked) {
  text-decoration: underline;
  text-decoration-thickness: var(--line);
}

/* Small colour square before each colour name; its colour comes from --swatch. */
.swatch {
  display: inline-block;
  width: 0.7em;
  height: 0.7em;
  margin-right: 0.3em;
  background: var(--swatch);
}

/* Sold out / unavailable values are struck through and can't be picked. */
.options label:has(:disabled) {
  cursor: default;
  text-decoration: line-through;
  text-decoration-thickness: var(--line);
}

.options label:has(:focus-visible) {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* Footer */

.site-footer,
.text-page {
  font-size: var(--text-size-small);
  line-height: var(--line-height-small);
  letter-spacing: var(--letter-spacing-small);
}

/* Footer: loose and horizontal, inside the same side margins as the grid.
   Links centred in one row, two gutters apart (wrapping on narrow screens);
   studio details below. */
.site-footer {
  display: grid;
  gap: calc(var(--gutter) * 2);
  padding: calc(var(--gutter) * 4) var(--page-padding) calc(var(--gutter) * 2);
}

.footer-links ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-m) calc(var(--gutter) * 2);
}

.site-footer a {
  cursor: pointer;
}

/* Footer lines (email, copyright, …), one above the other, centred. */
.site-footer address {
  font-style: normal;
  text-align: center;
}

/* Text pages (about, terms, …): one centred column of text. */
.text-page {
  padding: var(--gutter) var(--gutter) calc(var(--gutter) * 4);
}

.text-page-body {
  max-width: 32em;
  margin: 0 auto;
}

.text-page-body h1,
.text-page-body h2 {
  text-align: center;
}

/* Sections (e.g. each policy on the policies page). */
.text-page-body section > * + * {
  margin-top: 1lh;
}

.text-page-body section + section {
  margin-top: 3lh;
}

.text-page-body > * + * {
  margin-top: 1lh;
}

/* Popups */

.popup {
  border: 0;
  background: var(--popup-bg);
  color: inherit;
}

.popup::backdrop {
  background: rgb(255 255 255 / 0.6);
}

/* Same height as the site header; stays on top while the content scrolls under it. */
.popup-header {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  flex: none;
  justify-content: space-between;
  align-items: center;
  height: var(--header-height);
  background: var(--popup-bg);
}

/* Cart: modal panel on the right, full height. */
.cart {
  margin: 0 0 0 auto;
  width: min(450px, 100%); /* about 30% of a MacBook screen; full width on phones */
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  padding: 0 var(--header-side); /* same as the header: "Close" sits where "Bag" is */
  overflow-y: auto;
}

/* Slides in from the right and back out on close, while the overlay fades.
   display/overlay transition too, so the panel stays visible while sliding out. */
.cart,
.cart::backdrop {
  transition:
    translate var(--slide-duration) var(--slide-easing),
    opacity var(--slide-duration) var(--slide-easing),
    display var(--slide-duration) allow-discrete,
    overlay var(--slide-duration) allow-discrete;
}

.cart {
  translate: 100% 0;
}

.cart[open] {
  translate: 0 0;
}

.cart::backdrop {
  opacity: 0;
}

.cart[open]::backdrop {
  opacity: 1;
}

/* Closing: index.js slides the panel out first, then closes the dialog. */
.cart[open].is-closing {
  translate: 100% 0;
}

.cart[open].is-closing::backdrop {
  opacity: 0;
}

@starting-style {
  .cart[open] {
    translate: 100% 0;
  }

  .cart[open]::backdrop {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cart,
  .cart::backdrop {
    transition: none;
  }
}

/* Phone menu: a fully white screen sliding in from the left, the bag's slide
   mirrored (closing: index.js, like the bag). Close sits top right. */
.menu {
  margin: 0;
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  padding: 0 var(--header-side);
  background: var(--white);
  transition:
    translate var(--slide-duration) var(--slide-easing),
    display var(--slide-duration) allow-discrete,
    overlay var(--slide-duration) allow-discrete;
  translate: -100% 0;
}

.menu::backdrop {
  background: none;
}

.menu .popup-header {
  justify-content: flex-end; /* Close on the right */
  background: var(--white);
}

.menu[open] {
  display: flex;
  flex-direction: column;
  translate: 0 0;
}

.menu[open].is-closing {
  translate: -100% 0;
}

@starting-style {
  .menu[open] {
    translate: -100% 0;
  }
}

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

/* Shop and Lookbook, one under the other, in the middle of the screen. */
.menu-nav {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding-bottom: var(--header-height); /* centred on the screen, not under the header row */
}

.menu-open {
  display: none;
}

/* Only when open, so the closed <dialog> keeps display: none. */
.cart[open] {
  display: flex;
  flex-direction: column;
}

/* Space under the last product, so it never sits right on the subtotal line. */
.cart-lines {
  flex: 1;
  padding-bottom: var(--space-l);
}

/* Stays at the bottom of the panel while the products scroll behind it. */
.cart-summary {
  position: sticky;
  bottom: 0;
  padding-bottom: var(--header-side);
  background: var(--popup-bg);
}

.cart-subtotal {
  padding: var(--space-s) 0;
  border-block: var(--line) solid currentColor;
}

.cart-subtotal + p {
  padding-top: var(--space-s);
}

.cart-line {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: var(--header-side); /* same as the panel's side padding */
  align-items: start;
}

.cart-line + .cart-line {
  margin-top: var(--space-l);
}

.cart-line dt,
.cart-line dd {
  display: inline;
}

.cart-line dt::after {
  content: ": ";
}

/* Label or name on the left, amount on the right. */
.price {
  display: flex;
  justify-content: space-between;
}

.cart-quantity {
  display: flex;
  gap: 0.75em;
}

.cart-remove {
  margin-left: var(--space-m);
}

.button {
  display: block;
  margin-top: var(--space-s);
  padding-block: var(--space-s);
  text-align: center;
  text-decoration: underline;
  text-decoration-thickness: var(--line);
}

/* Announcement popup: black card in the middle of the screen. An optional
   background image from Sanity fills it, under the text and Close. */
.announcement {
  margin: auto; /* the reset's margin: 0 would undo the dialog's centring */
  width: min(300px, 100% - var(--gutter) * 2);
  height: 400px;
  max-height: calc(100% - var(--gutter) * 2);
  padding: var(--gutter);
  overflow: hidden;
  background: var(--black);
  color: var(--white);
}

.announcement:focus {
  outline: none; /* focused on open (autofocus) so Esc works; no ring needed */
}

.announcement p {
  position: relative; /* above the image */
  padding-right: 2em; /* keeps the text clear of the × */
}

.announcement-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.announcement-close {
  position: absolute;
  z-index: 1; /* above the image */
  top: var(--gutter);
  right: var(--gutter);
}

/* Lightbox: full screen. Close top right; under the image one row with the
   arrows at the edges and the title and counter (two lines) centred between
   them. Phones the same, with the image at the top (see the end). */
.lightbox {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  padding: 0;
  border: 0;
  background: var(--popup-bg);
  color: inherit;
}

.lightbox:focus {
  outline: none; /* focused on open (autofocus) so Esc works; no ring needed */
}

.lightbox-header {
  position: absolute;
  inset: 0 0 auto;
  z-index: 1;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  height: var(--header-height);
  padding: 0 var(--header-side); /* Close where the header's Bag is */
}

/* The video: the whole screen, shown whole (not cropped). Title (top left)
   and Close stay in place on top of it, inverted so they read on any frame. */
.lightbox--video .lightbox-carousel .carousel-track {
  inset: 0;
  width: 100%;
  height: 100%;
}

.lightbox--video .lightbox-carousel .carousel-track > * {
  padding-inline: 0;
}

.lightbox--video .lightbox-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.lightbox--video .lightbox-header,
.lightbox--video .lightbox-caption,
.lightbox--video .lightbox-controls {
  color: var(--white);
  mix-blend-mode: difference;
}

.lightbox--video .lightbox-caption {
  inset: var(--header-top) auto auto var(--header-side);
  text-align: left;
}

/* Video buttons: bottom centre, in the middle of the margin under the video. */
.lightbox-controls {
  --margin: calc(var(--header-height) / 2 - 0.5cap);

  position: absolute;
  left: 50%;
  bottom: calc(var(--margin) / 2);
  translate: -50% 50%;
}

/* Title and counter (X/Y): two centred lines under the image, between the
   arrows; a title too long for its line ends in "…". */
.lightbox-caption {
  position: absolute;
  inset: auto var(--caption-side) var(--header-top);
  text-align: center;
}

.lightbox-caption > * {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Header rows (site header, bag, lightbox): text trimmed to its capitals, so
   it centres exactly in the row and the space above the capitals equals
   --header-side. */
.site-nav > *,
.popup-header > *,
.lightbox-header > * {
  text-box: trim-both cap alphabetic;
}

/* The images swipe inside one area, each shown whole in its own shape, as
   large as fits, centred (so images of different shapes never get cropped).
   The area's top lines up with the top of Close's capitals; under it, the
   row (title and counter) with the same space above and below it. The
   carousel itself isn't positioned, so the track and arrows are placed
   against the screen. */
.lightbox {
  --top: calc(var(--header-height) / 2 - 0.5cap);
  --bottom: calc(var(--header-top) * 2 + 2lh);
  --side: var(--header-side);
  --caption-side: calc(var(--side) + 3em); /* room for the arrows */
}

.lightbox-carousel {
  position: static;
}

/* The track spans the full screen width, so images slide in and out at the
   screen edges; each image keeps the side room inside its own slide. */
.lightbox-carousel .carousel-track {
  position: absolute;
  inset: var(--top) 0 var(--bottom);
}

.lightbox-carousel .carousel-track > * {
  box-sizing: border-box;
  padding-inline: var(--side);
}

/* Each image is centred in its slide, exactly the size of the picture, so
   a click beside it lands on the slide (and closes the lightbox). */
.lightbox-slide {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.lightbox-image:not(.placeholder) {
  display: block; /* placeholders keep their grid, which centres the label */
}

.lightbox-image {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  /* The small image, shown until the large one loads (lightbox.js). */
  background: center / cover no-repeat;
}

.lightbox-image.placeholder {
  width: 100%;
  height: 100%;
}

/* Arrows at the screen edges, on the title's line. */
.lightbox .carousel-button {
  top: auto;
  bottom: calc(var(--header-top) + 1lh);
  translate: none;
  font: inherit;
  opacity: 1; /* always visible here, not only on hover */
  color: inherit; /* on the white background, not over the image */
  mix-blend-mode: normal;
}

.lightbox .carousel-prev {
  left: var(--side);
}

.lightbox .carousel-next {
  right: var(--side);
}

/* Close sign for the popup: a large, light ×. */
.close-x {
  font-size: 2em;
  font-weight: normal;
  line-height: 0.6;
}

.close-x:hover {
  text-decoration: none;
  opacity: 0.6;
}

/* Responsive */

/* Narrow windows and phones: 2 columns with gutter-wide margins, the header
   aligned to them. */
@media (max-width: 1060px) {
  :root {
    --columns: 2;
    --page-padding: var(--gutter);
    --grid-gap: clamp(1rem, 3.5vw, 3rem);
    --header-side: var(--gutter); /* same side margin as the grid */
  }

  .grid {
    column-gap: var(--grid-gap);
  }
}

@media (max-width: 700px) {
  /* Header stays one row; tighter nav spacing so it fits beside the logo. */
  .site-nav {
    gap: 0.75em;
  }

  /* The nav links move into the menu; Menu takes their place. */
  .site-nav--left a {
    display: none;
  }

  .menu-open {
    display: inline;
  }

  /* Lightbox: the image area at the top, under Close, as tall as a 2:3
     portrait at the full width (or what fits); the row right under it. */
  .lightbox {
    --top: var(--header-height);
    --side: var(--gutter);
    --area-height: min(100svh - var(--top) - var(--header-top) * 3 - 2lh, (100vw - var(--gutter) * 2) * 3 / 2);
    --row: calc(var(--top) + var(--area-height) + var(--header-top));
  }

  .lightbox-carousel .carousel-track {
    bottom: auto;
    height: var(--area-height);
  }

  /* Shorter images sit at the top of the area; the row stays in place. */
  .lightbox-slide {
    align-items: flex-start;
  }

  .lightbox .carousel-button,
  .lightbox:not(.lightbox--video) .lightbox-caption {
    top: var(--row);
    bottom: auto;
  }

  /* Video buttons: as far from the bottom as Close is from the top
     (measured to the capitals, so the text is trimmed to them). */
  .lightbox-controls {
    bottom: var(--header-top);
    translate: -50% 0;
    text-box: trim-both cap alphabetic;
  }

  .cart-line {
    grid-template-columns: 3.5rem 1fr;
  }
}
