/* ==========================================================================
   The front page.

   Appended to analogue.css at build time rather than pasted into it, so the
   original stylesheet stays the file it was tested as. Three things only: the
   hero slideshow, the full-width editorial band, and the house list.
   ========================================================================== */

/* ---- Hero slideshow -----------------------------------------------------
   Full bleed, tall enough to hold the frame but never taller than the screen.
   Slides are stacked and crossfaded; the first carries no lazy attribute so
   it is the one image the browser fetches immediately.
   -------------------------------------------------------------------------- */
.hero-slides {
  position: relative;
  width: 100%;
  height: min(82svh, 760px);
  overflow: hidden;
  background: var(--wash);
}

.hero-slides__track { position: absolute; inset: 0; }

.hero-slides__slide {
  position: absolute; inset: 0; margin: 0;
  opacity: 0; transition: opacity 1.1s var(--ease);
}
.hero-slides__slide.is-on { opacity: 1; }
.hero-slides__slide img { width: 100%; height: 100%; object-fit: cover; display: block; }

.hero-slides__dots {
  position: absolute; left: 0; right: 0; bottom: 20px;
  display: flex; justify-content: center; gap: 10px; z-index: 2;
}
.hero-slides__dot {
  width: 7px; height: 7px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(243, 241, 237, .45);
  cursor: pointer; transition: background .3s var(--ease-ui), transform .3s var(--ease-ui);
}
.hero-slides__dot:hover { background: rgba(243, 241, 237, .8); }
.hero-slides__dot.is-on { background: var(--paper); transform: scale(1.35); }

@media (max-width: 720px) { .hero-slides { height: min(64svh, 520px); } }

/* ---- Hero corridor ------------------------------------------------------
   Two rails of pieces rushing out of the vanishing point. The keyframes are
   generated at build time by corridor.mjs and inlined by the page; everything
   here is the stage they move on.

   `container-type: inline-size` is what makes the whole thing resolution
   independent — every length in the generated keyframes is `cqw`, a percentage
   of THIS element's width, so the corridor keeps its proportions from a phone
   to a wide display without a single media query touching the geometry.
   -------------------------------------------------------------------------- */
.corridor {
  position: relative;
  width: 100%;
  /* Paired with exitHeight in corridor.mjs. The largest card is 30% of the
     frame's WIDTH tall — 432px at the site's widest — and the band is sized to
     hold it with air above and below, so a piece goes past WHOLE. Shorter and
     the nearest pieces lose their tops; taller and the corridor floats in a
     band of empty wash. Change exitHeight and this has to move with it. */
  height: min(56svh, 520px);
  overflow: hidden;
  background: var(--wash);
  container-type: inline-size;
}

/* The stage owns the perspective. `perspective-origin` sets where the
   vanishing point sits, and it must match the `axis` the keyframes were
   generated with or the rails will not converge on it. */
.corridor__stage {
  position: absolute;
  inset: 0;
  /* Nothing in here is reachable. The corridor is something to watch, not
     something to operate — see the note in corridor.mjs about why it stopped
     being a row of links. */
  pointer-events: none;
  perspective: 30cqw;
  perspective-origin: 50% 52%;
}

.corridor__space { position: absolute; inset: 0; transform-style: preserve-3d; }

.corridor__card {
  position: absolute;
  left: 50%;
  overflow: hidden;
  /* Without this the reverse of a rotated card paints as it crosses, which
     reads as a flicker at the moment it turns. */
  backface-visibility: hidden;
}

.corridor__card img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  user-select: none;
}

/* Half the catalogue is photographed on white — the bed linen especially. On
   the wash those cards have no edge at all and read as holes in the ribbon
   rather than as pieces going past. A hairline gives every card a boundary
   without putting a frame around the photograph. */
.corridor__card::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(20, 19, 17, .10);
  pointer-events: none;
}

@media (max-width: 720px) { .corridor { height: min(64svh, 520px); } }

/* ---- The editorial band -------------------------------------------------
   One picture, words laid over it. The gradient is not decoration: white text
   on an unknown photograph is unreadable somewhere in every photograph, and
   this is what makes the contrast a property of the component rather than of
   the image somebody swaps in next year.
   -------------------------------------------------------------------------- */
