/* ============================================================
   MEKAN TEXTILE - main.css
   "Linen" design system: paper ground, woven texture overlay,
   dashed hairlines, Instrument Serif display + Figtree text.
   ============================================================ */

/* ---------- Design tokens ---------- */
:root {
  --paper:      #f7f5f0;
  --paper-warm: #efece4;
  --white:      #ffffff;

  --ink:        #2a2a27;
  --ink-soft:   #5e5e58;
  --ink-faint:  #8a8a82;

  --line:       #e3e0d8;
  --line-dash:  #cfccc3;

  --sage:       #6f7f6a;
  --sage-mist:  #8a9a94;
  --forest:     #2f3a2c;

  --clay:       #dfd6c4;
  --clay-deep:  #cfc3aa;
  --flax:       #ece5d6;
  --flax-deep:  #d9cfba;

  --serif: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  --sans:  "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;

  --wrap:   1100px;
  --narrow: 760px;
  --gutter: clamp(1.25rem, 4vw, 2rem);

  /* How far it is from the text column out to the window edge; cloth
     uses this to run off the page the way a bolt does off a table.
     Half the container's overhang, plus the gutter the container adds
     inside it. It overshoots by half a scrollbar because 100vw counts
     the scrollbar; main's overflow clip absorbs that. */
  --bleed: calc((100vw - min(100vw, var(--wrap))) / 2 + var(--gutter));

  --r-sm: 4px;
  --r:    6px;
  --r-lg: 8px;

  --shadow-soft: 0 1px 2px rgba(42, 42, 39, .04), 0 10px 28px -16px rgba(42, 42, 39, .16);
  --shadow-menu: 0 20px 50px -24px rgba(42, 42, 39, .3);
  --shadow-card: 0 14px 34px -22px rgba(42, 42, 39, .35);
  --shadow-tag:  0 10px 24px -16px rgba(42, 42, 39, .4);

  --ease: cubic-bezier(.22, .61, .36, 1);
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  transition: opacity .25s ease;
}

body.lang-switching { opacity: .35; }

h1, h2, h3, h4, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; transition: color .3s var(--ease); }
a:hover { color: var(--sage); }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
table { border-collapse: collapse; }
::selection { background: var(--sage); color: var(--paper); }

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

/* ---------- Woven texture overlay ---------- */
.weave-overlay {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .045;
  background-image:
    repeating-linear-gradient(0deg,  rgba(42, 42, 39, .35) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(42, 42, 39, .35) 0 1px, transparent 1px 3px);
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(130% 90% at 50% -12%, rgba(255, 255, 255, .60), transparent 55%),
    radial-gradient(120% 100% at 50% 112%, rgba(42, 42, 39, .06), transparent 62%);
}

main, .site-footer { position: relative; z-index: 1; }

/* 100vw counts the scrollbar, so a bleed overshoots by a few pixels.
   clip trims it without making main a scroll container, which would
   break the sticky header. */
main { overflow-x: clip; }

/* ---------- Layout ---------- */
.container {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

.section { padding-block: clamp(4rem, 9vw, 7rem); }

.section-head {
  max-width: var(--narrow);
  margin: 0 auto clamp(2.5rem, 5vw, 4rem);
  text-align: center;
}

/* ---------- Typography ---------- */
.eyebrow {
  font-size: .82rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--sage);
  margin-bottom: 1.2rem;
}

.section-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.2rem, 4.5vw, 3.4rem);
  line-height: 1.08;
  letter-spacing: -.015em;
  text-wrap: balance;
  margin-bottom: 1.2rem;
}

.section-head .section-title:last-child { margin-bottom: 0; }

.lead {
  color: var(--ink-soft);
  max-width: 52ch;
}

.section-head .lead { margin-inline: auto; }

.body-text { color: var(--ink-soft); }

p { text-wrap: pretty; }

.mini-title {
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 500;
  margin-bottom: .8rem;
}

.note {
  font-size: .85rem;
  font-style: italic;
  color: var(--ink-faint);
  margin-top: 1.2rem;
}

/* ---------- Buttons ---------- */
.btn {
  position: relative;
  display: inline-block;
  overflow: hidden;
  font-size: .88rem;
  font-weight: 500;
  padding: .6em 1.2em;
  border-radius: var(--r);
  transition:
    background .3s var(--ease),
    color .3s var(--ease),
    border-color .3s var(--ease),
    transform .3s var(--ease),
    box-shadow .3s var(--ease);
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

/* a sheen crossing the weave */
.btn-primary::after,
.btn-light::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .28) 50%, transparent 62%);
  transform: translateX(-130%);
  transition: transform .8s var(--ease);
}
.btn-primary:hover::after,
.btn-light:hover::after { transform: translateX(130%); }

.btn-lg { font-size: .92rem; padding: .85em 1.6em; }

.btn-primary { background: var(--ink); color: var(--paper); }
.btn-primary:hover { box-shadow: 0 14px 26px -16px rgba(42, 42, 39, .9); }
.btn-primary:hover { background: var(--sage); color: var(--paper); }

.btn-ghost { border: 1px solid var(--line-dash); color: var(--ink); }
.btn-ghost:hover { border-color: var(--ink); color: var(--ink); }

.btn-light { background: var(--paper); color: var(--forest); }
.btn-light:hover { background: var(--white); color: var(--forest); }

/* ============================================================
   HEADER
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(247, 245, 240, .9);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition:
    border-color .3s var(--ease),
    background .3s var(--ease),
    transform .45s var(--ease);
}

/* out of the way going down, back the moment you look up */
.site-header.tucked { transform: translateY(-100%); }

.site-header.scrolled { border-bottom-color: var(--line); }

.scroll-thread {
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 100%;
  height: 2px;
  background: var(--sage);
  opacity: .75;
  transform: scaleX(var(--p, 0));
  transform-origin: 0 50%;
}

.header-inner {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 1.1rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
}
.brand:hover { color: inherit; }

.brand-logo {
  height: 2rem;
  width: auto;
  border-radius: var(--r-sm);
}

.brand-name {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.4rem;
  letter-spacing: -.01em;
}

.main-nav {
  display: flex;
  gap: 1.8rem;
  font-size: .9rem;
  color: var(--ink-soft);
}

/* six links, some two words long in some languages: keep each on one
   line and close them up on narrower screens before the menu folds */
.main-nav > a { white-space: nowrap; }
@media (max-width: 1240px) {
  .main-nav { gap: 1.1rem; font-size: .86rem; }
}
.main-nav a { position: relative; padding-block: .25rem; }
.main-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--sage);
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform .4s var(--ease);
}
.main-nav a:hover::after,
.main-nav a.is-current::after {
  transform: scaleX(1);
  transform-origin: 0 50%;
}
.main-nav a.is-current { color: var(--ink); }

