/* ==========================================================================
   Stitch Wishess — "Holo-Craft"
   Pastel futurism. Palette sampled directly from the studio's own artwork.
   ========================================================================== */

:root {
  /* Surface */
  --paper: #f2fafc;
  --paper-warm: #fdf4ea;
  --paper-raised: rgba(255, 255, 255, 0.72);

  /* Ink */
  --ink: #0d2a31;
  --ink-soft: #4a6e75;
  --ink-faint: #8aa5aa;

  /* Aurora — sampled from sky-texture.png */
  --aurora: #8fd4e6;
  --periwinkle: #9cc2e6;
  --mint: #aee2d2;

  /* Medallion — sampled from stitch-witch-portrait.png */
  --lilac: #e4cce4;
  --blossom: #f0c0e4;
  --peach: #fcd8cc;

  /* The palette has no error colour because the storefront never needed one.
     A deep rose keeps it in the family — blossom taken down to a weight that
     reads as "stop". */
  --alert: #a8456a;

  --line: rgba(13, 42, 49, 0.14);
  --line-soft: rgba(13, 42, 49, 0.07);

  --holo: linear-gradient(
    100deg,
    var(--aurora) 0%,
    var(--periwinkle) 22%,
    var(--lilac) 44%,
    var(--blossom) 62%,
    var(--peach) 78%,
    var(--mint) 100%
  );

  /* Same iridescence, pitched dark enough to read as type */
  --holo-ink: linear-gradient(
    100deg,
    #2f9cba 0%,
    #5b86c9 28%,
    #9a6dc4 52%,
    #c25fa0 74%,
    #3f9e83 100%
  );

  --font-display: "Unbounded", "Segoe UI", system-ui, sans-serif;
  --font-body: "Manrope", "Segoe UI", system-ui, sans-serif;
  --font-mono: "DM Mono", ui-monospace, "Cascadia Mono", monospace;

  --rail: 5.5rem;
  --content-max: 78rem;
  --radius: 20px;

  --s1: 0.5rem;
  --s2: 1rem;
  --s3: 1.75rem;
  --s4: 3rem;
  --s5: 5.5rem;
  --s6: 9rem;
}

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16.5px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The studio's own painted sky, fixed behind everything.
   The veil on top keeps body copy readable over the saturated bands. */
body::before {
  content: "";
  position: fixed;
  inset: -8%;
  z-index: -4;
  /* A palette tint over the photo. `cover` crops differently at every window
     shape, and the image's centre is its palest region — without this the
     background washes out on tall or narrow viewports. */
  background:
    linear-gradient(
      160deg,
      rgba(143, 212, 230, 0.42) 0%,
      rgba(156, 194, 230, 0.3) 28%,
      rgba(174, 226, 210, 0.26) 52%,
      rgba(240, 192, 228, 0.3) 76%,
      rgba(252, 216, 204, 0.34) 100%
    ),
    url("assets/sky-texture.png") center / cover no-repeat;
  filter: saturate(1.14);
  animation: drift 46s ease-in-out infinite alternate;
}

/* Drifting cloud layers, cut from the same painted sky.
   Each layer is 200% wide and travels exactly a whole number of tiles,
   so the loop never shows a seam. */
.clouds {
  position: fixed;
  inset: 0;
  z-index: -3;
  overflow: hidden;
  pointer-events: none;
}

/* Puffs are gradients, not the photo: the sky texture has no tileable edge,
   so tiling it leaves a seam. Every blob fades out well inside its own tile,
   which makes the repeat invisible. */
.cloud-layer {
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;
  height: 100%;
  background-repeat: repeat-x;
  will-change: transform;
}

.cloud-layer--far {
  background-image:
    radial-gradient(22% 30% at 24% 28%, rgba(255, 255, 255, 0.95), transparent 72%),
    radial-gradient(19% 25% at 56% 52%, rgba(255, 255, 255, 0.85), transparent 74%),
    radial-gradient(16% 21% at 81% 24%, rgba(240, 250, 253, 0.88), transparent 74%);
  background-size: 50% 100%;
  opacity: 1;
  animation: cloud-drift 190s linear infinite;
}

.cloud-layer--near {
  background-image:
    radial-gradient(18% 23% at 20% 70%, rgba(255, 255, 255, 0.82), transparent 74%),
    radial-gradient(15% 19% at 52% 84%, rgba(255, 248, 242, 0.72), transparent 76%),
    radial-gradient(13% 17% at 78% 62%, rgba(255, 255, 255, 0.68), transparent 76%);
  background-size: 25% 100%;
  opacity: 0.9;
  animation: cloud-drift 105s linear infinite;
}

@keyframes cloud-drift {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }
}

/* Fine grain so the pastels read as material, not flat gradient */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

@keyframes drift {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  50% { transform: translate3d(-2.5%, 2%, 0) scale(1.06); }
  100% { transform: translate3d(2%, -1.5%, 0) scale(1.03); }
}

img {
  max-width: 100%;
  display: block;
}

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

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 4px;
}

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.035em;
  margin: 0 0 var(--s2);
}

h1 { font-size: clamp(2.6rem, 5.2vw + 0.6rem, 5.4rem); }
h2 { font-size: clamp(2rem, 3.4vw + 0.6rem, 3.4rem); }

h3 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.25;
}

p {
  margin: 0 0 var(--s2);
  color: var(--ink-soft);
}

