/* ============================================================
   MEKAN TEXTILE - fx.css
   The loud layer on top of the Linen system. Where Linen is the
   finished cloth, this is the mill: indigo from the dye vat, weld
   yellow from the shuttle, and machinery that moves.
   Loaded after main.css; only overrides what it has to.
   ============================================================ */

:root {
  --indigo-deep: #0c1325;
  --indigo:      #16213d;
  --indigo-mid:  #22335e;
  --ecru:        #ece4d0;
  --weld:        #d9b44a;
  --weld-deep:   #a8842b;
  --madder:      #b0402f;

  --ease-cloth: cubic-bezier(.65, 0, .35, 1);
  --ease-snap:  cubic-bezier(.16, 1, .3, 1);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}


/* ============================================================
   COVER
   The warehouse fills the screen and stays pinned while the site
   slides up over it. --cp is how far the site has risen (0 to 1),
   set by fx.js; the picture draws back and darkens, the words lift
   away, and the page snaps to whichever side you are nearer.
   ============================================================ */
html { scroll-snap-type: y proximity; }
.cover {
  position: sticky;
  top: 0;
  z-index: 0;
  height: 100svh;
  min-height: 34rem;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  background: var(--indigo-deep);
  color: var(--ecru);
  scroll-snap-align: start;
}
.cover.is-under { visibility: hidden; }
.cover-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 65% 50%;
  transform-origin: 50% 50%;
  transform: scale(calc(1 + var(--cp, 0) * .08));
  filter: brightness(calc(1 - var(--cp, 0) * .45));
  animation: coverSettle 1.6s var(--ease) both;
}
@keyframes coverSettle {
  from { transform: scale(1.05); filter: brightness(.6); }
}
/* On a phone held upright the photo is two and a half times wider than
   the screen is, so filling the height would leave a fifth of it. The
   photo spans the full width instead, so the whole warehouse shows,
   racks, trolley, forklift and all, and the screen around it fills
   with the same warehouse, blurred and dimmed. */
@media (max-aspect-ratio: 4/5) {
  .cover::before {
    content: "";
    position: absolute;
    inset: -6%;
    background: url("../assets/img/band-warehouse.jpg?v=3") 50% 50% / cover no-repeat;
    filter: blur(20px) brightness(.78);
  }
  .cover-img {
    inset: auto 0;
    top: calc(50% - 100vw * 799 / 1967 / 2);
    height: calc(100vw * 799 / 1967);
    object-fit: contain;
    box-shadow: 0 24px 60px rgba(12, 19, 37, .45);
  }
}
.cover-shade {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(12, 19, 37, .7) 0%, rgba(12, 19, 37, .2) 28%, rgba(12, 19, 37, 0) 55%, rgba(12, 19, 37, .3) 100%);
}
/* a thread drops at the foot: the way in */
.cover-cue {
  /* centred by margins, not a transform: riseIn below animates the
     transform and would undo a translateX(-50%), leaving the cue off
     to the right. The left padding balances the letter-spacing the
     last letter trails. */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2rem;
  width: max-content;
  margin-inline: auto;
  padding-left: .16em;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ecru);
  text-shadow: 0 1px 12px rgba(12, 19, 37, .6);
  opacity: calc(1 - var(--cp, 0) * 3);
  animation: riseIn 1s var(--ease) 1.2s both;
}
.cover-cue i {
  width: 1px;
  height: 3.2rem;
  background: linear-gradient(var(--weld), transparent);
  transform-origin: top;
  animation: cueDrop 1.9s var(--ease) infinite;
}
@keyframes cueDrop {
  0% { transform: scaleY(0); opacity: 0; }
  35% { opacity: 1; }
  100% { transform: scaleY(1); opacity: 0; }
}
/* the site is a sheet that rises over the cover */
.site-header { scroll-snap-align: start; }
main { background: var(--paper); }

/* ============================================================
   HEADER, WORN OVER THE PRESS
   ============================================================ */
.site-header.on-press {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
  color: var(--ecru);
}
.site-header.on-press.scrolled {
  background: rgba(12, 19, 37, .62);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom-color: rgba(236, 228, 208, .12);
}
.site-header.on-press .main-nav,
.site-header.on-press .lang-btn { color: rgba(236, 228, 208, .72); }
.site-header.on-press .main-nav a:hover,
.site-header.on-press .lang-btn:hover,
.site-header.on-press .main-nav a.is-current { color: var(--ecru); }
.site-header.on-press .main-nav a::after { background: var(--weld); }
.site-header.on-press .menu-toggle span { background: var(--ecru); }
.site-header.on-press .btn-primary { background: var(--ecru); color: var(--indigo-deep); }
.site-header.on-press .btn-primary:hover { background: var(--weld); color: var(--indigo-deep); }
.site-header.on-press .scroll-thread { background: var(--weld); }
.site-header.on-press .brand-logo { box-shadow: 0 0 0 1px rgba(236, 228, 208, .25); }

/* the language menu is a white card, so it keeps ink-coloured text
   even while the header around it wears the press's pale colours */
.lang-menu { color: var(--ink); }
.lang-menu li { color: var(--ink); font-weight: 500; }
.lang-menu li:hover { color: var(--ink); }
.lang-menu li[aria-selected="true"],
.lang-menu li[aria-selected="true"]:hover { color: var(--paper); }

/* the products menu is a white card too */
.site-header.on-press .nav-menu a,
.site-header.on-press .nav-menu a:hover { color: var(--ink); }
.site-header.on-press .nav-group-title { color: var(--ink-faint); }

/* the mobile menu is paper, so the header goes back to paper with it */
.site-header.on-press:has(~ .mobile-menu.open) {
  background: var(--paper);
  color: var(--ink);
}
.site-header.on-press:has(~ .mobile-menu.open) .menu-toggle span { background: var(--ink); }

/* ============================================================
   HERO: THE PRESS
   ============================================================ */
.hero { padding: 0; text-align: left; }

.press {
  --strip: 3.5rem;         /* room for the job readout at the foot */
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: max(38rem, 100svh);
  margin-top: calc(-1 * var(--header-h, 72px));
  padding: calc(var(--header-h, 72px) + clamp(1.5rem, 5vh, 3.5rem)) var(--gutter) calc(var(--strip) + clamp(2.5rem, 7vh, 5rem));
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--indigo-deep);
  color: var(--ecru);
}

.press-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -2;
  display: block;
}

/* ink-dark ground behind the words, falling away so the print
   carries the right of the screen */
.press-shade {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(12, 19, 37, .94) 0%, rgba(12, 19, 37, .88) 22%, rgba(12, 19, 37, .48) 42%, rgba(12, 19, 37, 0) 60%),
    linear-gradient(to bottom, rgba(12, 19, 37, .8), rgba(12, 19, 37, .35) 12%, transparent 26%);
}

/* the words stand at the left edge of the cloth, not in a centred
   column, so the print has the rest of the width */
.press .hero-inner {
  position: relative;
  width: 100%;
  max-width: none;
  margin: 0;
  padding-left: clamp(0rem, 4vw - 1.25rem, 2.75rem);
  opacity: 1;
  animation: none;
}
.press-copy { max-width: 40rem; }

.press .hero-eyebrow {
  justify-content: flex-start;
  color: var(--weld);
  opacity: 0;
  animation: riseIn .9s var(--ease) .05s forwards;
}
.press .hero-eyebrow::before { display: none; }
.press .hero-eyebrow::after { border-top-color: var(--weld); }