/* ---------- Products menu ----------
   The link still goes to the section; the chevron beside it opens a
   card listing every product, each a jump to its swatch. */
.nav-drop { position: relative; display: flex; align-items: center; gap: .3rem; }
.nav-drop-btn {
  display: inline-flex;
  align-items: center;
  padding: .25rem .15rem;
  color: inherit;
  cursor: pointer;
}
.nav-drop-btn .chev { transition: transform .3s var(--ease); }
.nav-drop.open .nav-drop-btn .chev { transform: rotate(180deg); }
.nav-menu {
  position: absolute;
  top: calc(100% + .8rem);
  left: -.6rem;
  display: flex;
  gap: .4rem;
  padding: .6rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow-menu);
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
  z-index: 5;
}
.nav-drop.open .nav-menu {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.nav-menu a {
  display: block;
  padding: .5rem .7rem;
  border-radius: var(--r);
  font-size: .88rem;
  white-space: nowrap;
  color: var(--ink);
  transition: background .2s var(--ease);
}
.nav-menu a::after { display: none; }
/* the three families stand as columns, each under its own name */
.nav-group { min-width: 11rem; padding: .3rem .2rem; }
.nav-menu .nav-group + .nav-group { border-left: 1px dashed var(--line-dash); }
.nav-group-title {
  display: block;
  padding: .3rem .7rem .45rem;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}
.nav-menu a:hover,
.nav-menu a:focus-visible { background: #f0eee8; }

/* the card the menu sent you to is picked out for a moment */
@keyframes cardHit {
  0%, 70% { outline-color: var(--indigo, #16213d); }
  100% { outline-color: transparent; }
}
.kartela-card.is-hit .kartela-shot,
.tech-card.is-hit,
.fabric-table tr.is-hit {
  outline: 2px solid transparent;
  outline-offset: 3px;
  animation: cardHit 1.8s var(--ease) forwards;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 1.2rem;
}

/* ---------- Language switcher ---------- */
.lang-switch { position: relative; }

.lang-btn {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-size: .85rem;
  font-weight: 500;
  color: var(--ink-soft);
  transition: color .3s var(--ease);
}
.lang-btn:hover { color: var(--ink); }

.flag {
  display: inline-flex;
  width: 1.1rem;
  line-height: 0;
  border-radius: 2px;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(42, 42, 39, .1);
}
.flag svg { display: block; width: 100%; height: auto; }

.lang-label { letter-spacing: .01em; }

.lang-btn .chev { transition: transform .3s var(--ease); }
.lang-switch.open .chev { transform: rotate(180deg); }

.lang-menu {
  position: absolute;
  top: calc(100% + .8rem);
  right: 0;
  min-width: 12rem;
  max-height: 22rem;
  overflow-y: auto;
  padding: .4rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow-menu);
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
  z-index: 5;
}

.lang-switch.open .lang-menu {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.lang-menu li {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .5rem .7rem;
  border-radius: var(--r);
  font-size: .88rem;
  cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.lang-menu li .flag { width: 1.2rem; }
.lang-menu li:hover { background: #f0eee8; }
.lang-menu li[aria-selected="true"] { background: var(--ink); color: var(--paper); }
.lang-menu li[aria-selected="true"]:hover { background: var(--ink); }

/* ---------- Mobile menu ---------- */
.menu-toggle {
  display: none;
  width: 2rem;
  height: 2rem;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
}
.menu-toggle span {
  display: block;
  height: 1px;
  width: 100%;
  background: var(--ink);
  transition: transform .3s var(--ease), opacity .3s var(--ease);
}
.menu-toggle[aria-expanded="true"] span:first-child { transform: translateY(3px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:last-child  { transform: translateY(-3px) rotate(-45deg); }

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  padding: 6rem var(--gutter) 2.5rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s var(--ease);
}
.mobile-menu.open { opacity: 1; pointer-events: auto; }
.mobile-menu nav { display: grid; gap: .4rem; }

/* everything in the menu arrives the same way; only the nav links are
   set as headline type, so the address below keeps its own scale */
.mobile-menu a {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .45s var(--ease), transform .45s var(--ease);
}
.mobile-menu.open a { opacity: 1; transform: none; }

.mobile-menu nav a {
  font-family: var(--serif);
  font-size: 2rem;
  line-height: 1.3;
  padding-block: .3rem;
  border-bottom: 1px dashed var(--line-dash);
}

.mobile-menu.open nav a:nth-child(1) { transition-delay: .06s; }
.mobile-menu.open nav a:nth-child(2) { transition-delay: .11s; }
.mobile-menu.open nav a:nth-child(3) { transition-delay: .16s; }
.mobile-menu.open nav a:nth-child(4) { transition-delay: .21s; }
.mobile-menu.open nav a:nth-child(5) { transition-delay: .26s; }
.mobile-menu.open nav a:nth-child(6) { transition-delay: .31s; }
.mobile-menu.open nav a:nth-child(7) { transition-delay: .36s; }
.mobile-menu.open .mobile-mail { transition-delay: .42s; }

/* the products, listed under Products in the menu */
.mobile-sub {
  display: grid;
  gap: .1rem;
  padding: .3rem 0 .5rem 1.1rem;
  border-bottom: 1px dashed var(--line-dash);
}
.mobile-sub .nav-group { display: grid; gap: .1rem; padding-top: .35rem; }
.mobile-sub .nav-group-title {
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding-block: .3rem .1rem;
}
.mobile-menu nav .mobile-sub a {
  font-family: var(--sans);
  font-size: 1.05rem;
  line-height: 1.4;
  padding-block: .25rem;
  border-bottom: 0;
  color: var(--ink-soft);
}

.mobile-mail {
  display: block;
  margin-top: auto;
  padding-top: 1.2rem;
  border-top: 1px solid var(--ink);
  font-family: var(--serif);
  font-size: 1.3rem;
  overflow-wrap: anywhere;
}
.mobile-mail .contact-label { margin-bottom: .4rem; }

/* ============================================================
   HERO
   ============================================================ */
.hero {
  padding: clamp(5rem, 12vh, 9rem) var(--gutter) 0;
  text-align: center;
}

.hero-inner {
  max-width: var(--narrow);
  margin: 0 auto;
  padding: 0;
  opacity: 0;
  animation: fadeIn 1.4s var(--ease) .1s forwards;
}

.hero-eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .9rem;
  margin-bottom: 1.6rem;
}
.hero-eyebrow::before,
.hero-eyebrow::after {
  content: "";
  width: 2.4rem;
  border-top: 1px dashed var(--sage);
}

.hero-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(3rem, 7.5vw, 6rem);
  line-height: 1.02;
  letter-spacing: -.02em;
  text-wrap: balance;
  margin-bottom: 1.6rem;
}
.hero-title .line { display: block; overflow: hidden; }
.hero-title .line-inner {
  display: block;
  transform: translateY(110%);
  animation: lineUp 1.1s var(--ease) forwards;
}
.hero-title .line:nth-child(1) .line-inner { animation-delay: .15s; }
.hero-title .line:nth-child(2) .line-inner { animation-delay: .27s; }
.hero-title .line:nth-child(3) .line-inner { animation-delay: .39s; }
.hero-title em { font-style: italic; color: var(--sage); }

.hero-sub {
  font-size: 1.15rem;
  color: var(--ink-soft);
  max-width: 48ch;
  margin: 0 auto 2.2rem;
}

.hero-ctas {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
}

/* ---------- Hero fabric band + spec card ---------- */
.hero-band {
  max-width: var(--wrap);
  margin: clamp(3rem, 7vw, 5rem) auto 0;
  position: relative;
}

/* ---------- Photographed cloth ----------
   Each quality is shown as the cloth it actually is. One shared rule
   sets how a photograph sits in a panel; the classes below only name
   the file. A scrim rides over the rail shots so the specification
   stays readable whatever the fabric underneath is doing. */
.photo-fill {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.rail-panama,
.rail-teatowel,
.rail-apron,
.rail-bag,
.rail-drill,
.rail-muslin,
.rail-canvas {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  transition: background-size .9s var(--ease);
}
.rail-panama { background-image: linear-gradient(180deg, rgba(18, 18, 16, .66) 0%, rgba(18, 18, 16, .20) 30%, rgba(18, 18, 16, .08) 56%, rgba(18, 18, 16, .30) 100%), url("../assets/img/rail-panama.jpg"); }
.rail-teatowel { background-image: linear-gradient(180deg, rgba(18, 18, 16, .66) 0%, rgba(18, 18, 16, .20) 30%, rgba(18, 18, 16, .08) 56%, rgba(18, 18, 16, .30) 100%), url("../assets/img/rail-teatowel.jpg"); }
.rail-apron { background-image: linear-gradient(180deg, rgba(18, 18, 16, .66) 0%, rgba(18, 18, 16, .20) 30%, rgba(18, 18, 16, .08) 56%, rgba(18, 18, 16, .30) 100%), url("../assets/img/rail-apron.jpg"); }
.rail-drill  { background-image: linear-gradient(180deg, rgba(18, 18, 16, .66) 0%, rgba(18, 18, 16, .20) 30%, rgba(18, 18, 16, .08) 56%, rgba(18, 18, 16, .30) 100%), url("../assets/img/rail-drill.jpg?v=202609210330"); }
.rail-muslin { background-image: linear-gradient(180deg, rgba(18, 18, 16, .66) 0%, rgba(18, 18, 16, .20) 30%, rgba(18, 18, 16, .08) 56%, rgba(18, 18, 16, .30) 100%), url("../assets/img/rail-muslin.jpg"); }
.rail-bag { background-image: linear-gradient(180deg, rgba(18, 18, 16, .66) 0%, rgba(18, 18, 16, .20) 30%, rgba(18, 18, 16, .08) 56%, rgba(18, 18, 16, .30) 100%), url("../assets/img/rail-bag.jpg"); }
.rail-canvas { background-image: linear-gradient(180deg, rgba(18, 18, 16, .66) 0%, rgba(18, 18, 16, .20) 30%, rgba(18, 18, 16, .08) 56%, rgba(18, 18, 16, .30) 100%), url("../assets/img/rail-canvas.jpg"); }

/* the open quality shows a little more of its cloth */
.rail-swatch.is-active { background-size: 116%; }

.fs-poplin,
.fs-panama,
.fs-drill,
.fs-canvas {
  background-size: cover;
  background-position: center;
}
.fs-poplin { background-image: url("../assets/img/rail-poplin.jpg"); }
.fs-panama { background-image: url("../assets/img/rail-panama.jpg"); }
.fs-drill  { background-image: url("../assets/img/rail-drill.jpg?v=202609210330"); }
.fs-canvas { background-image: url("../assets/img/rail-canvas.jpg"); }

/* ---------- Hero: the range, on one rail ----------
   Four qualities side by side; picking one opens its specification. */
.swatch-rail {
  display: flex;
  aspect-ratio: 21 / 9;
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow:
    inset 0 0 0 1px var(--line),
    0 24px 60px -40px rgba(42, 42, 39, .55);
}

.rail-swatch {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 1.1rem 1.2rem 1.3rem;
  text-align: left;
  border-right: 1px solid rgba(247, 245, 240, .55);
  transition: flex-grow .55s var(--ease);
}
.rail-swatch:last-child { border-right: 0; }
.rail-swatch.is-active { flex-grow: 2.1; }


/* the rail sits on photographs now, so the type carries its own shadow
   rather than relying on how dark a given cloth happens to be */
.rail-swatch > span { text-shadow: 0 1px 10px rgba(18, 18, 16, .55); }

.rail-name {
  display: block;
  font-family: var(--serif);
  font-size: 1.15rem;
  line-height: 1.2;
  color: var(--ink);
}
.rail-gsm {
  display: block;
  font-size: .7rem;
  letter-spacing: .14em;
  color: rgba(42, 42, 39, .62);
}

/* the eyelet marks which quality is open */
.rail-mark {
  position: absolute;
  top: 1.35rem;
  right: 1.2rem;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid rgba(42, 42, 39, .35);
  transition: background .35s var(--ease), border-color .35s var(--ease);
}
.rail-swatch.is-active .rail-mark {
  background: var(--ink);
  border-color: var(--ink);
}

.rail-detail {
  display: block;
  max-width: 30ch;
  margin-top: 1.1rem;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .45s var(--ease), transform .45s var(--ease);
}
.rail-swatch.is-active .rail-detail {
  opacity: 1;
  transform: none;
  transition-delay: .12s;
}

.rail-spec {
  display: block;
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(42, 42, 39, .62);
  margin-bottom: .35rem;
}
/* a product made in two qualities lists both; each keeps its own line */
.rail-alt { display: inline-block; white-space: nowrap; }
/* the bar between them belongs to the first, so it never starts a line */
.rail-alt:not(:last-child)::after {
  content: "";
  display: inline-block;
  width: 1px;
  height: .8em;
  margin: 0 .55em;
  vertical-align: -.1em;
  background: currentColor;
  opacity: .5;
}
.rail-use {
  display: block;
  font-size: .9rem;
  line-height: 1.5;
  color: rgba(42, 42, 39, .82);
}

.rail-swatch.on-dark .rail-name { color: var(--paper); }
.rail-swatch.on-dark .rail-gsm,
.rail-swatch.on-dark .rail-spec { color: rgba(247, 245, 240, .82); }
.rail-swatch.on-dark .rail-use  { color: rgba(247, 245, 240, .94); }
.rail-swatch.on-dark .rail-mark { border-color: rgba(247, 245, 240, .6); }
.rail-swatch.on-dark.is-active .rail-mark {
  background: var(--paper);
  border-color: var(--paper);
}

.rail-swatch:focus-visible { outline-offset: -4px; }

/* a sage ring disappears against the forest sections, so on dark
   ground the focus outline switches to paper */
.printing :focus-visible,

/* the rail walks the range on its own; this line is the time until it moves on */
.rail-swatch::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: var(--ink);
  opacity: .3;
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.rail-swatch.on-dark::after { background: var(--paper); opacity: .45; }
.swatch-rail.is-playing .rail-swatch.is-active::after {
  animation: railDwell var(--rail-dwell, 5.2s) linear forwards;
}
.swatch-rail.is-held .rail-swatch.is-active::after { animation-play-state: paused; }

.spec-card {
  position: absolute;
  right: 1.5rem;
  bottom: -1.4rem;
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: .9rem 1.1rem .9rem 1.6rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-card);
  transform: rotate(-1.5deg);
  text-align: left;
  transition: transform .45s var(--ease), box-shadow .45s var(--ease);
}
.spec-card:hover {
  transform: rotate(0deg) translateY(-4px);
  box-shadow: 0 22px 44px -24px rgba(42, 42, 39, .45);
}
.spec-card::before {
  content: "";
  position: absolute;
  left: .6rem;
  top: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--line-dash);
  transform: translateY(-50%);
}
.spec-divider {
  width: 1px;
  height: 2rem;
  background: var(--line);
}
.spec-label {
  display: block;
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.spec-value {
  font-family: var(--serif);
  font-size: 1.2rem;
  white-space: nowrap;
}

.hero-scroll {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .7rem;
  margin-top: 2.6rem;
  font-size: .72rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.hero-scroll .scroll-line {
  width: 2.6rem;
  height: 1px;
  background: linear-gradient(90deg, var(--line-dash), transparent);
}

/* ============================================================
   MARQUEE
   ============================================================ */
.marquee {
  position: relative;
  z-index: 1;
  margin-top: clamp(3.5rem, 7vw, 5.5rem);
  padding-block: .8rem;
  border-top: 1px dashed var(--line-dash);
  border-bottom: 1px dashed var(--line-dash);
  overflow: hidden;
}

.marquee-track {
  display: flex;
  align-items: center;
  gap: 2.6rem;
  width: max-content;
  animation: marquee 42s linear infinite;
  will-change: transform;
}
/* once script drives it, the words take their speed from your scrolling */
.marquee.js-marquee .marquee-track { animation: none; }

.marquee-track span {
  font-family: var(--serif);
  font-size: 1.2rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

.marquee-track i {
  font-style: normal;
  font-size: .6rem;
  color: var(--sage);
}

/* ============================================================
   ABOUT
   ============================================================ */
.about-copy {
  max-width: var(--narrow);
  margin: 0 auto;
}
/* this paragraph is the claim the rest of the page answers, so it is
   set one step above every other section title */
.about-copy .section-title {
  font-size: clamp(2.6rem, 5.4vw, 4.2rem);
  letter-spacing: -.025em;
  margin-bottom: 1.6rem;
}

.about-copy .lead {
  font-size: 1.2rem;
  color: var(--ink);
  margin-bottom: 1.2rem;
  max-width: none;
}

.about-stats {
  max-width: var(--wrap);
  margin: clamp(3rem, 6vw, 5rem) auto 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2rem;
  text-align: center;
  padding-block: 2.5rem;
  border-top: 1px dashed var(--line-dash);
  border-bottom: 1px dashed var(--line-dash);
}

.stat-value {
  display: block;
  font-family: var(--serif);
  font-size: clamp(2.6rem, 4.5vw, 3.8rem);
  line-height: 1;
  margin-bottom: .6rem;
  font-variant-numeric: tabular-nums;
}

.stat-label {
  font-size: .85rem;
  color: var(--ink-soft);
}

/* ============================================================
   PRODUCTS
   ============================================================ */
.products { padding-top: 0; }

.product-block {
  display: grid;
  /* the photograph is a sample, not a billboard: it keeps to a
     modest column and the copy takes the rest */
  grid-template-columns: minmax(0, 28rem) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  padding-block: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px dashed var(--line-dash);
}
.product-block:last-of-type { border-bottom: 1px dashed var(--line-dash); }

.product-block.flip { grid-template-columns: minmax(0, 1fr) minmax(0, 28rem); }
.product-block.flip .product-visual { order: 2; }
.product-block.flip .product-info   { order: 1; }

/* Each family's photograph sits inside the page as a cut piece of
   cloth, alternating sides down the page, with the dashed selvedge
   on the edge that faces the copy. */
.product-visual {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 2px;
  background: var(--paper-warm);
}

/* the cut edge of the cloth, always on the side still in view */
.product-block:not(.flip) .product-visual { border-right: 6px dashed rgba(255, 255, 255, .55); }
.product-block.flip .product-visual { border-left: 6px dashed rgba(255, 255, 255, .55); }

/* the tag hangs off the inner edge, into the gutter between cloth and copy */
.product-block.flip .product-badge {
  right: auto;
  left: -1rem;
}

/* only the photograph is clipped: the badge is meant to hang off
   the right-hand edge, and an overflow rule on the block would shave it */
.visual-frame {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
}

/* the photograph is cut taller than its frame so it can drift with
   the scroll and still fill it; --py is the drift script writes in */
.visual-img {
  position: absolute;
  inset: -11% 0;
  width: 100%;
  height: 122%;
  object-fit: cover;
  transform: translateY(var(--py, 0px)) scale(1.16);
  filter: blur(12px) saturate(.9);
  transition:
    transform 1.6s var(--ease) var(--rd, 0ms),
    filter 1.4s var(--ease) var(--rd, 0ms);
}
.reveal-cloth.in .visual-img {
  transform: translateY(var(--py, 0px)) scale(1);
  filter: blur(0) saturate(1);
}
.product-block:hover .visual-img { transform: translateY(var(--py, 0px)) scale(1.05); }

/* light falling across the cloth, over whatever weave is set */
.product-visual::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(158deg, rgba(255, 255, 255, .20), rgba(42, 42, 39, .12));
}

.product-block:not(.flip) .visual-apparel { border-right-color: rgba(255, 255, 255, .45); }
.product-block.flip .visual-niche { border-left-color: rgba(255, 255, 255, .6); }

.product-badge {
  position: absolute;
  top: 1rem;
  right: -1rem;
  padding: .55rem .8rem .55rem 1.3rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 3px;
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  box-shadow: var(--shadow-tag);
  z-index: 2;
  outline: 1px dashed var(--line-dash);
  outline-offset: -4px;
}
.product-badge::before {
  content: "";
  position: absolute;
  left: .45rem;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1px solid var(--line-dash);
  transform: translateY(-50%);
}

.product-num {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.05rem;
  color: var(--sage);
}

.product-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 3.2vw, 2.6rem);
  line-height: 1.1;
  margin: .4rem 0 .8rem;
}

.product-lead {
  font-size: 1.1rem;
  margin-bottom: 1rem;
}

.product-info .body-text { margin-bottom: 1.6rem; }

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.chips li {
  font-size: .85rem;
  padding: .4em .9em;
  border: 1px solid var(--line-dash);
  border-radius: var(--r-sm);
  opacity: 0;
  transform: translateY(8px);
  transition:
    background .3s var(--ease),
    color .3s var(--ease),
    border-color .3s var(--ease),
    opacity .5s var(--ease) var(--cd, 0ms),
    transform .5s var(--ease) var(--cd, 0ms);
}
.in .chips li { opacity: 1; transform: none; }
.chips li:nth-child(1) { --cd: 260ms; }
.chips li:nth-child(2) { --cd: 320ms; }
.chips li:nth-child(3) { --cd: 380ms; }
.chips li:nth-child(4) { --cd: 440ms; }
.chips li:nth-child(5) { --cd: 500ms; }
.chips li:nth-child(6) { --cd: 560ms; }
.chips li:nth-child(7) { --cd: 620ms; }
.chips li:nth-child(8) { --cd: 680ms; }
.chips li:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.niche-cards {
  display: grid;
  gap: 1.5rem;
  margin-top: 1.2rem;
}
.niche-cards + .mini-title { margin-top: 1.6rem; }
/* two claims, ruled off the way a swatch is ruled off its reading */
.niche-card {
  padding-top: .9rem;
  border-top: 1px solid var(--ink);
}
.niche-card h4 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.3rem;
  margin-bottom: .3rem;
}
.niche-card p {
  font-size: .95rem;
  color: var(--ink-soft);
}

/* ============================================================
   KARTELA
   The swatch book for a product family: one card per quality,
   photographed on the product it ends up in. The rail scrolls
   rather than wrapping, so a family can carry as many swatches
   as it needs without the block growing taller.
   ============================================================ */
.kartela {
  grid-column: 1 / -1;
  order: 3;
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
  /* a grid item defaults to min-width:auto, which would let the rail's
     cards push the whole block wider than the page instead of scrolling */
  min-width: 0;
}

.kartela-title { margin-bottom: 1rem; }

.kartela-rail {
  display: flex;
  min-width: 0;
  gap: 1.1rem;
  margin-right: calc(-1 * var(--bleed));
  padding-right: var(--gutter);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  padding-bottom: .2rem;
  /* the page scrolls vertically, the rail horizontally: say so */
  cursor: grab;
}
.kartela-rail::-webkit-scrollbar { display: none; }
.kartela-rail.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.kartela-rail:focus-visible { outline-offset: 4px; }

.kartela-card {
  /* cards keep their size instead of stretching to fill the row, so
     a family with two or three swatches reads as a tidy card, not a
     wall of photographs */
  flex: 0 0 clamp(10rem, 14vw, 13rem);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity .7s var(--ease) var(--kd, 0ms),
    transform .7s var(--ease) var(--kd, 0ms);
}
.kartela.in .kartela-card { opacity: 1; transform: none; }

/* the cards deal out one after another, left to right */
.kartela-card:nth-child(1) { --kd: 0ms; }
.kartela-card:nth-child(2) { --kd: 90ms; }
.kartela-card:nth-child(3) { --kd: 180ms; }
.kartela-card:nth-child(4) { --kd: 270ms; }
.kartela-card:nth-child(5) { --kd: 360ms; }
.kartela-card:nth-child(6) { --kd: 450ms; }
.kartela-card:nth-child(n+7) { --kd: 520ms; }

/* a swatch is a cut piece of cloth: square corners, ruled off from
   its reading the way a chip is stapled above its label */
.kartela-shot {
  display: block;
  aspect-ratio: 4 / 5;
  border-radius: 2px;
  overflow: hidden;
  background: var(--paper-warm);
}

.kartela-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: blur(10px) saturate(.82);
  transform: scale(1.14);
  transition:
    transform 1.5s var(--ease) var(--kd, 0ms),
    filter 1.2s var(--ease) var(--kd, 0ms);
}
.kartela.in .kartela-shot img { filter: blur(0) saturate(.82); transform: scale(1); }
.kartela-card:hover .kartela-shot img {
  transform: scale(1.07);
  filter: blur(0) saturate(1);
  transition: transform .6s var(--ease), filter .4s var(--ease);
}

.kartela-name {
  display: block;
  margin-top: .9rem;
  padding-top: .75rem;
  border-top: 1px solid var(--ink);
  font-family: var(--serif);
  font-size: 1.2rem;
  line-height: 1.2;
}

/* pinned to the foot of the card so the weights line up across the rail
   however many lines the quality list above it runs to */
.kartela-gsm {
  display: block;
  margin-top: auto;
  padding-top: .3rem;
  font-size: .72rem;
  letter-spacing: .14em;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

/* which of our qualities this product group is woven from */
.kartela-qualities {
  display: block;
  margin-top: .35rem;
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--sage);
}

/* how far along the rail you are */
.kartela-progress {
  display: block;
  height: 1px;
  margin-top: 1rem;
  background: var(--line);
}
.kartela-progress[hidden] { display: none; }
.kartela-progress i {
  display: block;
  height: 100%;
  width: var(--seen, 100%);
  margin-left: var(--from, 0%);
  background: var(--sage);
  transition: width .25s var(--ease), margin-left .25s var(--ease);
}

/* the same reading the hero gives, scoped to this family */
.kartela-strip {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2rem);
  margin-top: 1rem;
  padding-top: .9rem;
  border-top: 1px dashed var(--line-dash);
}
.kartela-strip .spec-value {
  display: block;
  font-family: var(--serif);
  font-size: 1.05rem;
  white-space: nowrap;
}

/* ============================================================
   FABRIC TABLE
   ============================================================ */
.fabrics { padding-top: 0; }
.fabrics .section-head { margin-bottom: clamp(2rem, 4vw, 3rem); }

.table-wrap {
  overflow-x: auto;
  padding-bottom: .2rem;
}

.fabric-table {
  width: 100%;
  min-width: 680px;
}

.fabric-table th {
  text-align: left;
  padding: .8rem 1rem;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--ink);
}
.fabric-table th.col-swatch { width: 3.5rem; }