.band {
  position: relative; display: block; width: 100%;
  /* 21/9 in a 1500px measure was a letterbox with paper either side of it —
     a picture behaving like a figure in a document. Given the whole viewport
     it is a room you walk into, so it gets a floor as well as a ratio: tall
     enough to hold the eye, capped so it never eats a laptop screen whole. */
  aspect-ratio: 21 / 9;
  min-height: clamp(420px, 78vh, 860px);
  overflow: hidden; background: var(--ink);
}
.band--tall { aspect-ratio: 16 / 9; }
/* .band sets width:100% and this file loads after analogue.css, so it was
   quietly beating .bleed's width:100vw and the picture stopped at the measure.
   Two classes beats one. */
.band.bleed { width: 100vw; max-width: 100vw; }
@media (max-width: 809.98px) {
  .band, .band--tall { aspect-ratio: 4 / 5; min-height: 0; }
}

.band img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 1.2s var(--ease);
}
.band:hover img { transform: scale(1.03); }

/* Two scrims, not one.
 *
 * A single bottom gradient is enough over a dark interior and nowhere near
 * enough over the fragrance still, which is almost white — the heading sat on
 * pale glass and could not be read. The vertical scrim carries most of it and
 * the horizontal one guarantees the left column where the words actually are,
 * so the component stays legible over any photograph put into it later. */
.band::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(to right, rgba(22, 21, 15, .62) 0%, rgba(22, 21, 15, .28) 46%, rgba(22, 21, 15, 0) 78%),
    linear-gradient(to top, rgba(22, 21, 15, .82) 0%, rgba(22, 21, 15, .34) 48%, rgba(22, 21, 15, .08) 100%);
}

/* The words run the height of the picture, not a block in one corner.
 *
 * Stacked bottom-left, everything sits in the same eighth of the frame and the
 * other seven are wallpaper. Pinning the eyebrow to the top and the heading to
 * the bottom puts them on a diagonal, which uses the whole picture and gives
 * the type somewhere to be that is not "the corner". The photograph still has
 * its middle, which is where the photograph is actually good. */