.press .hero-title {
  font-size: clamp(3rem, min(7.4vw, 11vh), 6.6rem);
  line-height: .92;
  letter-spacing: -.035em;
  margin-bottom: clamp(1.1rem, 2.4vh, 1.8rem);
  text-wrap: initial;
}
.hero-title .ln { display: block; }
.hero-title .ln-em { font-style: italic; letter-spacing: -.02em; color: var(--weld); }

/* each letter lands like a drop from the head: out of focus, then sharp */
.w { display: inline-block; white-space: nowrap; }
.hero-title .ch {
  display: inline-block;
  opacity: 0;
  transform: translateX(-.35em) scale(1.08);
  filter: blur(10px);
  animation: pickIn 1s var(--ease-snap) forwards;
  animation-delay: calc(var(--d, 0ms) + var(--i) * 28ms);
}
.hero-title .ln:nth-child(2) { --d: 260ms; }
.hero-title .ln:nth-child(3) { --d: 520ms; }

.press .hero-sub {
  font-size: clamp(1rem, 1.1vw + .4rem, 1.12rem);
  margin: 0 0 clamp(1.4rem, 3vh, 2.2rem);
  color: rgba(236, 228, 208, .8);
  max-width: 46ch;
  opacity: 0;
  animation: riseIn 1s var(--ease) 1.25s forwards;
}
.press .hero-ctas {
  justify-content: flex-start;
  opacity: 0;
  animation: riseIn 1s var(--ease) 1.45s forwards;
}

/* the carriage's display, sat on the bare cloth at the foot */
.press-readout {
  position: absolute;
  right: var(--gutter);
  bottom: 1.2rem;
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .7rem 1.1rem;
  border-radius: 999px;
  background: rgba(236, 228, 208, .86);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 10px 30px -12px rgba(6, 8, 18, .55);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(12, 19, 37, .72);
  font-variant-numeric: tabular-nums;
}
.pr-inks { display: flex; gap: 3px; }
.pr-inks i { width: .55rem; height: .55rem; border-radius: 50%; background: var(--c); }
.pr-pass { min-width: 7.5ch; }
.pr-job { white-space: nowrap; }

.btn-weld { background: var(--weld); color: var(--indigo-deep); }
.btn-weld:hover { background: var(--ecru); color: var(--indigo-deep); box-shadow: 0 16px 34px -14px rgba(217, 180, 74, .7); }
.btn-weld::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .45) 50%, transparent 62%);
  transform: translateX(-130%);
  transition: transform .8s var(--ease);
}
.btn-weld:hover::after { transform: translateX(130%); }

.btn-ghost-light { border: 1px solid rgba(236, 228, 208, .38); color: var(--ecru); }
.btn-ghost-light:hover { border-color: var(--ecru); color: var(--ecru); background: rgba(236, 228, 208, .08); }

[data-magnetic] {
  transition:
    background .3s var(--ease),
    color .3s var(--ease),
    border-color .3s var(--ease),
    transform .3s var(--ease),
    box-shadow .3s var(--ease),
    translate .35s var(--ease-snap);
}

.hero-band { margin-top: clamp(3rem, 7vw, 5rem); padding-inline: var(--gutter); }

/* ============================================================
   RIBBONS
   ============================================================ */
.marquee {
  margin-top: clamp(3rem, 7vw, 5.5rem);
  padding-block: clamp(2rem, 5vw, 3.5rem);
  border: 0;
  overflow: hidden;
}

.ribbon {
  position: relative;
  width: 112%;
  margin-left: -6%;
  padding-block: clamp(.7rem, 1.6vw, 1.1rem);
  overflow: hidden;
}
.ribbon::before {
  content: "";
  position: absolute;
  inset: 5px 0;
  pointer-events: none;
  border-top: 1px dashed currentColor;
  border-bottom: 1px dashed currentColor;
  opacity: .35;
}
.ribbon-warp {
  z-index: 2;
  background: var(--indigo);
  color: var(--ecru);
  transform: rotate(-2.6deg);
  box-shadow: 0 22px 40px -24px rgba(12, 19, 37, .7);
}
.ribbon-weft {
  z-index: 1;
  margin-top: clamp(-2.6rem, -3.5vw, -1.6rem);
  background: var(--weld);
  color: var(--indigo-deep);
  transform: rotate(2deg);
}

.ribbon .marquee-track {
  gap: clamp(1.4rem, 3vw, 2.4rem);
  will-change: transform;
}
.ribbon-weft .marquee-track { animation-direction: reverse; }
.marquee.js-marquee .marquee-track { animation: none; }

.ribbon .marquee-track span {
  font-family: var(--serif);
  font-size: clamp(1.7rem, 4vw, 3.3rem);
  line-height: 1.1;
  color: inherit;
}
.ribbon-weft .marquee-track span { font-style: italic; }
.ribbon .marquee-track i {
  font-style: normal;
  font-size: clamp(1rem, 2vw, 1.6rem);
  color: inherit;
  opacity: .55;
}

/* ============================================================
   READ-THROUGH LEAD
   ============================================================ */
.read-scrub .w {
  color: rgba(42, 42, 39, .16);
  transition: color .45s var(--ease);
}
.read-scrub .w.lit { color: var(--ink); }
.about-copy .read-scrub {
  font-family: var(--serif);
  font-size: clamp(1.6rem, 3vw, 2.3rem);
  line-height: 1.25;
  letter-spacing: -.01em;
  margin-bottom: 1.6rem;
}

/* ============================================================
   RUNNING STITCH UNDER SECTION TITLES
   Sewn in stitch by stitch once the title has landed.
   ============================================================ */
.section-head .section-title::after,
.dye-copy .section-title::after {
  content: "";
  display: block;
  width: 0;
  height: 2px;
  margin: 1.1rem auto 0;
  background: repeating-linear-gradient(90deg, var(--sage) 0 11px, transparent 11px 17px);
  transition: width 1.1s steps(7, end) calc(var(--rd, 0ms) + .7s);
}
.section-head .section-title.in::after,
.dye-copy .section-title.in::after { width: 119px; }
.dye-copy .section-title::after { margin-left: 0; }
.printing .section-title::after { background: repeating-linear-gradient(90deg, var(--weld) 0 11px, transparent 11px 17px); }

/* ============================================================
   PRODUCT FRAMES OPEN AS THEY ARRIVE
   ============================================================ */
@supports (animation-timeline: view()) {
  .fx:not(.fx-still) .product-visual .visual-frame {
    animation: frameOpen linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 42%;
  }
  .fx:not(.fx-still) .warp-band {
    animation: boltUnroll linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 50%;
  }
  .fx:not(.fx-still) .stat {
    animation: statLift linear both;
    animation-timeline: view();
    animation-range: entry 10% cover 35%;
  }
}
@keyframes frameOpen {
  from { scale: .84; rotate: -1.5deg; }
  to   { scale: 1; rotate: 0deg; }
}
@keyframes boltUnroll {
  from { clip-path: inset(0 22% 0 22% round 4px); }
  to   { clip-path: inset(0 0 0 0 round 0); }
}
@keyframes statLift {
  from { translate: 0 40px; }
  to   { translate: 0 0; }
}

/* ============================================================
   DYE HOUSE
   ============================================================ */
.bg-filters { margin-bottom: 1.2rem; }

.dye-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.dye-copy .lead { margin-bottom: 2rem; }

.dye-vat {
  position: relative;
  aspect-ratio: 5 / 4;
  border-radius: 3px;
  overflow: hidden;
  box-shadow: 0 30px 60px -34px rgba(12, 19, 37, .55);
  color: var(--ink-on, var(--paper));
}