/* Mono is the utility voice: labels, prices, specs, coordinates */
.label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 var(--s2);
}

.holo-text {
  background: var(--holo-ink);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: holo-shift 14s ease-in-out infinite alternate;
}

@keyframes holo-shift {
  0% { background-position: 0% 50%; }
  100% { background-position: 100% 50%; }
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.wrap {
  max-width: var(--content-max);
  margin: 0 auto;
  padding-inline: var(--s3);
}

main {
  padding-left: var(--rail);
}

.band {
  padding-block: var(--s6);
}

.band--tight {
  padding-block: var(--s5);
}

/* Section heading: a stitch dash, then the name in mono */
.band-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s4);
  padding-bottom: var(--s2);
  border-bottom: 1px dashed var(--line);
}

.band-head h2 {
  margin: 0;
}

.band-head .band-note {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   The thread — signature element.
   A dashed stitch line that sews itself down the page as you scroll,
   with beads at each section anchor. This is how the beaded pens are made.
   -------------------------------------------------------------------------- */

.thread {
  position: fixed;
  top: 0;
  left: 0;
  width: var(--rail);
  height: 100vh;
  z-index: -2;
  pointer-events: none;
}

.thread__svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.thread__track {
  fill: none;
  stroke: rgba(13, 42, 49, 0.18);
  stroke-width: 1.75;
  stroke-dasharray: 7 7;
}

.thread__stitch {
  fill: none;
  stroke: url(#threadHolo);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 7 7;
}

.thread__beads {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.bead {
  position: absolute;
  left: 50%;
  width: 13px;
  height: 13px;
  margin-left: -6.5px;
  margin-top: -6.5px;
  border-radius: 50%;
  background: var(--paper);
  border: 1.5px solid rgba(13, 42, 49, 0.28);
  transition: transform 0.45s cubic-bezier(0.2, 0.9, 0.3, 1), border-color 0.45s ease, box-shadow 0.45s ease;
  pointer-events: auto;
}

/* No printed labels: they sat 22px right of the bead, overflowed the rail and
   collided with body copy. The section name lives in the bead's title
   attribute instead, so the rail stays purely a spine. */
.bead.is-strung {
  background: var(--holo);
  border-color: transparent;
  transform: scale(1.5);
  box-shadow: 0 0 0 4px rgba(143, 212, 230, 0.22);
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  padding-left: var(--rail);
  /* The original storefront ran a dark bar over the pastel sky; it is what
     gave the site its contrast, so it comes back here. */
  background: rgba(11, 34, 40, 0.9);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.site-header .brand {
  color: #f1f3f3;
}

.site-header .nav a {
  color: rgba(241, 243, 243, 0.72);
}

.site-header .nav a:hover,
.site-header .nav a[aria-current="page"] {
  color: #ffffff;
  border-bottom-color: var(--aurora);
}

.site-header :focus-visible {
  outline-color: var(--aurora);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding-top: 0.85rem;
  padding-bottom: 0.85rem;
}

.brand {
  display: flex;
  align-items: center;
  /* wide enough that an orbiting heart never crosses the wordmark */
  gap: 1.6rem;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.brand__mark {
  position: relative;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--holo);
  background-size: 200% 100%;
  animation: holo-shift 14s ease-in-out infinite alternate;
  flex: none;
}

/* The two blue hearts the original wordmark wore, set orbiting the mark.
   The counter-rotation keeps each heart upright as it travels. */
.brand__mark::before,
.brand__mark::after {
  content: "\1F499";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1em;
  height: 1em;
  margin: -0.5em 0 0 -0.5em;
  font-size: 11px;
  line-height: 1;
  text-align: center;
  animation: heart-orbit 11s linear infinite;
}

.brand__mark::after {
  font-size: 8px;
  animation-delay: -5.5s;
  opacity: 0.85;
}

@keyframes heart-orbit {
  from { transform: rotate(0deg) translateX(22px) rotate(0deg); }
  to { transform: rotate(360deg) translateX(22px) rotate(-360deg); }
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--s3);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.nav a {
  color: var(--ink-soft);
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.nav a:hover,
.nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--aurora);
}

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

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.85rem 1.7rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform 0.25s cubic-bezier(0.2, 0.9, 0.3, 1), box-shadow 0.25s ease, border-color 0.25s ease;
}

.btn-primary {
  background: var(--ink);
  color: var(--paper);
}

.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 30px -14px rgba(13, 42, 49, 0.55);
}

.btn-ghost {
  background: var(--paper-raised);
  color: var(--ink);
  border-color: var(--line);
  backdrop-filter: blur(12px);
}

.btn-ghost:hover {
  transform: translateY(-2px);
  border-color: var(--aurora);
}

/* --------------------------------------------------------------------------
   Hero — the medallion is the thesis
   -------------------------------------------------------------------------- */

.hero {
  padding-block: var(--s6) var(--s5);
}

.hero__grid {
  display: grid;
  grid-template-columns: 1fr 1.25fr;
  align-items: center;
  gap: var(--s4);
}

.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 var(--s3);
}

.hero__eyebrow::before {
  content: "";
  width: 34px;
  height: 1px;
  background: var(--ink-faint);
  flex: none;
}

.hero h1 {
  margin-bottom: var(--s3);
}