.band__words {
  position: absolute; inset: 0; z-index: 1;
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  padding: clamp(20px, 3.4vw, 54px);
}
/* Everything except the eyebrow travels together at the bottom. */
.band__words > .eyebrow { margin-bottom: auto; }
.band__words > :not(.eyebrow) { max-width: min(62ch, 76%); }
.band__words .display-l {
  /* Bigger than the page's own display-l. A heading laid over a full-bleed
     photograph competes with the whole picture; at the body-copy scale it
     loses, and looks like a caption that floated. */
  font-size: clamp(34px, 5.2vw, 88px);
  line-height: 1.02;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.band__words .measure { max-width: 52ch; }
@media (max-width: 809.98px) {
  .band__words { justify-content: flex-end; }
  .band__words > .eyebrow { margin-bottom: 0; }
}

.btn--on-dark {
  border: 1px solid rgba(243, 241, 237, .5);
  color: var(--paper);
  padding: 10px 20px;
}
.btn--on-dark:hover { background: var(--paper); color: var(--ink); opacity: 1; }

@media (max-width: 720px) {
  .band, .band--tall { aspect-ratio: 4 / 5; }
}

/* ---- A card with no photograph yet --------------------------------------
   Used by collection cards while their pieces are still unphotographed. It is
   a real card, set in the display face, not a hole where a picture failed.
   -------------------------------------------------------------------------- */
.card__frame--words {
  display: flex; align-items: center; justify-content: center;
  padding: 18px; text-align: center;
  background: var(--wash);
  border: 1px solid var(--hair);
}
.card__standin { color: var(--stone); line-height: 1.1; }
/* A product card's standin is the piece's NAME, which can be long ("Mamma
   Taweret in Natural Wood Plain 50 cm"); the collection cards set theirs in
   the display face because a house has a short name. Type size follows. */
.card > .card__frame--words .card__standin { font-size: 14px; line-height: 1.3; letter-spacing: .02em; }

/* ---- Choosing an option -------------------------------------------------
   Ten colourways behind one photograph. Each option is a real product, so a
   sold-out one is struck through rather than silently failing at the cart.
   -------------------------------------------------------------------------- */
.opts { margin: 4px 0 2px; }
.opts__label { display: flex; align-items: baseline; gap: 10px; }
.opts__chosen { color: var(--stone); letter-spacing: 0; text-transform: none; }

.opts__row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

.opt {
  display: inline-block; padding: 7px 13px;
  border: 1px solid var(--hair); border-radius: 999px;
  font-family: var(--body); font-size: 13px; line-height: 1;
  color: var(--ink); text-decoration: none;
  transition: border-color .25s var(--ease-ui), background .25s var(--ease-ui), color .25s var(--ease-ui);
}
.opt:hover { border-color: var(--ink); }
.opt.is-on { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.opt.is-out { color: var(--stone); text-decoration: line-through; opacity: .6; }
.opt.is-out.is-on { background: var(--stone); border-color: var(--stone); color: var(--paper); }
/* A colour the chosen size is not made in. Struck through like a
   sold-out one, but it is a <span> with nowhere to go, so it must not offer
   a hand or a hover: sold out is a state, not made is a fact. */
.opt.is-absent { cursor: default; opacity: .38; border-style: dashed; }
.opt.is-absent:hover { border-color: var(--hair); }

/* Two rows on a family with two axes — size, then colour. They are separate
   questions, so they get separate rows and a little more air between them
   than the 8px inside one row. */
.opts + .opts { margin-top: 14px; }

/* How many ways a family comes, on its card in a grid. */
.card__opts {
  font-family: var(--body); font-size: 12px; color: var(--stone);
  margin-top: 2px;
}

/* ---- The ring, full width ----------------------------------------------
   The coverflow ring turns cards through a perspective, so the cards nearest
   the viewer sit WIDER than the column they are in. Inside `.wrap` that is an
   overflow: on a phone the page gained 41px of sideways scroll. The ring gets
   the full viewport and clips its own overhang.
   -------------------------------------------------------------------------- */
.ring-bleed {
  width: 100%;
  overflow: hidden;   /* the ring's far cards may reach past the edge */
}

/* ---- The flat colourway strip ------------------------------------------
   Superseded on the home page by the ring above, kept because it is the right
   shape in a narrow column. `overflow-x: auto` only contains the children if
   the element itself cannot grow — min-width:0 is what stops a flex item from
   pushing the page sideways, and its absence is what made the home page scroll.
   -------------------------------------------------------------------------- */
.rollcall {
  display: flex; gap: 18px; overflow-x: auto; padding: 4px 0 18px;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  min-width: 0; max-width: 100%;
  -webkit-overflow-scrolling: touch;
}
.rollcall__item {
  flex: 0 0 auto; width: clamp(180px, 22vw, 280px);
  scroll-snap-align: center; text-decoration: none; color: inherit;
}
.rollcall__frame {
  aspect-ratio: 1; background: var(--wash); overflow: hidden;
  border: 1px solid var(--hair);
}
.rollcall__frame img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .8s var(--ease);
}
.rollcall__item:hover .rollcall__frame img { transform: scale(1.05); }
.rollcall__name {
  font-family: var(--body); font-size: 13px; margin-top: 10px; color: var(--ink);
}
.rollcall__price { font-family: var(--body); font-size: 13px; color: var(--stone); }
.rollcall__item.is-out .rollcall__name { color: var(--stone); }

/* ---- The reel: every piece, coverflow ----------------------------------
   A ring of square cards in perspective; home.js places each card from its
   distance to the centre (translateX, translateZ, rotateY, opacity), so the
   CSS only has to give the stage its height, the cards their width, and keep
   the shadows clear of the clip. --reel-card is the one number everything
   else is derived from.
   -------------------------------------------------------------------------- */
.reel-section { padding-left: 0; padding-right: 0; overflow: hidden; }
.reel-section > .wrap { width: auto; padding: 0 var(--gap-side); box-sizing: content-box; max-width: var(--measure); }
.reel-section .kt-band__head { margin-bottom: 8px; }
.reel { --reel-card: clamp(160px, 24vw, 300px); position: relative; min-width: 0; }
.reel__frame {
  overflow: hidden; padding: 34px 0 30px; outline: none;
  cursor: grab; touch-action: pan-y; user-select: none; -webkit-user-select: none;
}
.reel__frame:active { cursor: grabbing; }
.reel__frame:focus-visible { box-shadow: inset 0 0 0 1px var(--ink); }
.reel__ring { position: relative; height: calc(var(--reel-card) * 4 / 3); transform-style: preserve-3d; }
/* The card IS the photograph: no frame, no wash, no letterbox. Its width is
   fixed (the ring is paced by width) and its height is whatever the picture
   needs — a 3:4 shot stands taller than a 4:3 one — centred on the ring's
   midline so the row reads as one line of pictures, edge to edge. */
.reel__card {
  position: absolute; left: 50%; top: 50%; width: var(--reel-card);
  margin-top: calc(var(--reel-card) * -2 / 3); /* half the tallest card */
  display: flex; align-items: center; justify-content: center;
  height: calc(var(--reel-card) * 4 / 3);
  overflow: hidden; will-change: transform, opacity;
}
.reel__card img {
  width: 100%; height: auto; max-height: 100%; object-fit: contain; display: block;
  pointer-events: none; box-shadow: 0 18px 40px -18px rgba(0,0,0,.35);
}
.reel__card--words { padding: 0; }
.reel__card--words .card__standin {
  width: 100%; aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  background: var(--wash); padding: 14px; box-sizing: border-box; text-align: center;
}
.reel__card.is-centre { cursor: pointer; }
.reel__arrow {
  position: absolute; top: calc(34px + var(--reel-card) * 2 / 3); transform: translateY(-50%);
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--hair); background: var(--paper); color: var(--ink);
  font: inherit; font-size: 16px; line-height: 1; cursor: pointer;
  display: none; align-items: center; justify-content: center; z-index: 200;
  transition: border-color .3s var(--ease-ui);
}
.reel__arrow:hover { border-color: var(--ink); }
.reel__arrow--prev { left: max(var(--gap-side), calc((100% - var(--measure)) / 2)); }
.reel__arrow--next { right: max(var(--gap-side), calc((100% - var(--measure)) / 2)); }
.reel.is-live .reel__arrow { display: flex; }
.reel__caption { text-align: center; min-height: 48px; padding: 0 var(--gap-side); }
.reel__title {
  font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink); text-decoration: none; border-bottom: 1px solid transparent;
}
.reel__title:hover { border-bottom-color: var(--ink); }
.reel__line { font-size: 13px; color: var(--stone); margin: 4px 0 0; }
@media (max-width: 720px) {
  .reel { --reel-card: 56vw; }
  .reel__arrow { display: none !important; }
}