.vat-layer {
  position: absolute;
  inset: 0;
  transition: background .6s var(--ease);
}
.vat-new {
  clip-path: circle(0% at var(--x, 50%) var(--y, 50%));
  transition: none;
}
.vat-new.spread {
  clip-path: circle(150% at var(--x, 50%) var(--y, 50%));
  transition: clip-path 1.2s var(--ease-cloth);
}

/* the canvas weave, and the light across its folds */
.vat-weave {
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(0deg,  rgba(255, 255, 255, .10) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .14) 0 1px, transparent 1px 3px);
  mix-blend-mode: overlay;
}
.vat-fold {
  position: absolute;
  inset: -20%;
  background:
    linear-gradient(100deg,
      rgba(255, 255, 255, .16) 0%, transparent 18%,
      rgba(0, 0, 0, .22) 34%, transparent 46%,
      rgba(255, 255, 255, .12) 60%, transparent 72%,
      rgba(0, 0, 0, .18) 88%, transparent 100%);
  background-size: 160% 100%;
  animation: foldDrift 9s ease-in-out infinite alternate;
}

.vat-tag {
  position: absolute;
  left: 1.2rem;
  bottom: 1.2rem;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  padding: .8rem 1rem .75rem;
  background: var(--paper);
  color: var(--ink);
  border-radius: 2px;
  box-shadow: var(--shadow-tag);
  transform-origin: 50% -1.2rem;
  animation: tagSway 5s ease-in-out infinite alternate;
}
/* the tag hangs from a loop of thread */
.vat-tag::before {
  content: "";
  position: absolute;
  top: -1.2rem;
  left: 50%;
  width: 1px;
  height: 1.2rem;
  background: var(--ink-faint);
}
.vat-shade { font-family: var(--serif); font-size: 1.5rem; line-height: 1; }
.vat-shade b { font-weight: 400; display: inline-block; font-variant-numeric: tabular-nums; }
.vat-shade b.flip { animation: numFlip .6s var(--ease-snap); }
.vat-name { font-family: var(--serif); font-style: italic; font-size: 1.05rem; color: var(--ink-soft); }
.vat-spec { font-size: .78rem; color: var(--ink-soft); }

.dye-wall {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(.9rem, 1.6vw, 1.2rem) clamp(.45rem, 1vw, .75rem);
}

.dye-chip {
  --lift: 0;
  --tilt: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: .4rem;
  text-align: left;
  transform-origin: 50% 0;
  translate: 0 calc(var(--lift) * -12px);
  scale: calc(1 + var(--lift) * .1);
  rotate: calc(var(--tilt) * 1deg);
  transition: translate .35s var(--ease-snap), scale .35s var(--ease-snap), rotate .5s var(--ease-snap);
  animation: swatchSway 3.6s ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -170ms);
  cursor: pointer;
}
/* the cut piece of canvas itself */
.dye-cloth {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  background:
    repeating-linear-gradient(0deg,  rgba(255, 255, 255, .10) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .12) 0 1px, transparent 1px 3px),
    linear-gradient(160deg, rgba(255, 255, 255, .18), transparent 45%, rgba(0, 0, 0, .18)),
    var(--c);
  /* pinking-shear teeth along the foot of each swatch */
  -webkit-mask:
    linear-gradient(#000 0 0) top / 100% calc(100% - 5px) no-repeat,
    conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) bottom / 10px 5px repeat-x;
          mask:
    linear-gradient(#000 0 0) top / 100% calc(100% - 5px) no-repeat,
    conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) bottom / 10px 5px repeat-x;
}
.dye-cloth::after {
  content: attr(data-n);
  position: absolute;
  top: .35rem;
  left: .4rem;
  font-size: .7rem;
  font-variant-numeric: tabular-nums;
  color: #fff;
  mix-blend-mode: difference;
  opacity: 0;
  transition: opacity .3s var(--ease);
}
.dye-chip:hover .dye-cloth::after,
.dye-chip[aria-checked="true"] .dye-cloth::after { opacity: .9; }
/* the colour's name, written under the swatch like a card label */
.dye-name {
  display: block;
  font-size: .72rem;
  line-height: 1.25;
  color: var(--ink-soft);
  hyphens: auto;
  overflow-wrap: break-word;
}
.dye-chip[aria-checked="true"] .dye-cloth { box-shadow: inset 0 0 0 2px var(--paper), inset 0 0 0 3px var(--ink); }
.dye-chip[aria-checked="true"] .dye-name { color: var(--ink); font-weight: 600; }
.dye-chip[aria-checked="true"] { translate: 0 -8px; }
.dye-chip:focus-visible { outline-offset: 2px; }

/* the wall comes in as a card being unfolded, row by row */
.dye-wall.reveal .dye-chip { opacity: 0; translate: 0 -24px; }
.dye-wall.reveal.in .dye-chip {
  opacity: 1;
  translate: 0 calc(var(--lift) * -12px);
  transition:
    opacity .7s var(--ease) calc(var(--i) * 28ms),
    translate .9s var(--ease-snap) calc(var(--i) * 28ms),
    scale .35s var(--ease-snap),
    rotate .5s var(--ease-snap);
}
.dye-wall.reveal.in .dye-chip[aria-checked="true"] { translate: 0 -8px; }
.dye-wall.reveal.in.settled .dye-chip { transition: translate .35s var(--ease-snap), scale .35s var(--ease-snap), rotate .5s var(--ease-snap); }

/* ============================================================
   PRINTING: THE HEAD PASSES, THE CLOTH IS PRINTED
   The first two samples are revealed by a digital print head
   sweeping across; the third by a rotary screen rolling down.
   ============================================================ */