.hero__lede {
  max-width: 38ch;
  font-size: 1.08rem;
  margin-bottom: var(--s3);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

/* Medallion: circular crop of the artwork, ringed and lit */
.medallion {
  position: relative;
  aspect-ratio: 1;
  border-radius: 50%;
  justify-self: center;
  width: min(100%, 42rem);
  padding: 10px;
  background: var(--holo);
  background-size: 200% 200%;
  animation: holo-spin 20s linear infinite;
  box-shadow: 0 30px 70px -30px rgba(13, 42, 49, 0.4);
}

.medallion__disc {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  overflow: hidden;
  background: var(--paper);
}

.medallion__disc img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Slow sheen sweep across the disc — iridescent foil */
.medallion__sheen {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: linear-gradient(
    115deg,
    transparent 34%,
    rgba(255, 255, 255, 0.5) 47%,
    rgba(255, 255, 255, 0.16) 53%,
    transparent 66%
  );
  background-size: 260% 260%;
  mix-blend-mode: screen;
  animation: sheen 9s ease-in-out infinite;
}

@keyframes holo-spin {
  0% { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}

@keyframes sheen {
  0%, 62% { background-position: 120% 0%; }
  100% { background-position: -40% 100%; }
}

/* --------------------------------------------------------------------------
   Product grid — specimen cards
   -------------------------------------------------------------------------- */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
  gap: var(--s3);
}

.card {
  display: flex;
  flex-direction: column;
  background: var(--paper-raised);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 10px 10px 1.1rem;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  transition: transform 0.3s cubic-bezier(0.2, 0.9, 0.3, 1), box-shadow 0.3s ease, border-color 0.3s ease;
}

.card:hover {
  transform: translateY(-6px);
  border-color: rgba(143, 212, 230, 0.7);
  box-shadow: 0 26px 50px -26px rgba(13, 42, 49, 0.34);
}

/* 3:4 rather than 4:5. Cards stay cropped so the grid holds a clean line, but
   the commonest photograph in this catalog is exactly 3:4 — at this ratio
   those lose nothing at all, where 4:5 was shaving them. */
.card__media {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: calc(var(--radius) - 8px);
  overflow: hidden;
  background: linear-gradient(150deg, var(--aurora), var(--lilac));
  margin-bottom: 0.95rem;
}

.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.55s cubic-bezier(0.2, 0.9, 0.3, 1);
}

.card:hover .card__media img {
  transform: scale(1.05);
}

.card__media--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(13, 42, 49, 0.5);
  text-align: center;
  padding: var(--s2);
}

.card__body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0 0.45rem;
  flex: 1;
}

.card__title {
  margin: 0;
  color: var(--ink);
}

.card__price {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 0;
  margin-top: auto;
  padding-top: 0.35rem;
}

/* --------------------------------------------------------------------------
   The maker
   -------------------------------------------------------------------------- */

.maker {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: var(--s5);
  align-items: center;
}

.maker__frame {
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line-soft);
  background: var(--paper-raised);
  padding: 10px;
  box-shadow: 0 24px 50px -30px rgba(13, 42, 49, 0.35);
}

.maker__frame img {
  border-radius: calc(var(--radius) - 8px);
  aspect-ratio: 3 / 4;
  object-fit: cover;
  width: 100%;
}

.maker__quote {
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 1.5vw + 0.7rem, 1.7rem);
  font-weight: 500;
  line-height: 1.32;
  letter-spacing: -0.025em;
  color: var(--ink);
  margin: 0 0 var(--s3);
}

.maker__sig {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* --------------------------------------------------------------------------
   Materials — the studio's vernacular, as a spec table
   -------------------------------------------------------------------------- */

.materials {
  display: grid;
  /* eight materials, so four columns fill two rows exactly */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px dashed var(--line);
  border-left: 1px dashed var(--line);
}

.materials div {
  padding: 1.25rem 1.1rem;
  border-bottom: 1px dashed var(--line);
  border-right: 1px dashed var(--line);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  transition: background-color 0.3s ease, color 0.3s ease;
}

.materials div:hover {
  background: rgba(255, 255, 255, 0.6);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Page heads (collection / about / product)
   -------------------------------------------------------------------------- */

.page-head {
  padding-block: var(--s5) var(--s4);
}

.page-head h1 {
  margin-bottom: var(--s2);
}

.page-head p {
  max-width: 44ch;
}

/* Product detail */
.detail {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s5);
  align-items: start;
  padding-block: var(--s4) var(--s5);
}

.detail__media {
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line-soft);
  background: var(--paper-raised);
  padding: 10px;
}

/* contain, not cover. 85% of this catalog is portrait and the pens run as
   narrow as 0.51 — a square crop was cutting half the pen away. The frame is
   2:3 because that is the median shape here, so most photographs sit in it
   with little letterboxing, and none of them lose anything.
   A fixed ratio keeps the page from jumping as you step through the strip. */
.detail__media img {
  border-radius: calc(var(--radius) - 8px);
  display: block;
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: contain;
}

/* Gallery — every photograph of a piece, not just the first.
   Products carry up to ten; the strip wraps rather than scrolling so none of
   them are hidden behind a gesture. */
.thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: 0.5rem;
  margin-top: 0.7rem;
}

.thumb {
  padding: 0;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  overflow: hidden;
  background: var(--paper-raised);
  cursor: pointer;
  aspect-ratio: 1;
  transition: border-color 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}

/* Also contain: a square crop of a pen photograph shows the middle handful of
   beads, which made every thumbnail in a strip of ten look identical. Whole
   photographs are what make them tellable apart. */
.thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.thumb:hover {
  transform: translateY(-2px);
  border-color: var(--aurora);
}

/* The selected photograph gets the same holo ring the strung beads wear, so
   "this one is active" reads the same way everywhere on the site. */
.thumb.is-active {
  border-color: transparent;
  box-shadow: 0 0 0 2px var(--aurora), 0 0 0 6px rgba(143, 212, 230, 0.22);
}

/* Count on the card: tells you there is more to see before you open a piece */
.card__count {
  position: absolute;
  right: 0.6rem;
  bottom: 0.6rem;
  padding: 0.25rem 0.55rem;
  border-radius: 999px;
  background: rgba(13, 42, 49, 0.62);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  backdrop-filter: blur(6px);
}

/* Product titles run long; they must not inherit the hero scale */
.detail h1 {
  font-size: clamp(1.8rem, 1.9vw + 0.9rem, 2.7rem);
  line-height: 1.04;
  margin-bottom: var(--s2);
}

.detail__price {
  font-family: var(--font-mono);
  font-size: 1.15rem;
  color: var(--ink);
  margin-bottom: var(--s3);
}

.detail__desc {
  border-top: 1px dashed var(--line);
  padding-top: var(--s3);
  margin-bottom: var(--s3);
  max-width: 58ch;
}

.detail .not-found {
  grid-column: 1 / -1;
  text-align: center;
  padding: var(--s6) 0;
}

/* About */
.about-body {
  max-width: 44rem;
  padding-block: var(--s4) var(--s6);
}

.about-body p {
  font-size: 1.05rem;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  padding-left: var(--rail);
  border-top: 1px dashed var(--line);
  margin-top: var(--s5);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: var(--s4);
  padding-block: var(--s4) var(--s3);
}

.footer-grid h3 {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--s2);
}

.footer-grid ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-grid li {
  margin-bottom: 0.45rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.footer-grid a:hover {
  color: var(--ink);
}

.footer-bottom {
  border-top: 1px solid var(--line-soft);
  padding-block: var(--s2) var(--s4);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: flex;
  justify-content: space-between;
  gap: var(--s2);
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Scroll reveal
   -------------------------------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.9, 0.3, 1);
}

.reveal.is-in {
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1000px) {
  .hero__grid,
  .maker {
    grid-template-columns: 1fr;
    gap: var(--s4);
  }

  .medallion {
    order: -1;
    width: min(100%, 30rem);
  }

  .detail {
    grid-template-columns: 1fr;
    gap: var(--s4);
  }

  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 720px) {
  :root {
    --rail: 0rem;
    --s5: 3.5rem;
    --s6: 5rem;
  }

  .thread {
    display: none;
  }

  .band-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
  }

  .footer-grid {
    grid-template-columns: 1fr;
  }

  .materials {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .nav {
    gap: 1rem;
    font-size: 0.66rem;
    letter-spacing: 0.1em;
  }
}

/* Phone: drop the wordmark so the nav never runs off the edge */
@media (max-width: 560px) {
  .wrap {
    padding-inline: 1.1rem;
  }

  .brand__label {
    display: none;
  }

  .nav {
    gap: 0.8rem;
    font-size: 0.62rem;
    letter-spacing: 0.07em;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  body::before,
  .holo-text,
  .brand__mark,
  .medallion,
  .medallion__sheen,
  .cloud-layer,
  .brand__mark::before,
  .brand__mark::after {
    animation: none;
  }

  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .card,
  .btn,
  .card__media img,
  .thumb {
    transition: none;
  }
}

/* ==========================================================================
   The bag.
   ========================================================================== */

.bag-wrap { padding-block: var(--s4) var(--s5); }

.bag {
  display: grid;
  grid-template-columns: 1fr 20rem;
  gap: var(--s4);
  align-items: start;
}

.bag h1 { font-size: clamp(1.8rem, 3vw, 2.6rem); margin-bottom: var(--s3); }

.bag-empty { text-align: center; padding-block: var(--s5) var(--s6); }
.bag-empty h1 { font-size: clamp(1.8rem, 4vw, 2.8rem); margin-bottom: var(--s2); }
.bag-empty p { color: var(--ink-soft); margin-bottom: var(--s3); }

/* Anything the server removed or reduced is said out loud. A bag that quietly
   gets smaller is a bag nobody trusts. */
.bag-problems {
  margin: 0 0 var(--s3);
  padding: var(--s2) var(--s3);
  list-style: none;
  border-radius: 14px;
  background: rgba(168, 69, 106, 0.1);
  color: var(--alert);
  font-size: 0.9rem;
}

.bag-items { list-style: none; margin: 0; padding: 0; }

.bag-item {
  display: grid;
  grid-template-columns: 5rem 1fr auto auto auto;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) 0;
  border-bottom: 1px dashed var(--line);
}

.bag-item__media {
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  background: var(--paper-raised);
  border: 1px solid var(--line-soft);
}

.bag-item__media img { width: 100%; height: 100%; object-fit: contain; }
.bag-item__media--empty { background: linear-gradient(150deg, var(--aurora), var(--lilac)); }

.bag-item__title {
  display: block;
  font-family: var(--font-display);
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
}

.bag-item__title:hover { text-decoration: underline; }

.bag-item__price {
  margin: 0.2rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--ink-faint);
}