/* ---- Kyme Toys: collections and collaborations -------------------------- */
.kt-band { margin-top: 34px; }
.kt-band__head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 12px; border-bottom: 1px solid var(--hair); padding-bottom: 10px; margin-bottom: 20px;
}
.kt-collab {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 0; border-bottom: 1px solid var(--hair);
  text-decoration: none; color: inherit;
  transition: opacity .3s var(--ease-ui);
}
.kt-collab:hover { opacity: .62; }
.kt-collab__frame {
  width: 64px; height: 64px; flex: none; overflow: hidden;
  background: var(--wash); border: 1px solid var(--hair);
}
.kt-collab__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kt-collab__who { min-width: 190px; }

@media (max-width: 720px) {
  .kt-collab { flex-wrap: wrap; }
  .kt-collab__who { min-width: 0; }
}

/* ---- The seven houses ---------------------------------------------------
   A list, not a grid: seven rows read faster than seven cards, and the count
   on the right lines up into a column you can scan.
   -------------------------------------------------------------------------- */
.house-list { border-top: 1px solid var(--hair); }

.house {
  display: flex; align-items: center; gap: 16px;
  padding: 16px 0; border-bottom: 1px solid var(--hair);
  text-decoration: none; color: inherit;
  transition: opacity .3s var(--ease-ui);
}
.house:hover { opacity: .62; }

.house__id { display: flex; align-items: center; gap: 16px; min-width: 200px; }
.house__id img {
  width: 44px; height: 44px; object-fit: cover; background: var(--wash); flex: none;
}
.house__line { flex: 1 1 220px; }

@media (max-width: 720px) {
  .house { flex-wrap: wrap; }
  .house__id { min-width: 0; }
  .house__line { flex-basis: 100%; }
}

/* ---- The sign-in page ---------------------------------------------------
   Two columns: the form on paper, one piece of the work beside it. /account is
   the only page a customer reaches with nothing on it to look at, and a shop
   that sells objects should not show a blank room at the moment it asks
   somebody to commit to it.

   The picture is the second column and not a background, so it can be given a
   real aspect and so `loading="lazy"` means something. Below 900px it is not
   rendered at all — a phone gets the form, full width, and pays nothing for a
   photograph it would never have seen.
   -------------------------------------------------------------------------- */
.signin {
  display: grid;
  grid-template-columns: 1fr;
  min-height: calc(100svh - var(--nav-h, 84px));
}

/* `hidden` must win over the grid, or the signed-out block keeps its space
   after somebody signs in and the page opens on a screen of nothing. */
.signin[hidden] { display: none; }

.signin__form { display: flex; align-items: center; justify-content: center; padding: 56px 24px 72px; }
/* The form column keeps a readable measure of its own; it is the PAGE that is
   full width, not the text. */