.fabric-table tbody tr {
  border-bottom: 1px solid var(--line);
  transition: background .25s var(--ease);
}
.fabric-table tbody tr:hover { background: #f0eee8; }
.fabric-table tr.row-accent { background: rgba(111, 127, 106, .1); }
.fabric-table tr.row-accent .fabric-name { color: var(--sage); }

.fabric-table td { padding: 1.2rem 1rem; font-size: .95rem; font-variant-numeric: tabular-nums; }
.fabric-table td.cell-swatch { padding: 1rem; }

.fabric-swatch {
  display: block;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 3px;
  box-shadow: inset 0 0 0 1px rgba(42, 42, 39, .12);
  background-color: var(--paper-warm);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.fabric-table tbody tr:hover .fabric-swatch {
  transform: scale(1.12) rotate(-3deg);
  box-shadow: inset 0 0 0 1px rgba(42, 42, 39, .12), 0 8px 18px -10px rgba(42, 42, 39, .5);
}
.fabric-name {
  font-family: var(--serif);
  font-size: 1.35rem;
  font-weight: 400;
}

.fabric-table .cell-use { color: var(--ink-soft); font-size: .92rem; }

/* weight, drawn to scale against the heaviest quality we weave */
.cell-weight { white-space: nowrap; }
.gsm-bar {
  display: block;
  height: 3px;
  width: 5.5rem;
  margin-top: .5rem;
  border-radius: 2px;
  background: var(--line);
  overflow: hidden;
}
.gsm-bar::before {
  content: "";
  display: block;
  height: 100%;
  width: 0;
  background: var(--sage);
  opacity: .55;
  transition: width 1.1s var(--ease) var(--rd, 0ms);
}
.fabric-table tbody tr.in .gsm-bar::before { width: var(--w, 50%); }
.row-accent .gsm-bar::before { opacity: 1; }

.table-note {
  margin-top: 1.4rem;
  font-size: .85rem;
  color: var(--ink-faint);
  text-align: center;
}

/* ============================================================
   WARP BAND
   A full-width look down a loom, sat between the cloth and the ink.
   The photograph is cut taller than the band so it can drift against
   the scroll; --py is the offset script writes each frame.
   ============================================================ */
.warp-band {
  position: relative;
  height: clamp(16rem, 34vw, 26rem);
  overflow: hidden;
  background: var(--forest);
  border-top: 1px dashed var(--line-dash);
}

.warp-img {
  position: absolute;
  inset: -22% 0;
  width: 100%;
  height: 144%;
  object-fit: cover;
  transform: translateY(var(--py, 0px));
  will-change: transform;
}

/* On a phone the band takes the photo's own shape, so the whole
   warehouse shows instead of a slice blown up for the drift. */
@media (max-width: 640px) {
  .warp-band { height: calc(100vw * 799 / 1967); }
  .warp-img {
    inset: 0;
    height: 100%;
    transform: none;
  }
}

/* the same woven grid that runs over the CTA band, so the two rhyme */
.warp-band::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: .14;
  background-image:
    repeating-linear-gradient(0deg,  var(--paper) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, var(--paper) 0 1px, transparent 1px 4px);
  animation: clothDrift 7s linear infinite;
}
/* at phone size the 4px grid beats against the screen's own pixels and
   reads as a mesh over the photo, so it stays on larger screens only */
@media (max-width: 640px) {
  .warp-band::after { display: none; }
}

/* ============================================================
   PRINTING
   ============================================================ */
/* Printing is where ink meets cloth, so it is the dark passage of the
   page: it carries straight on from the loom band above it, and the
   three samples are the only light in it. */
.printing {
  background: var(--forest);
  color: var(--paper);
  border-bottom: 1px dashed var(--line-dash);
}
.printing .eyebrow { color: var(--sage-mist); }
.printing .lead { color: rgba(247, 245, 240, .72); }

.tech-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.2rem;
}