.tech-card:nth-child(-n+2) .print-sample.reveal-cloth {
  -webkit-mask-image: linear-gradient(to right, #000 50%, transparent 50%);
          mask-image: linear-gradient(to right, #000 50%, transparent 50%);
  -webkit-mask-size: 200% 300%;
          mask-size: 200% 300%;
  -webkit-mask-position: 100% 50%;
          mask-position: 100% 50%;
  transition:
    -webkit-mask-position 1.7s var(--ease-cloth) var(--rd, 0ms),
    mask-position 1.7s var(--ease-cloth) var(--rd, 0ms);
}
.tech-card:nth-child(-n+2) .print-sample.reveal-cloth.in {
  -webkit-mask-position: 0% 50%;
          mask-position: 0% 50%;
}
.tech-card:nth-child(3) .print-sample.reveal-cloth {
  transition:
    -webkit-mask-position 1.7s var(--ease-cloth) var(--rd, 0ms),
    mask-position 1.7s var(--ease-cloth) var(--rd, 0ms);
}

.print-sample::before {
  content: "";
  position: absolute;
  z-index: 2;
  pointer-events: none;
}
/* digital head: a strip of CMYK nozzles with a lamp behind it */
.tech-card:nth-child(-n+2) .print-sample::before {
  top: 0;
  bottom: 0;
  left: 0;
  width: 16px;
  translate: -100% 0;
  background:
    linear-gradient(90deg, transparent, rgba(255, 255, 255, .85) 70%, #fff),
    repeating-linear-gradient(180deg, #00a3c7 0 5px, #d31f79 5px 10px, #f4cf0b 10px 15px, #1d1d1b 15px 20px);
  background-size: 10px 100%, 6px 100%;
  background-position: 0 0, 100% 0;
  background-repeat: no-repeat;
  box-shadow: 0 0 22px 6px rgba(255, 255, 255, .5);
  transition: left 1.7s var(--ease-cloth) var(--rd, 0ms), opacity .4s var(--ease) calc(var(--rd, 0ms) + 1.6s);
}
.tech-card:nth-child(-n+2) .print-sample.in::before { left: 100%; opacity: 0; }

/* rotary: an engraved cylinder rolling down the cloth */
.tech-card:nth-child(3) .print-sample::before {
  left: -4%;
  right: -4%;
  top: 0;
  height: 22px;
  translate: 0 -100%;
  border-radius: 11px;
  background:
    radial-gradient(circle, rgba(0, 0, 0, .35) 1px, transparent 1.4px) 0 0 / 5px 5px,
    linear-gradient(180deg, #4d4d48, #e9e6de 38%, #a9a69d 62%, #2e2e2b);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
  transition: top 1.7s var(--ease-cloth) var(--rd, 0ms), opacity .4s var(--ease) calc(var(--rd, 0ms) + 1.6s);
}
.tech-card:nth-child(3) .print-sample.in::before { top: 100%; opacity: 0; }

/* ============================================================
   THE DARK PASSAGES ARE INDIGO
   The loom band, Printing and the closing band were forest green in
   Linen; they now share the indigo of the hero, the stats and the
   contact label, so the page has one dark colour.
   ============================================================ */
.warp-band,
.printing { background: var(--indigo); }
.btn-light,
.btn-light:hover { color: var(--indigo); }

.photo-credits {
  margin-top: clamp(2rem, 4vw, 3rem);
  font-size: .72rem;
  line-height: 1.6;
  color: rgba(236, 228, 208, .45);
}
.photo-credits a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.photo-credits a:hover { color: var(--ecru); }
.photo-credits--light { margin-top: .6rem; text-align: center; color: var(--ink-faint); }
.photo-credits--light a:hover { color: var(--ink); }

/* ============================================================
   FOOTER WORDMARK
   ============================================================ */
.footer-mark {
  position: relative;
  overflow: hidden;
  padding: clamp(1.5rem, 4vw, 3rem) var(--gutter) clamp(.6rem, 1.5vw, 1.2rem);
  font-family: var(--serif);
  font-size: clamp(3.6rem, 16.5vw, 17rem);
  line-height: .78;
  letter-spacing: -.045em;
  text-align: center;
  white-space: nowrap;
  color: var(--indigo);
  user-select: none;
}
.footer-mark .ch {
  display: inline-block;
  translate: 0 100%;
  transition: translate 1.1s var(--ease-snap) calc(var(--i) * 45ms);
}
.footer-mark.in .ch { translate: 0 0; }
.footer-mark .ch:hover { color: var(--weld-deep); translate: 0 -6%; transition-duration: .3s; transition-delay: 0s; }

/* ============================================================
   PINKED EDGES
   The dark bands are cut with pinking shears top and bottom, the
   way a sample is cut so it cannot fray.
   ============================================================ */
.about-stats {
  --tooth: 9px;
  -webkit-mask:
    conic-gradient(from 135deg at top, #0000, #000 1deg 89deg, #0000 90deg) top / calc(var(--tooth) * 2) var(--tooth) repeat-x,
    linear-gradient(#000 0 0) 0 var(--tooth) / 100% calc(100% - var(--tooth) * 2) no-repeat,
    conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) bottom / calc(var(--tooth) * 2) var(--tooth) repeat-x;
          mask:
    conic-gradient(from 135deg at top, #0000, #000 1deg 89deg, #0000 90deg) top / calc(var(--tooth) * 2) var(--tooth) repeat-x,
    linear-gradient(#000 0 0) 0 var(--tooth) / 100% calc(100% - var(--tooth) * 2) no-repeat,
    conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) bottom / calc(var(--tooth) * 2) var(--tooth) repeat-x;
}

/* ============================================================
   THE NUMBERS, ON A BAND OF INDIGO
   ============================================================ */
.about-stats {
  position: relative;
  max-width: none;
  margin-inline: calc(-1 * var(--bleed));
  padding: clamp(3.4rem, 7vw, 5rem) var(--bleed);
  gap: 0;
  border: 0;
  background:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .035) 0 2px, transparent 2px 5px),
    var(--indigo);
  color: var(--ecru);
}
.about-stats .stat {
  position: relative;
  padding-inline: 1rem;
}
/* stitched seams between the figures, sewn in as they arrive */
.about-stats .stat + .stat::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8%;
  bottom: 8%;
  border-left: 1px dashed rgba(236, 228, 208, .3);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 1s steps(10, end) calc(var(--rd, 0ms) + .3s);
}
.about-stats .stat.in + .stat.in::before { transform: scaleY(1); }
.about-stats .stat-value {
  font-size: clamp(3.4rem, 7.5vw, 6.4rem);
  letter-spacing: -.03em;
  color: var(--ecru);
  margin-bottom: .8rem;
}
.about-stats .stat-label {
  display: block;
  max-width: 18ch;
  margin-inline: auto;
  color: rgba(236, 228, 208, .68);
}

/* ============================================================
   THE PICK GLASS
   A folding brass linen tester over the cloth, with its scale.
   ============================================================ */
.fabric-lab {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.25fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}

.pickglass {
  position: sticky;
  top: calc(var(--header-h, 72px) + 1.5rem);
  margin: 0;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 3px;
  background: var(--indigo-deep);
  box-shadow: var(--shadow-card);
  cursor: crosshair;
  touch-action: pan-y;
}

.pg-cloth {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
}
.pg-next { clip-path: inset(0 100% 0 0); }
.pg-next.wipe { clip-path: inset(0 0 0 0); transition: clip-path .9s var(--ease-cloth); }

.pg-lens {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;
  width: clamp(120px, 42%, 180px);
  aspect-ratio: 1;
  border-radius: 5px;
  overflow: hidden;
  pointer-events: none;
  will-change: transform;
  box-shadow:
    0 0 0 5px #c9a55a,
    0 0 0 6px #7d6128,
    0 0 0 8px rgba(12, 19, 37, .25),
    0 28px 44px -12px rgba(0, 0, 0, .65);
}
.pg-lens-cloth {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
}
/* the etched scale along one edge, and the fine crosshair */
.pg-lens::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 16px;
  z-index: 2;
  background:
    repeating-linear-gradient(90deg, rgba(20, 16, 8, .8) 0 1px, transparent 1px 30px) left bottom / 100% 14px no-repeat,
    repeating-linear-gradient(90deg, rgba(20, 16, 8, .7) 0 1px, transparent 1px 6px) left bottom / 100% 7px no-repeat;
}
.pg-lens::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(rgba(255, 255, 255, .28), rgba(255, 255, 255, .28)) center / 1px 30% no-repeat,
    linear-gradient(rgba(255, 255, 255, .28), rgba(255, 255, 255, .28)) center / 30% 1px no-repeat,
    radial-gradient(120% 120% at 30% 20%, rgba(255, 255, 255, .16), transparent 45%);
}

.pg-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 3rem 1.2rem 1rem;
  background: linear-gradient(to top, rgba(12, 19, 37, .8), transparent);
  color: var(--ecru);
  pointer-events: none;
}
.pg-name { font-family: var(--serif); font-size: 1.6rem; line-height: 1; }
.pg-meta { font-size: .82rem; opacity: .8; font-variant-numeric: tabular-nums; }

/* beside the glass the photograph does the swatch's job, so the table
   drops its swatch column and fits the space it has */
.fabric-lab .fabric-table { min-width: 0; }
.fabric-lab .fabric-table .col-swatch,
.fabric-lab .fabric-table .cell-swatch { display: none; }
.fabric-lab .fabric-table td { padding: 1rem .75rem; font-size: .9rem; }
.fabric-lab .fabric-table .fabric-name { white-space: nowrap; }
.fabric-lab .fabric-table th { padding-inline: .75rem; }
.fabric-table tbody tr[data-cloth] { cursor: pointer; transition: background .3s var(--ease); }
.fabric-table tbody tr.is-picked { background: rgba(22, 33, 61, .06); }
.fabric-table tbody tr.is-picked .fabric-name { color: var(--indigo); }
.fabric-table tbody tr[data-cloth]:focus-visible { outline-offset: -2px; }

/* ============================================================
   CONTACT: THE WOVEN LABEL
   ============================================================ */
.contact-panel.woven-label {
  position: relative;
  max-width: 54rem;
  padding: clamp(3.4rem, 8vw, 5rem) clamp(1.5rem, 6vw, 4rem);
  background:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .035) 0 2px, transparent 2px 5px),
    var(--indigo);
  color: var(--ecru);
  border: 0;
  border-radius: 2px;
  outline: 1px dashed rgba(236, 228, 208, .28);
  outline-offset: -12px;
  box-shadow: 0 44px 70px -40px rgba(12, 19, 37, .75);
  transform-origin: 50% 0;
}
.contact-panel.woven-label:hover {
  transform: translateY(-4px) rotate(-.5deg);
  box-shadow: 0 54px 80px -40px rgba(12, 19, 37, .8);
}
/* double gold rules, woven into the head and foot of the label */
.woven-label::before,
.woven-label::after {
  content: "";
  position: absolute;
  left: 32px;
  right: 32px;
  height: 5px;
  border-top: 1px solid #c9a55a;
  border-bottom: 1px solid #c9a55a;
}
.woven-label::before { top: 24px; }
.woven-label::after { bottom: 24px; }
.woven-label .contact-label { color: var(--weld); }
.woven-label .contact-mail {
  font-size: clamp(1.6rem, 5.2vw, 3.2rem);
  color: var(--ecru);
  border-bottom-color: rgba(236, 228, 208, .3);
}
.woven-label .contact-mail:hover { color: var(--weld); border-bottom-color: var(--weld); }
.woven-label .contact-arrow { color: var(--weld); }
.woven-label :focus-visible { outline-color: var(--weld); }