.signin__inner { width: 100%; max-width: 26rem; }

.signin__art { display: none; }

@media (min-width: 900px) {
  .signin { grid-template-columns: 1fr 1fr; }
  .signin__form { padding: 64px 48px; }
  .signin__art { display: block; position: relative; overflow: hidden; background: var(--wash); }
  .signin__art img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
}

/* ---- the password, and being able to look at it ------------------------- */
.signin__secret { position: relative; }
.signin__secret input { padding-right: 4.5rem; }
.signin__reveal {
  position: absolute; top: 50%; right: 0; transform: translateY(-50%);
  padding: 6px 2px; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .78rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--stone);
}
.signin__reveal:hover { color: var(--ink); }

/* ---- the divider above another way in ----------------------------------- */
.signin__or {
  position: relative; margin: 26px 0 18px; text-align: center;
  font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; color: var(--stone);
}
.signin__or::before {
  content: ""; position: absolute; top: 50%; left: 0; right: 0;
  border-top: 1px solid var(--hair);
}
.signin__or span { position: relative; padding: 0 14px; background: var(--paper); }

.signin__google { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; }
.signin__google svg { width: 18px; height: 18px; flex: none; }

/* ---- The patchwork on a form page ---------------------------------------
   Six columns, and every row filled exactly — the arrangements are chosen in
   catalogue.js from a set that adds to six, so no count of pieces can leave a
   hole. A grid with a fixed column count is only right for counts that divide
   by it, and Single Malt has one piece in each of four houses: four rows of
   one card and three columns of nothing.

   Tiles are a constant height and a varying width, so a wide piece gets a wide
   frame and the row rhythm changes down the page. That is the patchwork.
   -------------------------------------------------------------------------- */
.patch {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 20px 16px;
  width: 100%;
}

.patch__tile {
  grid-column: span var(--span, 2);
  display: block;
  text-decoration: none;
  color: inherit;
}

/* Height is fixed and width is not, so a two-column tile is portrait and a
   four-column one is a wide frame. `cover` fills either without distorting. */
.patch__frame {
  height: 268px;
  background: var(--wash);
  overflow: hidden;
}
.patch__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.patch__tile:hover .patch__frame img { opacity: .86; }
.patch__frame img { transition: opacity .4s var(--ease-ui); }

/* The house, on the piece. Grouping the houses into separate grids is what
   made the holes; naming each piece's house on its own card says the same
   thing where somebody is already looking. */
.patch__house {
  margin: 8px 0 0;
  font-size: 10px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--stone);
}
.patch__tile .card__name { margin: 2px 0 2px; }

.patch__frame.card__frame--words {
  display: flex; align-items: center; justify-content: center; padding: 18px;
  text-align: center;
}
.patch__frame .card__standin { font-size: 15px; line-height: 1.3; color: var(--stone); }