.tech-card { padding: 0; }

/* what each technology actually puts on the cloth */
.print-sample {
  display: block;
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 2px;
  overflow: hidden;
  background: rgba(247, 245, 240, .08);
}

.print-sample img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transform: scale(1.12);
  filter: blur(12px) saturate(.88);
  transition: transform 1.6s var(--ease) var(--rd, 0ms), filter 1.2s var(--ease) var(--rd, 0ms);
}
.print-sample.in img { transform: scale(1); filter: blur(0) saturate(.88); }
.tech-card:hover .print-sample img {
  transform: scale(1.06);
  filter: blur(0) saturate(1);
  transition: transform .5s var(--ease), filter .4s var(--ease);
}

/* a machine of ours rather than a photograph of a hall: it stands on the
   same pale stage as the turntable beside it, with no weave drawn over */
.print-sample--plate { background: var(--paper); }
.print-sample.print-sample--plate::after { content: none; }
.print-sample--plate img { filter: blur(12px); }
.print-sample--plate.in img { filter: blur(0); }
.tech-card:hover .print-sample--plate img { filter: blur(0); }

.print-sample::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(90deg, rgba(42, 42, 39, .12) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg,  rgba(255, 255, 255, .10) 0 1px, transparent 1px 3px);
}

/* ---------- The turntable ----------
   The press stands on a lit stage cut out of the dark section, the one
   pale thing in the printing passage. The machine turns under the hand
   and the thread across the foot of the stage fills as the frames
   arrive. */