/* ============================================================
   PRINTING CARDS LEAN TOWARDS THE POINTER
   ============================================================ */
.tech-card {
  transition: transform .6s var(--ease-snap);
  transform-style: preserve-3d;
  will-change: transform;
}

@media (max-width: 980px) {
  .fabric-lab { grid-template-columns: 1fr; }
  .fabric-lab .fabric-table { min-width: 560px; }
  .pickglass { position: relative; top: auto; aspect-ratio: 4 / 3; }

  .about-stats { grid-template-columns: 1fr 1fr; row-gap: 2.4rem; }
  .about-stats .stat:nth-child(odd)::before { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tech-card { transition: none; }
  .about-stats .stat + .stat::before { transform: none; transition: none; }
  .pg-next.wipe { transition: none; }
}

/* ============================================================
   TROUSER FABRIC COLLECTION
   Under Apparel Fabrics: filter by fibre, pick a swatch, see the
   swatch card and the cloth made up for men and for women.
   ============================================================ */
.text-link {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  margin-top: 1.3rem;
  padding-bottom: .15rem;
  font-weight: 500;
  font-size: .95rem;
  color: var(--indigo);
  border-bottom: 1px solid currentColor;
}
.text-link:hover { color: var(--sage); }

/* Apparel shows just two families, shirting and trousers, so its
   swatch book is a pair of wide cards that sit inside the page
   rather than a strip running off it */
.kartela-rail--pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 17rem));
  gap: clamp(1rem, 2.4vw, 1.8rem);
  margin-right: 0;
  padding-right: 0;
  overflow: visible;
  cursor: auto;
}
.kartela-rail--pair .kartela-card { flex: none; }
.kartela-rail--pair .kartela-shot { aspect-ratio: 4 / 3; }
.kartela-rail--pair .kartela-name { font-size: 1.25rem; }
@media (max-width: 640px) {
  .kartela-rail--pair .kartela-shot { aspect-ratio: 4 / 5; }
  .kartela-rail--pair .kartela-name { font-size: 1.15rem; }
  .kartela-rail--pair .kartela-open { font-size: .68rem; padding: .35rem .4rem .35rem .6rem; left: .4rem; right: .4rem; bottom: .4rem; }
  .kartela-rail--pair .kartela-open span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* the trouser card in the Apparel swatch book opens the collection */
.kartela-card--opens { cursor: pointer; }
.kartela-card--opens .kartela-shot { position: relative; }
.kartela-open {
  position: absolute;
  left: .6rem;
  right: .6rem;
  bottom: .6rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  padding: .5rem .55rem .5rem .8rem;
  border-radius: 999px;
  background: rgba(22, 33, 61, .9);
  color: var(--ecru);
  font-size: .78rem;
  font-weight: 500;
  backdrop-filter: blur(6px);
  transition: background .3s var(--ease), transform .4s var(--ease-snap);
}
.kartela-open b {
  min-width: 1.6rem;
  padding: .1rem .4rem;
  border-radius: 999px;
  background: var(--weld);
  color: var(--indigo-deep);
  font-weight: 600;
  text-align: center;
}
.kartela-card--opens:hover .kartela-open,
.kartela-card--opens:focus-visible .kartela-open { transform: translateY(-3px); background: var(--indigo); }
.kartela-card--opens.is-open .kartela-shot { outline: 2px solid var(--indigo); outline-offset: 3px; }
.kartela-card--opens.is-open .kartela-name { color: var(--indigo); }

/* the collection unfolds inside the swatch book, under the card */
.trousers {
  position: relative;
  margin: 1.6rem 0 1.4rem;
  padding: clamp(1.5rem, 3.4vw, 2.6rem);
  background:
    radial-gradient(120% 60% at 0% 0%, rgba(255, 255, 255, .7), transparent 60%),
    var(--paper-warm);
  border: 1px solid var(--line);
  border-radius: 3px;
  scroll-margin-top: calc(var(--header-h, 72px) + 1rem);
  opacity: 0;
  transform: translateY(-14px);
  transform-origin: top;
  transition: opacity .4s var(--ease), transform .55s var(--ease-snap);
}
.trousers.is-open { opacity: 1; transform: none; }
/* a notch pointing back up at the card that opened it */
.trousers::before {
  content: "";
  position: absolute;
  top: -8px;
  left: var(--notch-x, 30%);
  width: 14px;
  height: 14px;
  margin-left: -7px;
  background: var(--paper-warm);
  border-left: 1px solid var(--line);
  border-top: 1px solid var(--line);
  transform: rotate(45deg);
  transition: left .3s var(--ease);
}
.tr-close-panel {
  position: absolute;
  top: .9rem;
  right: .9rem;
  width: 2.3rem;
  height: 2.3rem;
  border-radius: 50%;
  border: 1px solid var(--line-dash);
  background: var(--white);
  font-size: 1.3rem;
  line-height: 1;
  color: var(--ink);
  transition: background .3s var(--ease), color .3s var(--ease), transform .3s var(--ease);
}
.tr-close-panel:hover { background: var(--indigo); color: var(--ecru); transform: rotate(90deg); }

.tr-head {
  position: relative;
  display: grid;
  gap: 1.4rem;
  padding-right: 3rem;
  margin-bottom: clamp(1.6rem, 3vw, 2.2rem);
}
.tr-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2rem, 3.8vw, 3rem);
  line-height: 1;
  letter-spacing: -.02em;
  margin-bottom: .8rem;
}
.tr-sub { color: var(--ink-soft); max-width: 46ch; }