.bag-item__line {
  margin: 0;
  min-width: 4.5rem;
  text-align: right;
  font-family: var(--font-mono);
}

.bag-item__drop {
  width: 2rem; height: 2rem;
  border: 0; background: none;
  color: var(--ink-faint);
  font-size: 1.2rem; line-height: 1;
  cursor: pointer;
}

.bag-item__drop:hover { color: var(--alert); }

.stepper {
  display: flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper-raised);
}

.stepper button {
  width: 2rem; height: 2rem;
  border: 0; background: none;
  color: var(--ink);
  font-size: 1rem; line-height: 1;
  cursor: pointer;
}

.stepper button:hover { color: var(--aurora); }
.stepper span { min-width: 1.8rem; text-align: center; font-family: var(--font-mono); font-size: 0.85rem; }

/* ----------------------------------------------------------------- total */

.bag-total {
  position: sticky;
  top: var(--s3);
  padding: var(--s3);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--paper-raised);
  backdrop-filter: blur(14px);
}

.bag-total dl { margin: 0 0 var(--s3); }

.bag-total dl div {
  display: flex;
  justify-content: space-between;
  gap: var(--s2);
  padding: 0.35rem 0;
}

.bag-total dt { color: var(--ink-soft); font-size: 0.92rem; }
.bag-total dd { margin: 0; font-family: var(--font-mono); font-size: 0.92rem; }

.bag-total__sum {
  margin-top: 0.4rem;
  padding-top: 0.7rem !important;
  border-top: 1px solid var(--line);
}

.bag-total__sum dt { color: var(--ink) !important; font-weight: 600; }
.bag-total__sum dd { font-size: 1.1rem; }

.bag-total__pay { width: 100%; justify-content: center; }