.spin {
  margin: 0;
}

/* it stands in for the photograph on the first card, so it keeps that
   card's shape and the other two stay level with it */
.spin-stage {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--paper);
  border-radius: 2px;
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;
  outline-offset: 3px;
}
.spin-stage:active { cursor: grabbing; }
.spin.is-turning .spin-stage { cursor: grabbing; }

.spin-frame {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}

/* the turning happens on a canvas: swapping the src of an <img> shows a
   blank frame while the next one decodes. The <img> above stays as the
   still the page falls back to before the frames arrive. */
.spin-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0;
  transition: opacity .3s var(--ease);
}
.spin.is-ready .spin-canvas { opacity: 1; }
.spin.is-ready .spin-frame { visibility: hidden; }

/* the loading thread, drawn while the frames come in */
.spin-thread {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: rgba(42, 42, 39, .08);
  opacity: 1;
  transition: opacity .5s var(--ease);
}
.spin-thread i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--forest);
  transition: width .2s linear;
}
.spin.is-ready .spin-thread { opacity: 0; }

/* the hint sits in the corner until the machine has been taken hold of */
.spin-hint {
  position: absolute;
  left: 1.1rem;
  bottom: 1rem;
  padding: .42rem .8rem;
  border: 1px solid rgba(42, 42, 39, .22);
  border-radius: 999px;
  background: rgba(247, 245, 240, .78);
  backdrop-filter: blur(4px);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.spin.is-ready .spin-hint { opacity: .85; transform: translateY(0); }
.spin.is-held .spin-hint { opacity: 0; transform: translateY(6px); }

@media (max-width: 860px) {
  .spin-hint { left: .8rem; bottom: .7rem; font-size: .68rem; }
}

/* the aside under the first card, where the turntable is explained */
.tech-note {
  margin-top: .9rem;
  padding-left: .9rem;
  border-left: 1px solid rgba(247, 245, 240, .28);
  font-size: .86rem;
  font-style: italic;
  color: rgba(247, 245, 240, .58);
}

/* the rule under each sample does the job the card border used to */
.tech-kicker {
  display: block;
  margin-top: 1.3rem;
  padding-top: .9rem;
  border-top: 1px solid rgba(247, 245, 240, .28);
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
  color: var(--sage-mist);
}

.tech-card h3 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.5rem;
  margin: .3rem 0 .7rem;
}