/* ---------- fibre family filters ---------- */
.tr-filters {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.tr-filter {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .55rem .5rem .95rem;
  border: 1px solid var(--line-dash);
  border-radius: 999px;
  font-size: .85rem;
  font-weight: 500;
  color: var(--ink);
  background: var(--white);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease), transform .3s var(--ease);
}
.tr-filter:hover { border-color: var(--indigo); transform: translateY(-1px); }
.tr-filter-n {
  min-width: 1.6rem;
  padding: .1rem .45rem;
  border-radius: 999px;
  background: var(--paper-warm);
  font-size: .75rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.tr-filter[aria-pressed="true"] {
  background: var(--indigo);
  border-color: var(--indigo);
  color: var(--ecru);
}
.tr-filter[aria-pressed="true"] .tr-filter-n { background: var(--weld); color: var(--indigo-deep); }

/* ---------- swatch tiles ---------- */
.tr-swatches {
  display: grid;
  grid-template-columns: repeat(9, minmax(0, 1fr));
  gap: clamp(.6rem, 1.2vw, .9rem);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.tr-swatch {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .1rem;
  text-align: left;
  transition: transform .45s var(--ease-snap);
}
.tr-swatch[hidden] { display: none; }
.tr-cloth {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  margin-bottom: .5rem;
  overflow: hidden;
  border-radius: 2px;
  box-shadow: 0 10px 20px -14px rgba(12, 19, 37, .6);
  /* pinking-shear teeth along the foot, like a cut sample */
  -webkit-mask:
    linear-gradient(#000 0 0) top / 100% calc(100% - 5px) no-repeat,
    conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) bottom / 10px 5px repeat-x;
          mask:
    linear-gradient(#000 0 0) top / 100% calc(100% - 5px) no-repeat,
    conic-gradient(from -45deg at bottom, #0000, #000 1deg 89deg, #0000 90deg) bottom / 10px 5px repeat-x;
}
.tr-cloth img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .6s var(--ease-snap);
}
.tr-swatch:hover { transform: translateY(-4px) rotate(-1.5deg); }
.tr-swatch:hover .tr-cloth { box-shadow: 0 18px 26px -14px rgba(12, 19, 37, .6); }
.tr-cloth { transition: box-shadow .45s var(--ease-snap); }
/* a light raking across the weave */
.tr-cloth { position: relative; }
.tr-cloth::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(150deg, rgba(255, 255, 255, .22), transparent 42%, rgba(0, 0, 0, .12));
  pointer-events: none;
}
.tr-swatch:hover .tr-cloth img { transform: scale(1.12); }
.tr-swatch-code { font-size: .8rem; font-weight: 600; letter-spacing: .02em; color: var(--ink); }
.tr-swatch-name { font-size: .74rem; color: var(--ink-soft); line-height: 1.3; }
.tr-swatch-gsm { font-size: .7rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }

.tr-swatch[aria-checked="true"] { transform: translateY(-6px); }
.tr-swatch[aria-checked="true"] .tr-cloth {
  outline: 2px solid var(--indigo);
  outline-offset: 3px;
}
/* the chosen swatch is pinned with a weld tag */
.tr-swatch { position: relative; }
.tr-swatch[aria-checked="true"]::before {
  content: "";
  position: absolute;
  z-index: 2;
  top: -7px;
  right: 10%;
  width: 10px;
  height: 18px;
  background: var(--weld);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 72%, 0 100%);
  box-shadow: 0 2px 4px rgba(0, 0, 0, .3);
}
.tr-swatch[aria-checked="true"] .tr-swatch-code { color: var(--indigo); }

/* tiles deal back in when the filter changes */
/* the tiles deal in as the panel opens */
.trousers.is-open .tr-swatch:not([hidden]) { animation: trDeal .55s var(--ease-snap) backwards; animation-delay: calc(.12s + var(--k0, 0) * 28ms); }
/* and deal again, under another name so it replays, when the filter changes */
.trousers.is-open .tr-swatch.tr-in:not([hidden]) { animation: trRedeal .55s var(--ease-snap) backwards; animation-delay: calc(var(--k, 0) * 35ms); }
@keyframes trDeal {
  from { opacity: 0; transform: translateY(14px) rotate(-2deg); }
  to   { opacity: 1; transform: none; }
}
@keyframes trRedeal {
  from { opacity: 0; transform: translateY(14px) rotate(-2deg); }
  to   { opacity: 1; transform: none; }
}

/* ---------- viewer ----------
   The look sits on a lit table: the swatch card laid down at a tilt
   with a gold clip, the two made-up trousers standing beside it. The
   spec runs underneath as a woven label. */
.tr-viewer {
  display: grid;
  gap: 0;
}

.tr-looks {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1rem, 2.4vw, 1.8rem);
  align-items: center;
  padding: clamp(1.4rem, 3vw, 2.4rem) clamp(1rem, 2.6vw, 2.2rem) clamp(2rem, 4vw, 3rem);
  border-radius: 3px 3px 0 0;
  background:
    radial-gradient(90% 70% at 50% 18%, rgba(255, 255, 255, .75), transparent 70%),
    repeating-linear-gradient(0deg, rgba(42, 42, 39, .025) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(42, 42, 39, .025) 0 1px, transparent 1px 3px),
    #e7e2d6;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6), inset 0 -30px 60px -40px rgba(42, 42, 39, .25);
}

.tr-look { position: relative; margin: 0; }

.tr-shot {
  display: block;
  position: relative;
  width: 100%;
  aspect-ratio: 2 / 3;
  overflow: hidden;
  border-radius: 2px;
  background: #d8d2c4;
  cursor: zoom-in;
  box-shadow: 0 30px 50px -34px rgba(12, 19, 37, .55);
  transition: transform .6s var(--ease-snap), box-shadow .6s var(--ease-snap);
}
.tr-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  clip-path: inset(0 0 0 0);
  transition: clip-path .5s var(--ease-cloth), transform .9s var(--ease-snap);
}
.tr-look:not(.tr-look--card) .tr-shot:hover { transform: translateY(-4px); box-shadow: 0 40px 60px -34px rgba(12, 19, 37, .6); }
.tr-look:not(.tr-look--card) .tr-shot:hover img { transform: scale(1.035); }
/* a new fabric rolls the old photograph up and the new one down,
   like cloth wound off and on a beam */
.tr-shot.is-changing img { clip-path: inset(0 0 100% 0); }