.bag-total__note {
  margin: var(--s2) 0 0;
  font-size: 0.84rem;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.bag-total__back {
  display: block;
  margin-top: var(--s2);
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* --------------------------------------------------------- sold out ---- */

.card__sold {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(13, 42, 49, 0.42);
  backdrop-filter: blur(2px);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.buy-note {
  margin: 0 0 var(--s2);
  font-size: 0.9rem;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.btn[disabled]:hover { transform: none; box-shadow: none; }

@media (max-width: 860px) {
  .bag { grid-template-columns: 1fr; }
  .bag-total { position: static; }
}

@media (max-width: 560px) {
  .bag-item {
    grid-template-columns: 3.5rem 1fr auto;
    grid-template-areas: 'pic body drop' 'pic step line';
    row-gap: 0.5rem;
  }
  .bag-item__media { grid-area: pic; }
  .bag-item__body { grid-area: body; }
  .stepper { grid-area: step; }
  .bag-item__line { grid-area: line; }
  .bag-item__drop { grid-area: drop; }
}

/* ------------------------------------------------------- plain choices -- */

.choices { margin-bottom: var(--s3); }

.choices__row { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.choice {
  padding: 0.5rem 1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper-raised);
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-size: 0.88rem;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.choice:hover { border-color: var(--aurora); color: var(--ink); }

.choice.is-on {
  background: var(--ink);
  border-color: transparent;
  color: var(--paper);
}

.bag-item__variant {
  margin: 0.15rem 0 0;
  font-size: 0.8rem;
  color: var(--ink-soft);
}

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

/* ==========================================================================
   One strip.

   Every design photograph is also a gallery photograph, so a second row of
   the same pictures was showing the same thing twice. A thumbnail IS the
   design: it shows large and it is chosen, in one press.
   ========================================================================== */

/* A thumbnail that can be chosen sits a little prouder than one that is only
   a picture, so the difference is visible before anything is clicked. */
.thumb.is-design {
  border-color: var(--line);
  cursor: pointer;
}

/* Currently shown. */
.thumb.is-active { border-color: var(--aurora); }

/* Currently chosen — the same holo ring the strung beads wear. */
.thumb.is-chosen {
  border-color: transparent;
  box-shadow: 0 0 0 2px var(--aurora), 0 0 0 6px rgba(143, 212, 230, 0.22);
}

.thumb.is-gone { cursor: not-allowed; opacity: 0.45; }
.thumb.is-gone img { filter: grayscale(1); }

.thumb__gone {
  position: absolute;
  inset: auto 0 0 0;
  background: rgba(13, 42, 49, 0.72);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.48rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  padding: 0.12rem 0;
}

.thumb { position: relative; }

/* What is being bought, said next to the button rather than over the strip. */
.chosen {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0 0 var(--s2);
  color: var(--ink);
}

.chosen .label { margin: 0; }

/* --------------------------------------------------------- the small print */

.policy { max-width: 42rem; }

.policy h2 {
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  margin-bottom: var(--s2);
  scroll-margin-top: var(--s4);
}

.policy p { text-wrap: pretty; }

.policy ul {
  margin: 0 0 var(--s2);
  padding-left: 1.1rem;
  color: var(--ink-soft);
}

.policy li { margin-bottom: 0.5rem; }

.policy a { text-decoration: underline; text-underline-offset: 2px; }

/* ------------------------------------------------- shopping on a phone ---- */
/*
   The catalog grid is auto-fill with a 15.5rem minimum. On a desktop that is
   right; on a 390px phone the available width is about 355px, two columns would
   need roughly 520px, and so exactly one card fits. The catalog read as one
   product at a time — a column to scroll rather than a shop to browse.

   Two fixed columns below this width instead. The photographs stay 3:4 portrait
   rather than being squared off, because most of these are beaded pens standing
   upright and a square crop cuts their heads off.
*/
@media (max-width: 560px) {
  .grid {
    /* minmax(0, 1fr) rather than 1fr: a long unbroken word in a title would
       otherwise stretch its column past its share and unbalance the row. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.7rem;
  }

  .card {
    padding: 6px 6px 0.85rem;
    border-radius: calc(var(--radius) - 4px);
    /* Backdrop blur costs real frames per element, and this doubles how many
       are on screen at once. Phones stutter scrolling it, so it comes off. */
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .card__media {
    margin-bottom: 0.55rem;
    border-radius: calc(var(--radius) - 10px);
  }

  .card__body {
    padding: 0 0.25rem;
    gap: 0.3rem;
  }

  /* Titles in this catalog run to 68 characters. At full size in a 165px card
     that is six lines, one card becomes twice the height of its neighbour and
     the rows stop lining up. Two lines, then ellipsis. */
  .card__title {
    font-size: 0.82rem;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .card__price {
    font-size: 0.78rem;
  }

  .card__count {
    right: 0.35rem;
    bottom: 0.35rem;
    padding: 0.2rem 0.45rem;
    font-size: 0.56rem;
    letter-spacing: 0.06em;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .card__sold {
    font-size: 0.6rem;
    letter-spacing: 0.1em;
  }

  /* The page heading above the grid eats most of the first screen, so the
     catalog starts below the fold. Tighten it so products are visible on
     arrival, which is the whole point of a catalog page. */
  .page-head {
    padding-block: var(--s3) var(--s2);
  }

  .page-head h1 {
    font-size: clamp(1.9rem, 10vw, 2.6rem);
  }

  .band-head {
    margin-bottom: var(--s2);
  }
}

/* Very narrow phones still get two columns — a 320px screen leaves about 140px
   a card, which is tight but still a grid rather than a queue. */
@media (max-width: 360px) {
  .grid { gap: 0.55rem; }
  .card__title { font-size: 0.78rem; }
}

/* ----------------------------------------------------------- filters ---- */
/*
   Fifteen pieces in one flat grid reads as a pile. The same fifteen behind five
   chips reads as a shop with a range — which it is: pens, wall pieces, things
   for a car, desk pieces, keychains.

   Rendered from the categories actually present, so a chip never leads to an
   empty grid, and the whole bar disappears if there is only one kind left.
*/
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.85rem;
}

.filters:empty { display: none; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper-raised);
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-size: 0.8rem;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}

.chip:hover {
  color: var(--ink);
  border-color: var(--holo-ink);
  transform: translateY(-1px);
}

.chip.is-on {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.chip__count {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  opacity: 0.65;
}

.filters__note {
  margin: 0 0 var(--s2);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ---------------------------------------------------------- swatches ---- */
/*
   The designs, shown instead of counted. A card that says "8 designs" is
   hiding the reason to look; four thumbnails and a remainder is the reason
   itself. Decorative, so it is aria-hidden — the count already reads on the
   photograph and every design is named on the piece's own page.
*/
.swatches {
  display: flex;
  gap: 0.3rem;
  margin: 0.15rem 0 0.1rem;
}

.swatch {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 7px;
  overflow: hidden;
  flex: 0 0 auto;
  border: 1px solid var(--line-soft);
  background: var(--aurora);
}

.swatch img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.swatch.is-gone { opacity: 0.35; }

.swatch--more {
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  color: var(--ink-soft);
  background: transparent;
}

@media (max-width: 560px) {
  .swatches { gap: 0.22rem; margin-top: 0.1rem; }
  .swatch { width: 1.6rem; height: 1.6rem; border-radius: 5px; }
  .swatch--more { font-size: 0.5rem; }

  .chip {
    padding: 0.42rem 0.7rem;
    font-size: 0.74rem;
  }

  .filters {
    /* One scrollable row rather than three stacked ones eating the screen
       before any product is visible. */
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin-inline: calc(var(--s3) * -1);
    padding-inline: var(--s3);
  }

  .filters::-webkit-scrollbar { display: none; }
  .chip { flex: 0 0 auto; }
}

/* ------------------------------------------------------- bag add-ons ---- */
/*
   Postage is charged once per order and is already in the total by the time
   anyone reads this, so a small piece added here really does cost only the
   piece. That is worth saying plainly - it is the honest version of the
   nudge, and it happens to be the persuasive one.
*/
.addons {
  margin-top: var(--s4);
  padding-top: var(--s3);
  border-top: 1px solid var(--line);
}

.addons__why {
  margin: 0 0 var(--s2);
  color: var(--ink-soft);
  font-size: 0.9rem;
  text-wrap: pretty;
}

.addons__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.addon {
  display: grid;
  grid-template-columns: 3.2rem 1fr auto;
  align-items: center;
  gap: 0.8rem;
  padding: 0.5rem;
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  background: var(--paper-raised);
}

.addon__media {
  width: 3.2rem;
  height: 3.2rem;
  border-radius: 8px;
  overflow: hidden;
  background: var(--aurora);
  display: block;
}

.addon__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.addon__body {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.addon__title {
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.25;
  /* These titles run long; two lines keeps every row the same height. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.addon__title:hover { color: var(--holo-ink); }

.addon__price {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.addon__btn {
  padding: 0.45rem 0.9rem;
  font-size: 0.78rem;
  white-space: nowrap;
}

@media (max-width: 560px) {
  .addon {
    grid-template-columns: 2.6rem 1fr auto;
    gap: 0.6rem;
  }
  .addon__media { width: 2.6rem; height: 2.6rem; }
  .addon__title { font-size: 0.84rem; }
  .addon__btn { padding: 0.4rem 0.7rem; font-size: 0.72rem; }
}

/* The description now sits below the buy button rather than above it, so it
   needs to read as "more about this" rather than as the next thing to do. */
.detail__desc--after {
  margin-top: var(--s3);
  padding-top: var(--s3);
  border-top: 1px solid var(--line-soft);
}

/* -------------------------------------------- the buy area, made to sell -- */
/*
   What turns a competent page into one that feels worth paying for is not
   decoration, it is answering the questions someone is already asking: how
   long, how much to send it, and who is making it. Every line here is true.

   No countdown, no viewer count, no invented review. Stock on these pieces is
   null - made to order - so a scarcity line would be a lie, and where stock is
   genuinely finite the real number is already shown above the button.
*/
.btn-buy {
  width: 100%;
  justify-content: center;
  padding-block: 0.95rem;
  font-size: 1rem;
}

.assure {
  list-style: none;
  margin: var(--s2) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
}

.assure li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* A tick drawn in CSS rather than an icon file: no extra request, and it keeps
   working when the font does not load. */
.assure li::before {
  content: '';
  width: 0.55rem;
  height: 0.3rem;
  border-left: 1.5px solid var(--holo-ink);
  border-bottom: 1.5px solid var(--holo-ink);
  transform: rotate(-45deg) translateY(-0.1rem);
  flex: 0 0 auto;
}

.assure__maker {
  margin: 0.85rem 0 0;
  padding-top: 0.85rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.assure__maker a {
  color: var(--holo-ink);
  text-decoration: none;
  white-space: nowrap;
}

.assure__maker a:hover { text-decoration: underline; }

/* The price carried the mono face, which reads as a spec sheet. On the piece
   itself it is the number someone is deciding about, so it gets the display
   face and room to be looked at. */
.detail__price {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0.15rem 0 var(--s2);
}

@media (max-width: 560px) {
  .assure { gap: 0.35rem 0.8rem; }
  .assure li { font-size: 0.78rem; }
  .detail__price { font-size: 1.5rem; }
}

/* ------------------------------------- the piece, on one phone screen ---- */
/*
   Everything needed to decide - photograph, the designs, name, price, choose,
   buy - inside one screen, with no scrolling to reach the button.

   What was eating it: the main photograph is 2/3 aspect, which on a 370px
   column is 555px tall before anything else exists; nine design thumbnails
   wrapped onto two rows; and the h1 clamps to a 2.6rem floor, so a long title
   ran to three lines at 42px each.

   The photograph is object-fit: contain, so capping its height shrinks it
   rather than cropping - which matters here, because these are pens standing
   upright and the earlier complaint about this catalog was that their tops
   were being cut off.
*/
@media (max-width: 560px) {
  .detail {
    gap: 0.9rem;
    padding-block: 0.6rem 1.5rem;
  }

  .detail__media {
    padding: 6px;
  }

  .detail__media img {
    /* A share of the screen rather than a shape. Small enough to leave room
       for the decision, large enough to still be the thing you look at. */
    aspect-ratio: auto;
    height: 34vh;
    max-height: 20rem;
    object-fit: contain;
  }

  .thumbs {
    /* One row that scrolls, not two that stack. Nine designs on two rows cost
       150px of a screen that has to hold a decision. */
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 0.4rem;
    margin-top: 0.5rem;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
  }

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

  .thumb {
    flex: 0 0 3.2rem;
    width: 3.2rem;
    scroll-snap-align: start;
  }

  /* The wordmark sits in the header two inches above this. Saying it again
     costs a line of a screen that has none to spare. */
  /* p.label, not .label: the design row contains a span.label too, and hiding
     that would take the word DESIGN with it. */
  .detail > div > p.label:first-child {
    display: none;
  }

  .detail h1 {
    font-size: 1.45rem;
    line-height: 1.15;
    margin-bottom: 0.35rem;
  }

  .detail__price {
    font-size: 1.35rem;
    margin: 0 0 0.6rem;
  }

  .chosen {
    margin-bottom: 0.6rem;
    font-size: 0.9rem;
  }

  .btn-buy {
    padding-block: 0.85rem;
  }

  .assure {
    margin-top: 0.7rem;
  }

  .assure__maker {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    font-size: 0.8rem;
  }

  .detail__desc--after {
    margin-top: 1.2rem;
    padding-top: 1.2rem;
  }
}

/* Short phones - an SE is 667px tall - give the photograph less again rather
   than pushing the button off the bottom. */
@media (max-width: 560px) and (max-height: 720px) {
  .detail__media img { height: 26vh; }
  .thumb { flex-basis: 2.8rem; width: 2.8rem; }
  .detail h1 { font-size: 1.3rem; }
}

/* --------------------------------------------- stop the page overflowing -- */
/*
   A grid item's automatic minimum size is its content, not zero. So the
   thumbnail row - nine fixed-width thumbs that deliberately do not wrap -
   pushed its track wider than the screen, and because both tracks are 1fr the
   whole layout went with it: the title, the button label, the assurance strip
   and every line of the description were clipped at the same right edge, and
   the photograph sat off-centre with dead space beside it because contain
   centres inside a box wider than the viewport.

   body { overflow-x: hidden } was only hiding it. min-width: 0 is the fix:
   it lets the track shrink and lets the thumbnail row scroll inside itself,
   which is what it was always meant to do.
*/
.detail > *,
.gallery,
.thumbs,
.assure,
.chosen {
  min-width: 0;
}

.gallery,
.detail__media,
.detail__desc {
  max-width: 100%;
}

/* ------------------------------------------- the piece, looking its best -- */
@media (max-width: 560px) {
  /* The white frame hugs the photograph instead of being a full-width box with
     a portrait image floating in the middle of it. Centred, so it reads as a
     deliberate frame rather than a gap. */
  .detail__media {
    width: fit-content;
    max-width: 100%;
    margin-inline: auto;
    display: grid;
    place-items: center;
  }

  .detail__media img {
    width: auto;
    max-width: 100%;
    height: 34vh;
    max-height: 19rem;
    object-fit: contain;
  }

  /* Centred under a centred photograph. justify-content rather than a margin,
     so a row too wide to fit still starts at the left edge and scrolls. */
  .thumbs {
    justify-content: safe center;
  }

  /* "CHOOSE A DESIGN FIRST" in caps with letter-spacing is a long label on a
     narrow screen; it was being clipped rather than wrapped. */
  .btn-buy {
    font-size: 0.82rem;
    letter-spacing: 0.06em;
    white-space: normal;
    line-height: 1.3;
  }

  /* Three facts on one line do not fit. Two columns reads as a list rather
     than as a sentence that ran out of room. */
  .assure {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.3rem 0.7rem;
  }

  .assure li { font-size: 0.75rem; }
}

/* --------------------------------------------------------- catalog head -- */
/*
   The heading was three lines of display type and a paragraph, which pushed
   the first product most of a screen down. A shop should open on the things
   it sells.
*/
.catalog-head {
  padding-block: var(--s4) var(--s2);
}

.catalog-head h1 {
  margin: 0;
  font-size: clamp(2.4rem, 7vw, 4rem);
}

/* -------------------------------------------------------------- our picks */
.picks {
  padding-block: var(--s2) var(--s3);
}

.picks[hidden] { display: none; }

.picks__head h2 {
  margin: 0 0 0.15rem;
  font-size: clamp(1.3rem, 4vw, 1.8rem);
}

.picks__head p {
  margin: 0 0 var(--s2);
  color: var(--ink-soft);
  font-size: 0.88rem;
}

/*
   The mask is what makes a card look like it swooshes in and out: it arrives
   out of nothing at the left edge, is solid across the middle, and dissolves
   again on the right, so the row has no visible start or end.
*/
.picks__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent 0,
    #000 9%,
    #000 91%,
    transparent 100%
  );
  mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%);
}

.picks__track {
  --picks-duration: 48s;
  display: flex;
  gap: var(--s2);
  width: max-content;
  padding-block: 0.35rem;
  animation: pick-drift var(--picks-duration) linear infinite;
}

.picks__copy {
  display: flex;
  gap: var(--s2);
  /* No margin: the track's own gap already separates the two copies, and a
     margin on top of it would make the seam twice as wide as every other
     gap - visible once a cycle, which is exactly when it is most obvious. */
}

/*
   The track holds the list twice, so half its width is eight cards and seven
   gaps - but a full set is eight cards and EIGHT gaps, counting the one that
   separates it from the copy. Hence the extra half-gap: without it the row
   creeps backwards by half a gap every cycle and the drift visibly stutters.
*/
@keyframes pick-drift {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(calc(-50% - var(--s2) / 2), 0, 0); }
}

/* Stop it while someone is reading or reaching for a card. */
.picks__viewport:hover .picks__track,
.picks__track:focus-within {
  animation-play-state: paused;
}

.pick {
  flex: 0 0 11.5rem;
  width: 11.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  text-decoration: none;
  color: inherit;
  transition: transform 0.35s cubic-bezier(0.2, 0.9, 0.3, 1);
}

.pick:hover { transform: translateY(-4px); }

.pick__media {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius);
  overflow: hidden;
  background: linear-gradient(150deg, var(--aurora), var(--lilac));
  border: 1px solid var(--line-soft);
}

.pick__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.pick__count {
  position: absolute;
  right: 0.45rem;
  bottom: 0.45rem;
  padding: 0.2rem 0.45rem;
  border-radius: 999px;
  background: rgba(13, 42, 49, 0.62);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.06em;
}

.pick__title {
  font-weight: 600;
  font-size: 0.85rem;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pick__price {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
}

@media (max-width: 560px) {
  .catalog-head { padding-block: var(--s3) 0.4rem; }
  .picks { padding-block: 0.4rem var(--s2); }
  .pick { flex-basis: 8.5rem; width: 8.5rem; }
  .pick__title { font-size: 0.78rem; }
}

/*
   Anyone who has asked their system for less motion gets a row that simply
   sits still and scrolls by hand. A drifting carousel is exactly the kind of
   thing that setting exists for.
*/
@media (prefers-reduced-motion: reduce) {
  .picks__track {
    animation: none;
    width: auto;
    overflow-x: auto;
  }

  .picks__copy { display: none; }
}