.tech-card p {
  font-size: .95rem;
  color: rgba(247, 245, 240, .72);
}

/* ============================================================
   QUALITY
   ============================================================ */
/* the second half of About us: how we work, after the numbers */
.about-work { margin-top: clamp(4rem, 8vw, 6.5rem); }

.quality-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 clamp(2rem, 5vw, 4rem);
  border-top: 1px solid var(--ink);
}

.q-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.2rem;
  padding-block: 1.8rem;
  border-bottom: 1px dashed var(--line-dash);
}

.q-num {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.1rem;
  color: var(--sage);
}

.q-card h3 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.45rem;
  margin-bottom: .4rem;
}

.q-card p {
  font-size: .95rem;
  color: var(--ink-soft);
}

/* ---------- certification band ---------- */
.certs {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--ink);
}

.certs-label {
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: clamp(1.4rem, 3vw, 2.2rem);
}

.certs-row {
  display: grid;
  /* however many marks there are, they share the line evenly and wrap
     onto a second one rather than squeezing */
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: clamp(1rem, 2.2vw, 1.8rem);
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.cert {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 5.5rem;
  padding: 1rem;
  border: 1px dashed var(--line-dash);
  border-radius: var(--r-sm);
  background: var(--white);
  /* the marks are other people's colour, so they sit a shade back from
     our own palette and come forward when you look at them */
  filter: saturate(.88);
  opacity: .92;
  transition: filter .4s var(--ease), opacity .4s var(--ease),
              transform .4s var(--ease), border-color .4s var(--ease);
}
.cert:hover {
  filter: none;
  opacity: 1;
  transform: translateY(-2px);
  border-color: var(--ink-faint);
}

.cert-logo {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 3.2rem;
  object-fit: contain;
}
/* GOTS is a round badge where the others are wide lockups; a little more
   height gives it the same weight on the line */
.cert-logo[src$="gots.svg"] { max-height: 4.2rem; }

/* the stand-in while the certifier's own artwork is not in the repo */
.cert-lockup {
  display: grid;
  gap: .25rem;
  text-align: center;
}
/* a display of its own would otherwise outrank the hidden attribute and
   the stand-in would show next to the picture it is standing in for */
.cert-lockup[hidden] { display: none; }
.cert-lockup b {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.35rem;
  line-height: 1;
  letter-spacing: -.01em;
  color: var(--ink);
}
.cert-lockup sup { font-size: .5em; vertical-align: super; }
.cert-lockup i {
  font-style: normal;
  font-size: .68rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.certs-note {
  margin-top: 1.2rem;
  font-size: .82rem;
  color: var(--ink-faint);
}

@media (max-width: 560px) {
  .certs-row { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   CONTACT
   ============================================================ */
.contact-panel {
  max-width: var(--narrow);
  margin-inline: auto;
  padding: clamp(2.2rem, 5vw, 3.4rem) clamp(1.4rem, 5vw, 3rem);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-soft);
  text-align: center;
  transition: border-color .35s var(--ease), box-shadow .35s var(--ease), transform .35s var(--ease);
}
.contact-panel:hover {
  border-color: var(--sage);
  transform: translateY(-4px);
  box-shadow: var(--shadow-card);
}

.contact-label {
  display: block;
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.contact-panel .contact-label { margin-bottom: 1rem; }

.contact-mail {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  max-width: 100%;
  padding-bottom: .4rem;
  font-family: var(--serif);
  font-size: clamp(1.4rem, 4.4vw, 2.4rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--ink);
  border-bottom: 1px solid var(--line-dash);
  transition: color .3s var(--ease), border-color .3s var(--ease);
}

.contact-mail-text { overflow-wrap: anywhere; }

.contact-mail:hover {
  color: var(--sage);
  border-bottom-color: var(--sage);
}

.contact-arrow {
  color: var(--sage);
  transition: transform .3s var(--ease);
}

.contact-mail .contact-arrow { font-size: .55em; }
.contact-mail:hover .contact-arrow { transform: translateX(5px); }

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer {
  border-top: 1px solid var(--ink);
  padding-top: clamp(3rem, 6vw, 4.5rem);
}

.footer-inner {
  display: grid;
  grid-template-columns: 1.3fr 2fr;
  gap: clamp(2rem, 5vw, 4rem);
  padding-bottom: 3rem;
  border-bottom: 1px dashed var(--line-dash);
}

.footer-tag {
  margin-top: 1rem;
  max-width: 34ch;
  font-size: .95rem;
  color: var(--ink-soft);
}

.footer-nav {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 4rem);
}

.footer-nav a { position: relative; }
.footer-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1px;
  background: var(--sage);
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform .4s var(--ease);
}
.footer-nav a:hover::after { transform: scaleX(1); transform-origin: 0 50%; }

.footer-nav h4 {
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .9rem;
}
.footer-nav a {
  display: block;
  padding-block: .25rem;
  font-size: .95rem;
  color: var(--ink-soft);
}

.footer-base {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  padding-block: 1.4rem;
  font-size: .85rem;
  color: var(--ink-faint);
}

.footer-made {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
}

/* ============================================================
   MOTION
   Nothing here bounces. Cloth settles, thread draws, light travels.
   Every element below carries --rd, the delay script hands it so
   things in one group arrive in sequence rather than all at once.
   ============================================================ */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity .9s var(--ease) var(--rd, 0ms),
    transform .9s var(--ease) var(--rd, 0ms);
}
.reveal.in { opacity: 1; transform: none; }

/* copy that arrives from the side of the page it belongs to */
.reveal-left  { transform: translateX(-32px); }
.reveal-right { transform: translateX(32px); }
.reveal-left.in,
.reveal-right.in { transform: none; }

/* Both wipes below use a mask rather than clip-path on purpose:
   an element clipped to nothing has no visible area, and
   IntersectionObserver then never reports it on screen, so it would
   sit waiting for a reveal that can never fire. A mask is paint-only.
   The mask is a hard-edged gradient twice the height of the element,
   slid from fully-past (hidden) to fully-over (shown); 300% wide so a
   badge hanging off the selvedge is never shaved away. */
.reveal-wipe,
.reveal-title,
.reveal-cloth {
  -webkit-mask-image: linear-gradient(to bottom, #000 50%, transparent 50%);
          mask-image: linear-gradient(to bottom, #000 50%, transparent 50%);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: 300% 200%;
          mask-size: 300% 200%;
  -webkit-mask-position: 50% 100%;
          mask-position: 50% 100%;
}
.reveal-wipe.in,
.reveal-title.in,
.reveal-cloth.in {
  -webkit-mask-position: 50% 0%;
          mask-position: 50% 0%;
}

/* a heading lifts clear of its own baseline */
.reveal-title {
  transform: translateY(.16em);
  transition:
    opacity .55s var(--ease) var(--rd, 0ms),
    -webkit-mask-position 1.05s var(--ease) var(--rd, 0ms),
    mask-position 1.05s var(--ease) var(--rd, 0ms),
    transform 1.05s var(--ease) var(--rd, 0ms);
}
.reveal-title.in { transform: none; }

/* cloth off the roll: the weave is drawn down the bolt */
.reveal-cloth {
  opacity: 1;
  transform: none;
  transition:
    -webkit-mask-position 1.25s var(--ease) var(--rd, 0ms),
    mask-position 1.25s var(--ease) var(--rd, 0ms);
}

/* table rows shift less than blocks do, or the table looks loose */
.fabric-table tbody tr.reveal { transform: translateY(10px); }
.fabric-table tbody tr.reveal.in { transform: none; }

@keyframes fadeIn { to { opacity: 1; } }
@keyframes lineUp { to { transform: translateY(0); } }
@keyframes marquee { to { transform: translateX(-50%); } }
@keyframes railDwell { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes clothDrift { to { background-position: 4px 4px, 4px 4px; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero-inner { opacity: 1; animation: none; }
  .hero-title .line-inner { transform: none; animation: none; }
  .hero-band { transform: none !important; }
  .marquee-track { animation: none; }
  .reveal,
  .reveal-title,
  .reveal-cloth {
    opacity: 1;
    transform: none;
    transition: none;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .rail-swatch, .rail-detail { transition: none; }
  .rail-swatch::after { display: none; }
  .warp-band::after { animation: none; }
  /* the hover rules that zoom a photograph are more specific than the
     plain ones, so they have to be named here too or they still fire */
  .visual-img,
  .print-sample img,
  .product-block:hover .visual-img,
  .tech-card:hover .print-sample img,
  .kartela-card:hover .kartela-shot img,
  .fabric-table tbody tr:hover .fabric-swatch { transform: none; filter: none; transition: none; }
  .kartela-card { opacity: 1; transform: none; transition: none; }
  .kartela-shot img { filter: none; transform: none; transition: none; }
  .warp-img { transform: none; }
  .rail-swatch.is-active { background-size: cover; }
  .gsm-bar::before { width: var(--w, 50%); transition: none; }
  .chips li { opacity: 1; transform: none; }
  .mobile-menu a { opacity: 1; transform: none; }
  .btn:hover,
  .contact-panel:hover,
  .spec-card:hover { transform: none; }
  .btn-primary::after, .btn-light::after { display: none; }
  .site-header.tucked { transform: none; }
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 980px) {
  .main-nav { display: none; }
  .menu-toggle { display: flex; }
  .btn-header { display: none; }

  .product-block,
  .product-block.flip { grid-template-columns: 1fr; }
  .product-block.flip .product-visual { order: 0; }
  .product-block.flip .product-info   { order: 0; }

  /* one column, so the cloth runs to both edges */
  .product-visual,
  .product-block.flip .product-visual,
  .product-block:not(.flip) .product-visual {
    aspect-ratio: 16 / 10;
    margin-inline: calc(-1 * var(--bleed));
    border-left: 0;
    border-right: 0;
  }
  .product-block .product-badge { top: auto; bottom: 1rem; left: var(--gutter); right: auto; }

  .tech-grid { gap: 2rem 1.2rem; }

  .tech-grid,
  .quality-grid,
  .about-stats { grid-template-columns: 1fr 1fr; }


  .kartela-card { flex-basis: 11rem; }

  .swatch-rail { flex-direction: column; aspect-ratio: auto; }
  .rail-swatch {
    flex: 0 0 auto;
    min-height: 5.4rem;
    border-right: 0;
    border-bottom: 1px solid rgba(247, 245, 240, .55);
    gap: .8rem;
  }
  .rail-swatch:last-child { border-bottom: 0; }
  .rail-swatch.is-active { flex-grow: 0; }
  .rail-detail {
    max-width: none;
    max-height: 0;
    overflow: hidden;
    transition: max-height .45s var(--ease), opacity .45s var(--ease);
  }
  .rail-swatch.is-active .rail-detail { max-height: 9rem; }
  .rail-swatch.is-active {
    background-image: linear-gradient(180deg, rgba(18, 18, 16, .8) 0%, rgba(18, 18, 16, .66) 60%, rgba(18, 18, 16, .3) 100%), var(--rail-photo);
  }
  .rail-teatowel { --rail-photo: url("../assets/img/rail-teatowel.jpg"); }
  .rail-apron    { --rail-photo: url("../assets/img/rail-apron.jpg"); }
  .rail-bag      { --rail-photo: url("../assets/img/rail-bag.jpg"); }
  .rail-muslin   { --rail-photo: url("../assets/img/rail-muslin.jpg"); }

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

  .spec-card {
    position: static;
    transform: none;
    margin-top: 1rem;
    padding-left: 1.1rem;
    flex-wrap: wrap;
    justify-content: space-between;
    row-gap: 1rem;
  }
  .spec-card::before { display: none; }
  .spec-divider { display: none; }
}

@media (max-width: 640px) {
  body { font-size: 16px; }

  .hero-eyebrow::before,
  .hero-eyebrow::after { width: 1.4rem; }
  .hero-ctas .btn { flex: 1 1 auto; text-align: center; }


  .footer-nav { grid-template-columns: 1fr; gap: 1.5rem; }

  .product-badge { top: auto; right: auto; bottom: 1rem; left: 1rem; }

  .kartela-card { flex-basis: 42vw; }
  .kartela-strip { flex-wrap: wrap; row-gap: .8rem; }
  .kartela-strip .spec-divider { display: none; }
  .lang-label { display: none; }
}