/* the swatch card: laid on the table at a tilt, held by a gold clip */
.tr-look--card { padding: 0 .4rem; }
.tr-look--card .tr-shot {
  aspect-ratio: 900 / 1195;
  overflow: visible;
  background: transparent;
  box-shadow: none;
  transform: rotate(-3.5deg);
  transform-origin: 50% 0;
}
.tr-look--card .tr-shot img {
  border-radius: 2px;
  box-shadow:
    0 1px 2px rgba(12, 19, 37, .2),
    0 28px 44px -22px rgba(12, 19, 37, .6);
}
.tr-look--card .tr-shot::before {
  content: "";
  position: absolute;
  z-index: 2;
  top: -9px;
  left: 50%;
  width: 38%;
  height: 16px;
  margin-left: -19%;
  border-radius: 3px;
  background: linear-gradient(180deg, #ecd28a, #c9a55a 45%, #8f6f2c);
  box-shadow: 0 3px 6px rgba(12, 19, 37, .35), inset 0 1px 0 rgba(255, 255, 255, .5);
}
.tr-look--card .tr-shot:hover { transform: rotate(-1deg) translateY(-4px); }
/* a new card is dropped onto the table */
.tr-look--card .tr-shot.is-changing { transform: rotate(-9deg) translateY(-26px); opacity: 0; }
.tr-look--card .tr-shot.is-changing img { clip-path: inset(0 0 0 0); }
.tr-look--card .tr-shot { transition: transform .6s var(--ease-snap), opacity .35s var(--ease); }

/* captions sit on the photographs as small tags */
.tr-look figcaption {
  position: absolute;
  z-index: 3;
  top: .7rem;
  left: .7rem;
  padding: .28rem .7rem .32rem;
  border-radius: 999px;
  background: rgba(247, 245, 240, .92);
  color: var(--ink);
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .02em;
  pointer-events: none;
  box-shadow: 0 4px 12px -6px rgba(12, 19, 37, .4);
}
.tr-look--card figcaption {
  top: auto;
  bottom: -2.4rem;
  left: 50%;
  transform: translateX(-50%);
  background: transparent;
  box-shadow: none;
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
  font-weight: 400;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* ---------- the canvas bag collection ----------
   Same panel as the trouser collection, but one cloth in thirty
   shades rather than eighteen fabrics: a pair of looks, the swatch
   card and the tote, and a tote that is wider than a trouser shot. */
.tr-looks--pair {
  grid-template-columns: minmax(0, .66fr) minmax(0, 1fr);
  justify-content: center;
  max-width: 62rem;
  margin-inline: auto;
}
.tr-look--bag .tr-shot { aspect-ratio: 900 / 1125; }
/* thirty shades sit as three shelves of ten */
.bags .tr-swatches { grid-template-columns: repeat(10, minmax(0, 1fr)); }
/* two products, each a photograph the size of a hand, and a label
   that carries a sentence about each */
.muslin .tr-swatches { grid-template-columns: repeat(3, minmax(0, 11rem)); }
.muslin .tr-shot { aspect-ratio: 1 / 1; }
.muslin .tr-looks--pair { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); max-width: 56rem; }
/* a product with one photograph shows it alone, centred */
.muslin .tr-looks--pair.is-single { grid-template-columns: minmax(0, 30rem); }
/* the muslin shows its cloth and both roll lengths as packed */
.muslin .tr-looks--pair.is-triple { grid-template-columns: repeat(3, minmax(0, 1fr)); max-width: 64rem; }
.muslin .tr-spec { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) auto; }
.muslin .tr-id { max-width: 26rem; }
.muslin .tr-code { font-size: clamp(2rem, 3.4vw, 2.9rem); }
.muslin .tr-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .9rem 1.4rem; }

/* ---------- the striped apron collection ----------
   Four colourways of one apron: a row of four swatches, the apron
   worn (3:4) beside a square close-up of the pinstriped drill. */
.aprons .tr-swatches { grid-template-columns: repeat(4, minmax(0, 9.5rem)); }
.aprons .tr-looks--pair { grid-template-columns: minmax(0, .75fr) minmax(0, 1fr); max-width: 56rem; align-items: start; }
.aprons .tr-look--worn .tr-shot { aspect-ratio: 3 / 4; }
.aprons .tr-look--cloth .tr-shot { aspect-ratio: 1 / 1; }
@media (max-width: 640px) {
  .aprons .tr-swatches { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* ---------- the printed tea towel collection ----------
   Six collections, some of fifty designs, on shelves of eight; the artwork beside the towel
   at the shirting size, and five facts in two rows. */
.teatowels .tr-swatches { grid-template-columns: repeat(8, minmax(0, 1fr)); }
.teatowels .tr-looks--pair { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); max-width: 52rem; align-items: start; }
.teatowels .tr-shot { aspect-ratio: 900 / 1215; }
.teatowels .tr-facts { grid-template-columns: repeat(3, auto); gap: .9rem 1.6rem; justify-content: start; }
@media (max-width: 980px) {
  .teatowels .tr-swatches { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  /* the phone's swipe strip, as for the other collections */
  .teatowels .tr-swatches { grid-template-columns: none; grid-auto-columns: 7.6rem; }
  .teatowels .tr-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* ---------- the printed curtain collection ----------
   Shares the tea towel layout (it carries both classes); only the
   pictures differ, the artwork and the room both 4:5. A design with
   no room render yet stands alone at half the width. */
.curtains .tr-shot { aspect-ratio: 4 / 5; }
.curtains .tr-looks--pair.is-single { grid-template-columns: minmax(0, 25rem); }
/* ---------- the shirting collection ----------
   The trouser panel again, with shirt photographs a little squarer
   than a trouser shot and a fourth fact, the pattern. A fabric whose
   men's shot is left out shows its card and the women's shirt as a pair. */
.shirts .tr-shot,
.shirts .tr-look--card .tr-shot { aspect-ratio: 900 / 1215; }
.shirts .tr-facts { grid-template-columns: minmax(0, 1.5fr) auto auto auto; }
.shirts .tr-looks.is-pair {
  grid-template-columns: minmax(0, .82fr) minmax(0, 1fr);
  max-width: 44rem;
  margin-inline: auto;
}
@media (max-width: 640px) {
  .shirts .tr-facts { grid-template-columns: 1fr 1fr; }
  .shirts .tr-looks.is-pair { grid-template-columns: none; max-width: none; margin-inline: calc(-1 * var(--gutter)); }
}
.tr-desc { margin: .8rem 0 0; font-size: .92rem; line-height: 1.55; opacity: .82; }

/* ---------- the spec, as a woven label ---------- */
.tr-spec {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: clamp(1rem, 3vw, 2.6rem);
  align-items: center;
  padding: 2.1rem clamp(1.3rem, 3vw, 2.4rem) 2rem;
  background:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, .035) 0 2px, transparent 2px 5px),
    var(--indigo);
  color: var(--ecru);
  border-radius: 0 0 3px 3px;
  outline: 1px dashed rgba(236, 228, 208, .24);
  outline-offset: -9px;
}
.tr-spec::before,
.tr-spec::after {
  content: "";
  position: absolute;
  left: 22px;
  right: 22px;
  height: 5px;
  border-top: 1px solid #c9a55a;
  border-bottom: 1px solid #c9a55a;
}
.tr-spec::before { top: 16px; }
.tr-spec::after { bottom: 16px; }

.tr-id { min-width: 8.5rem; }
.tr-family { display: block; font-size: .76rem; letter-spacing: .04em; color: var(--weld); }
.tr-code {
  margin: .2rem 0 .05rem;
  font-family: var(--serif);
  font-size: clamp(2.6rem, 4.4vw, 3.6rem);
  line-height: .95;
  letter-spacing: -.02em;
}
.tr-colour { font-family: var(--serif); font-style: italic; font-size: 1.2rem; opacity: .85; }

.tr-facts {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) auto auto;
  gap: 0 1.4rem;
  margin: 0;
  padding-left: clamp(1rem, 2.6vw, 2.2rem);
  border-left: 1px dashed rgba(236, 228, 208, .24);
}
.tr-facts div { display: grid; gap: .25rem; }
.tr-facts dt { font-size: .72rem; letter-spacing: .04em; opacity: .6; }
.tr-facts dd { margin: 0; font-size: .95rem; line-height: 1.4; font-variant-numeric: tabular-nums; }
/* a weight or a width reads as one figure, never broken over two lines */
.tr-facts div:not(.tr-fact-wide) dd { white-space: nowrap; }

.tr-actions { display: grid; gap: .7rem; justify-items: stretch; }
.tr-cta {
  white-space: nowrap;
  text-align: center;
  background: var(--weld);
  color: var(--indigo-deep);
}
.tr-cta:hover { background: var(--ecru); color: var(--indigo-deep); }
.tr-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
}
.tr-count { font-size: .78rem; letter-spacing: .04em; opacity: .7; font-variant-numeric: tabular-nums; }
.tr-arrow {
  width: 2.2rem;
  height: 2.2rem;
  border: 1px solid rgba(236, 228, 208, .3);
  border-radius: 50%;
  color: var(--ecru);
  font-size: 1rem;
  transition: background .3s var(--ease), border-color .3s var(--ease), color .3s var(--ease);
}
.tr-arrow:hover { background: var(--ecru); border-color: var(--ecru); color: var(--indigo-deep); }
.tr-spec :focus-visible { outline-color: var(--weld); }