@media (max-width: 900px) {
  /* Four columns, and the arrangements still add up — a span of 3 is half a
     row here instead of a third, which keeps every row full. */
  .patch { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .patch__tile { grid-column: span min(var(--span, 2), 4); }
  .patch__frame { height: 220px; }
}
@media (max-width: 560px) {
  .patch { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 10px; }
  .patch__tile { grid-column: span min(var(--span, 2), 2); }
  .patch__frame { height: 176px; }
}

/* The houses on /lifestyle, as a patchwork.
 *
 * One band a house: two blocks butted hard against each other, stacking with
 * nothing between them. No gutter, no gap, no card, no frame — the photograph
 * IS the block and the words sit in one beside it, so the run reads as a quilt
 * rather than as five cards floating on a background.
 *
 * CENTRED, and held to the same measure as everything else. It used to run the
 * full width of the window, which on a wide monitor pinned the photograph to
 * the far right edge and left the writing stranded at the far left with a
 * quarter of the screen of empty paper between them. The page has one measure
 * — 1500px, the same one the front page's About band and every other section
 * uses — and this belongs inside it like the rest.
 *
 * `width: min(100% - two gutters, the measure)` is exactly what .section and
 * .wrap do together, written as one line because these bands are their own
 * sections and carry no padding of their own. */
.quilt {
  display: grid;
  grid-template-columns: 1fr 1fr;
  width: min(100% - var(--gap-side) * 2, var(--measure));
  margin-inline: auto;
  background: var(--paper);
}
/* Bands touch. A hairline between them would be five cards again. */
.quilt + .quilt { margin-top: 0; }
/* Air above the first and below the last, so the run does not jam into the
   photograph above it or the link below. The same figure every section uses. */
.quilt:first-of-type { margin-top: calc(var(--gap-section) * 1.6); }
.quilt:last-of-type { margin-bottom: calc(var(--gap-section) * 1.6); }

/* The words block. The same height as the photograph beside it — the grid sees
   to that — so the writing is centred in its own half rather than sitting at
   the top of a tall empty box. */
.quilt__words {
  display: flex; align-items: center;
  padding: clamp(22px, 3vw, 48px);
  background: var(--wash);
}
.quilt:nth-of-type(even) .quilt__words { background: var(--paper); }
.quilt__inner { width: 100%; max-width: 34rem; }

/* The picture block.
 *
 * 4:3, and NOTHING ELSE — no height cap, no viewport units. The width comes
 * from the measure above, the height follows from the proportion, and there is
 * only ever one way to satisfy that, so every browser draws it identically.
 *
 * An earlier version paired this ratio with a `max-height`. Those two
 * instructions contradict each other and engines settle it differently — some
 * clamp the height, some keep the ratio by shrinking the width and leave a
 * strip of bare paper beside the picture. The same page looked different on
 * two machines on the same afternoon. The measure is what caps the height now,
 * which it does without arguing with anything.
 *
 * The files are cut to 4:3 as well, so `cover` has nothing to crop away and
 * the whole family is on screen at every size. */
.quilt__pic {
  display: block; position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--wash);
}
.quilt__pic img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  display: block;
  transition: transform .6s var(--ease, cubic-bezier(.2,.7,.2,1));
}
.quilt__pic:hover img { transform: scale(1.03); }
@media (prefers-reduced-motion: reduce) {
  .quilt__pic img, .quilt__pic:hover img { transition: none; transform: none; }
}

/* Every other band puts the photograph on the left, which is the only thing
   stopping five identical bands from reading as a form.
   Desktop only: below the breakpoint the band is one column, and `order` would
   put a photograph above the words that explain it. */
@media (min-width: 810px) {
  .quilt--flip .quilt__words { order: 2; }
  .quilt--flip .quilt__pic { order: 1; }
}
@media (max-width: 809.98px) {
  .quilt { grid-template-columns: minmax(0, 1fr); }
}
}

/* The account, in three panels.
 *
 * A small row of links rather than three addresses. The account is one thing,
 * and a guest who came to change a delivery address should not have to go and
 * find which page we put it on. The underline moves; nothing else does.
 */
.acct-nav {
  display: flex; flex-wrap: wrap; gap: 22px;
  border-bottom: 1px solid var(--hair);
  padding-bottom: 0;
}
.acct-nav__tab {
  position: relative;
  padding: 0 0 10px;
  font-size: 13px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--stone); text-decoration: none;
  transition: color .3s var(--ease-ui);
}
.acct-nav__tab:hover { color: var(--ink); }
.acct-nav__tab.is-on { color: var(--ink); }
.acct-nav__tab.is-on::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 1px; background: var(--ink);
}
.acct-panel[hidden] { display: none; }

/* One subject to a block, with a rule between them rather than a card each:
   five bordered boxes down a page reads as a form to be completed, and this is
   a set of things that are already true and may be changed. */
.acct-block { padding-bottom: 32px; border-bottom: 1px solid var(--hair); }
.acct-block:last-child { border-bottom: 0; }

/* Closing the account. Marked, not shouted — the consequences are written out
   above it in words, which does more than a red button ever does. */
.acct-block--grave { border-top: 1px solid var(--hair); padding-top: 32px; }
.acct-block--grave .btn--ghost { border-color: var(--stone); color: var(--stone); }
.acct-block--grave .btn--ghost:hover { border-color: #8a2b2b; color: #8a2b2b; }

/* A checkbox and its sentence, aligned on the first line of the sentence
   rather than on its middle — a two-line label with a centred box looks
   like a mistake. */
.acct-check { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.acct-check input { margin-top: 4px; flex: 0 0 auto; }
.acct-check span { color: var(--stone); }

/* The two numbers on a tier card.
 *
 * The threshold is a running total — 175,000 for Gold — because that is what
 * the engine compares a balance against. The line under it is the climb from
 * the rung below, 100,000, which is the number somebody standing on Silver is
 * actually counting down. Printing only the total makes every tier look
 * further off than it is; printing only the climb makes the ladder impossible
 * to add up. So both, with the total leading. */
.mem-tier__step { margin-top: 2px; font-size: 13px; }