/* the label's words turn over when the fabric changes */
.tr-spec.tr-turn .tr-code,
.tr-spec.tr-turn .tr-colour,
.tr-spec.tr-turn .tr-facts dd { animation: trTurn .5s var(--ease-snap); }
@keyframes trTurn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- lightbox ---------- */
.tr-lightbox {
  padding: 0;
  border: 0;
  background: transparent;
  max-width: 94vw;
  max-height: 94vh;
  overflow: visible;
}
.tr-lightbox::backdrop { background: rgba(12, 19, 37, .86); backdrop-filter: blur(4px); }
.tr-lightbox img {
  display: block;
  max-width: 94vw;
  max-height: 90vh;
  width: auto;
  height: auto;
  border-radius: 2px;
  box-shadow: 0 40px 80px -30px rgba(0, 0, 0, .7);
}
.tr-lightbox[open] img { animation: trZoom .45s var(--ease-snap); }
@keyframes trZoom { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
.tr-close {
  position: absolute;
  top: -.9rem;
  right: -.9rem;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  background: var(--ecru);
  color: var(--indigo-deep);
  font-size: 1.4rem;
  line-height: 1;
  box-shadow: 0 8px 20px rgba(0, 0, 0, .35);
}

@media (max-width: 980px) {
  .tr-head { grid-template-columns: 1fr; }
  .tr-swatches,
  .bags .tr-swatches { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .tr-looks--pair { grid-template-columns: minmax(0, .8fr) minmax(0, 1fr); }
  .muslin .tr-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .muslin .tr-looks--pair.is-triple { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .7rem; }
  .tr-spec { grid-template-columns: 1fr 1fr; }
  .tr-facts { grid-column: 1 / -1; grid-row: 2; padding-left: 0; border-left: 0; padding-top: 1rem; border-top: 1px dashed rgba(236, 228, 208, .24); }
  .tr-actions { grid-column: 2; grid-row: 1; }
}

@media (max-width: 640px) {
  /* on a phone the panel runs edge to edge, so its swipe strips can too */
  .trousers {
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: var(--gutter);
    border-left: 0;
    border-right: 0;
    border-radius: 0;
  }
  /* on a phone the swatches become a strip you swipe along */
  .tr-swatches,
  .bags .tr-swatches {
    display: grid;
    grid-auto-flow: column;
    grid-template-columns: none;
    grid-auto-columns: 5.4rem;
    overflow-x: auto;
    padding: .5rem var(--gutter) .8rem;
    margin-inline: calc(-1 * var(--gutter));
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }
  .muslin .tr-swatches { grid-template-columns: none; grid-auto-columns: 7.6rem; }
  .tr-swatches::-webkit-scrollbar { display: none; }
  .tr-swatch { scroll-snap-align: start; }
  .tr-swatches { scroll-padding-inline: var(--gutter); }
  /* the family filters ride on one swipeable line too */
  .tr-filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding: .2rem var(--gutter) .4rem;
    margin-inline: calc(-1 * var(--gutter));
    scrollbar-width: none;
  }
  .tr-filters::-webkit-scrollbar { display: none; }
  .tr-filter { flex: 0 0 auto; }
  /* and so does the look */
  .tr-looks {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 70%;
    overflow-x: auto;
    padding: 1.6rem var(--gutter) 3rem;
    margin-inline: calc(-1 * var(--gutter));
    border-radius: 0;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    scrollbar-width: none;
  }
  .tr-spec { margin-inline: calc(-1 * var(--gutter)); border-radius: 0; grid-template-columns: 1fr; }
  .tr-actions { grid-column: 1; grid-row: auto; }
  .tr-facts { grid-template-columns: 1fr 1fr; row-gap: .9rem; }
  .tr-facts .tr-fact-wide { grid-column: 1 / -1; }
  .tr-looks::-webkit-scrollbar { display: none; }
  .tr-look { scroll-snap-align: center; }
  .tr-filter { font-size: .8rem; padding: .42rem .5rem .42rem .8rem; }
}

@media (prefers-reduced-motion: reduce) {
  .trousers, .trousers.is-open .tr-swatch, .kartela-open, .tr-close-panel,
  .tr-swatch, .tr-swatch.tr-in, .tr-cloth img, .tr-shot img, .tr-look--card .tr-shot, .tr-shot,
  .tr-spec.tr-turn .tr-code, .tr-spec.tr-turn .tr-colour, .tr-spec.tr-turn .tr-facts dd,
  .tr-lightbox[open] img { animation: none; transition: none; }
}

/* ============================================================
   KEYFRAMES
   ============================================================ */
@keyframes pickIn {
  to { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes riseIn {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@keyframes swatchSway {
  from { transform: rotate(-1.2deg); }
  to   { transform: rotate(1.2deg); }
}
@keyframes tagSway {
  from { rotate: -3deg; }
  to   { rotate: 3deg; }
}
@keyframes foldDrift {
  from { background-position: 0% 0; }
  to   { background-position: 100% 0; }
}
@keyframes numFlip {
  from { transform: translateY(-60%) rotateX(80deg); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes twillRun {
  to { background-position: 28px 0, 0 0; }
}

/* ============================================================
   REDUCED MOTION: everything arrives finished and holds still
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none; }
  .cover-img, .cover-cue { transform: none; filter: none; opacity: 1; animation: none; }
  .cover-cue i { animation: none; }
  .hero-title .ch,
  .press .hero-sub,
  .press .hero-ctas,
  .press .hero-eyebrow { opacity: 1; transform: none; filter: none; animation: none; }
  .dye-chip, .vat-tag, .vat-fold { animation: none; }
  .dye-wall.reveal .dye-chip { opacity: 1; translate: none; transition: none; }
  .vat-new.spread { transition: none; }
  .section-head .section-title::after,
  .dye-copy .section-title::after { width: 119px; transition: none; }
  .print-sample::before { display: none; }
  .tech-card:nth-child(-n+2) .print-sample.reveal-cloth { -webkit-mask-image: none; mask-image: none; }
  .footer-mark .ch { translate: none; transition: none; }
  .read-scrub .w { color: var(--ink); transition: none; }
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 980px) {
  .dye-grid { grid-template-columns: 1fr; }
  .dye-wall { grid-template-columns: repeat(6, 1fr); }
}

@media (max-width: 640px) {
  .press {
    --strip: 3.5rem;
    min-height: max(34rem, 100svh);
    justify-content: flex-start;
    /* the print lies along the foot, whole, under the words */
    padding-bottom: calc(var(--print-h, 0px) + 4.6rem);
  }
  .press-shade {
    background:
      linear-gradient(to bottom, rgba(12, 19, 37, .92) 0%, rgba(12, 19, 37, .84) 58%, rgba(12, 19, 37, .2) 82%, rgba(12, 19, 37, 0) 90%);
  }
  .press .hero-title { font-size: clamp(2.6rem, 12.5vw, 4rem); }
  .press .hero-sub { font-size: 1rem; }
  .press-readout { gap: .6rem; font-size: .64rem; bottom: .9rem; right: 50%; translate: 50% 0; white-space: nowrap; }
  .press-readout { padding: .55rem .95rem; }
  .dye-wall { grid-template-columns: repeat(4, 1fr); }
  .vat-tag { left: .8rem; bottom: .8rem; }
  .ribbon { width: 130%; margin-left: -15%; }
}
