/* METANOIA — metanoiaftp.com
   Daylight resistance. Bone canvas, soot ink, one Protest Red per screen.
   Taste file: Metanoia HQ Resources/METANOIA-DNA.md (it wins). */

:root {
  --bone: #EDE6DA;
  --unbleached: #D9CFBF;
  --earth: #6B5138;
  --olive: #5A5A40;
  --soot: #26221E;
  --signal: #B3301B;
  --hairline: rgba(107, 81, 56, 0.3);
  --pill-h: 52px;
  --metabar-h: 44px;
  --gutter: clamp(20px, 4vw, 64px);
  --grain-opacity: 0.035;
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: auto; }
body {
  background: var(--bone);
  color: var(--soot);
  font-family: 'Archivo', Helvetica, Arial, sans-serif;
  font-variation-settings: 'wdth' 100, 'wght' 450;
  font-size: 16px;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; background: none; border: none; cursor: pointer; color: inherit; }
::selection { background: var(--soot); color: var(--bone); }

/* Arabic companion */
[lang="ar"] { font-family: 'Noto Kufi Arabic', sans-serif; direction: rtl; }

/* ---------- type roles ---------- */
.placard {
  font-variation-settings: 'wdth' 63, 'wght' 900;
  font-weight: 900;
  text-transform: uppercase;
  line-height: 0.95;
  letter-spacing: -0.01em;
}
.subhead {
  font-variation-settings: 'wdth' 80, 'wght' 700;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.label {
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 12px;
  color: var(--olive);
}
.label--ink { color: var(--soot); }

/* ---------- layers ---------- */
#dotfield {
  position: fixed; inset: 0;
  width: 100vw; height: 100dvh;
  z-index: 0; pointer-events: none;
}
.grain {
  position: fixed; inset: -50px;
  z-index: 9; pointer-events: none;
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}
.page { position: relative; z-index: 1; transition: filter 0.45s ease; }
body.menu-open .page { filter: blur(10px); }
body.golden .page { filter: sepia(0.05) saturate(1.03); }
body.menu-open.golden .page { filter: blur(10px) sepia(0.05); }

/* ---------- preloader ---------- */
#preloader {
  position: fixed; inset: 0; z-index: 100;
  background:
    radial-gradient(rgba(38, 34, 30, 0.16) 1px, transparent 1.5px) 0 0 / 14px 14px,
    var(--bone);
  display: flex; align-items: center; justify-content: center;
}
.pl-mark { position: relative; font-size: clamp(40px, 9vw, 120px); }
.pl-mark span {
  display: block; mix-blend-mode: multiply;
  position: absolute; inset: 0; white-space: nowrap;
}
.pl-mark span:nth-child(1) { color: var(--earth); position: relative; }
.pl-mark span:nth-child(2) { color: var(--olive); }
.pl-mark span:nth-child(3) { color: var(--soot); }
.pl-count {
  position: absolute; left: var(--gutter); bottom: calc(var(--metabar-h) + 18px);
  font-variation-settings: 'wdth' 63, 'wght' 900;
  font-size: clamp(28px, 5vw, 56px); text-transform: uppercase;
}
.pl-label {
  position: absolute; right: var(--gutter); bottom: calc(var(--metabar-h) + 26px);
}
body.loaded #preloader { display: none; }

/* ---------- nav pill ---------- */
#navpill {
  position: fixed; top: 16px; left: 50%; transform: translateX(-50%);
  z-index: 50;
  width: min(560px, calc(100vw - 2 * var(--gutter)));
  background: var(--soot); color: var(--bone);
  border-radius: 4px;
  display: flex; align-items: center; justify-content: space-between;
  height: var(--pill-h); padding: 0 14px;
}
#navpill .label { color: var(--bone); }
#pill-mark { width: 42px; height: 42px; display: block; object-fit: contain; filter: grayscale(1) brightness(0) invert(1); }
#pill-label { flex: 1; text-align: center; font-size: 11px; white-space: nowrap; overflow: hidden; }
#pill-bag {
  color: var(--bone); font-size: 10px; white-space: nowrap;
  padding: 8px 12px; margin-right: 4px;
  border: 1px solid rgba(237, 230, 218, 0.3); border-radius: 2px;
  transition: border-color 0.25s ease;
}
#pill-bag:hover, #pill-bag.has-items { border-color: var(--bone); }
#burger { display: flex; flex-direction: column; gap: 5px; padding: 8px 2px; }
#burger i { display: block; width: 20px; height: 2px; background: var(--bone); transition: transform 0.35s ease, opacity 0.35s ease; }
body.menu-open #burger i:nth-child(1) { transform: translateY(3.5px) rotate(45deg); }
body.menu-open #burger i:nth-child(2) { transform: translateY(-3.5px) rotate(-45deg); }

#menu {
  position: fixed; top: calc(16px + var(--pill-h) + 8px); left: 50%;
  transform: translateX(-50%) translateY(-8px);
  z-index: 49;
  width: min(560px, calc(100vw - 2 * var(--gutter)));
  background: var(--bone); color: var(--soot);
  border: 1px solid var(--hairline); border-radius: 4px;
  padding: 8px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s linear 0.3s;
}
body.menu-open #menu {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: translateX(-50%) translateY(0);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
#menu a.menu-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 16px 12px;
  border-bottom: 1px solid var(--hairline);
  font-variation-settings: 'wdth' 80, 'wght' 700;
  text-transform: uppercase; letter-spacing: 0.04em; font-size: 18px;
  clip-path: inset(0 0 0 0);
}
#menu a.menu-row .label { pointer-events: none; }
#menu .menu-cta {
  display: block; margin-top: 8px; padding: 16px 12px; text-align: center;
  background: var(--signal); color: var(--bone);
  font-variation-settings: 'wdth' 80, 'wght' 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  border-radius: 2px;
}

/* ---------- sections ---------- */
section { position: relative; padding: clamp(90px, 14vh, 160px) var(--gutter); }
.section-label { display: block; margin-bottom: 28px; }

/* hero */
#hero {
  min-height: 100dvh;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding-bottom: calc(var(--metabar-h) + 48px);
  overflow: hidden;
}
#hero .hero-media {
  position: absolute; inset: 0; z-index: -1;
}
#hero .hero-media > video,
#hero .hero-media > img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(1.2) contrast(1.05);
}
#hero .hero-media > video { z-index: 0; opacity: 0; }
#hero .hero-media > img {
  z-index: 1;
  transition: opacity 0.3s ease;
}
#hero .hero-media.is-video-playing > video { opacity: 1; }
#hero .hero-media.is-video-playing > img { opacity: 0; }
/* stationary print screen: same 16px/1.3px grid as the dotfield canvas,
   phase-aligned to it; main.js counter-translates so it holds still in
   viewport space while the photo scrolls underneath */
#hero .hero-media .shade {
  position: absolute; inset: 0; z-index: 2;
  background-image: radial-gradient(circle, rgba(38, 34, 30, 0.38) 1.3px, transparent 1.7px);
  background-size: 16px 16px;
  mix-blend-mode: multiply;
  will-change: transform;
  pointer-events: none;
}
/* the halftone print (js/halftone.js paints it). It sits ABOVE both washes,
   not under them: at rest the ink lives in the bottom band, which is exactly
   where the dark scrim and the bone wash are heaviest, and underneath them the
   colour separations turn to mud. Over the top the dots read as ink on paper,
   and during the scroll dissolve the canvas's own bone correctly covers the
   scrim as the frame turns to blank stock. */
#hero .hero-media canvas.halftone {
  position: absolute; inset: 0; z-index: 6;
  width: 100%; height: 100%;
  pointer-events: none;
}
/* legibility scrim. The loop swings from bright sky to near-black across
   its 18s, so the type band is held to a fixed dark floor instead of
   gambling on whichever frame is up. Sits over the halftone, under the
   bone wash that blends the hero into the page. */
#hero .hero-media::before {
  content: ''; position: absolute; inset: 0; z-index: 4;
  background: linear-gradient(180deg,
    rgba(18, 16, 14, 0) 24%,
    rgba(18, 16, 14, 0.32) 54%,
    rgba(18, 16, 14, 0.66) 82%,
    rgba(18, 16, 14, 0.70) 100%);
  pointer-events: none;
}
/* The join between film and paper, and nothing else. It used to also lay an
   18% bone haze over the top third of the frame, which milked the footage for
   no reason once the type went bone and the dark scrim took over legibility:
   that is gone. What is left is the seam. The bone page (#why) starts straight
   under the hero, so without some join the film would cut to paper on a hard
   line. Held to the last 1.5% of the hero, down from 8%, so it reads as an
   edge rather than a fade and never competes with the ink. */
#hero .hero-media::after {
  content: ''; position: absolute; inset: 0; z-index: 5;
  background: linear-gradient(180deg, rgba(237, 230, 218, 0) 99.4%, var(--bone) 100%);
  pointer-events: none;
}
/* "For the people." — one line where it fits; the only legal break is before
   "people" ("For the" is non-breaking in the markup), so a wrapped headline
   reads FOR THE / PEOPLE. */
#hero h1 {
  font-size: clamp(44px, 8.6vw, 148px);
  color: var(--bone);
  text-shadow: 0 2px 48px rgba(18, 16, 14, 0.4);
}
/* under 600px the one-liner runs gutter to gutter with nothing to spare, so
   the headline is held to two lines: FOR THE / PEOPLE. */
@media (max-width: 600px) {
  #hero h1 { max-width: 9ch; }
}
#hero .label { color: var(--bone); }
/* the kicker sits under the headline and needs its own air: without this the
   0.95 leading drops it straight onto the descenders */
#hero .label--ink { display: block; margin-top: clamp(14px, 2vh, 22px); }
#hero .hero-row {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap; margin-top: 40px;
}

/* statement: the dictionary entry.
   Half the height of the old four-sentence block. The academic read comes from
   layout alone (hairline, interpuncts, phonetic bracket, hanging numeral), not
   from a borrowed serif: only Archivo and Noto Kufi are on disk, and a serif
   here would read as a museum rather than as Metanoia. */
#why { padding-top: clamp(44px, 6vh, 72px); padding-bottom: clamp(44px, 6vh, 72px); }

#why .entry { margin-top: clamp(18px, 2.4vh, 30px); }
#why .entry-word {
  font-size: clamp(46px, 8.6vw, 132px);
  line-height: 0.9;
  letter-spacing: -0.02em;
}
#why .entry-body { margin-left: 0; }

/* the apparatus. All of it 12px and olive, so the headword carries the scale
   contrast on its own. */
#why .entry-meta,
#why .entry-root {
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--olive); line-height: 1.9;
}
#why .entry-meta { display: flex; flex-wrap: wrap; gap: 0 20px; margin-top: 14px; }
#why .entry-phon { letter-spacing: 0.06em; text-transform: none; }
#why .entry-root { letter-spacing: 0.1em; }
/* Archivo carries no slant or italic axis (weight 100-900, width 62-125% only),
   so a dictionary's italic root is set by weight and ink instead of by a
   synthetic oblique, which looks cheap at 12px with this much letterspacing. */
#why .entry-root i { font-variation-settings: 'wdth' 100, 'wght' 800; font-style: normal; color: var(--soot); }

#why .entry-rule {
  height: 1px; background: var(--hairline);
  max-width: 34ch; margin: 14px 0 16px;
}

/* the sense. Hanging numeral: the definition indents under itself the way a
   printed lexicon sets it, never under the numeral. */
#why .entry-sense {
  display: flex; gap: 0.7em;
  font-variation-settings: 'wdth' 80, 'wght' 700;
  font-weight: 700;
  font-size: clamp(20px, 2.5vw, 34px);
  line-height: 1.24; max-width: 30ch;
}
#why .entry-num {
  flex: none; color: var(--olive);
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: 12px; letter-spacing: 0.14em;
  padding-top: 0.55em;
}
#why .entry-def .w { opacity: 0.22; display: inline-block; }

/* the only sentence on the page that says "we" */
#why .why-line {
  margin-top: clamp(24px, 3.2vh, 38px);
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: clamp(15px, 1.5vw, 19px);
  letter-spacing: 0.01em; max-width: 34ch;
  color: var(--soot);
}
#why .side-label { position: absolute; right: var(--gutter); bottom: clamp(44px, 6vh, 72px); }

/* shop rail: a solid field lets the pieces breathe apart from the editorial dot field */
#shop { background: var(--bone); }
#shop h2 { font-size: clamp(40px, 7vw, 110px); margin-bottom: 12px; }
/* a caption under the placard, not a body paragraph. Three declaratives that
   answer "why does it cost that" before the first price comes into view. */
#shop .shop-intro {
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: clamp(14px, 1.35vw, 17px);
  letter-spacing: 0.03em; line-height: 1.5;
  color: var(--olive); max-width: 44ch;
  margin-top: 4px; margin-bottom: 56px;
}
.artifact { border-top: 1px solid var(--hairline); }
.artifact:last-of-type { border-bottom: 1px solid var(--hairline); }
.artifact-head {
  width: 100%;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 0.62fr);
  gap: clamp(12px, 3vw, 40px); align-items: center;
  padding: 22px 0; text-align: left;
}
.artifact-toggle {
  display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(120px, 0.5fr) auto;
  gap: clamp(12px, 3vw, 40px); align-items: center;
  text-align: left; padding: 0;
}
.artifact-head h3 {
  font-variation-settings: 'wdth' 63, 'wght' 900;
  font-weight: 900; text-transform: uppercase; line-height: 1;
  font-size: clamp(20px, 2.6vw, 34px);
}
.artifact .tags { display: flex; gap: 8px; flex-wrap: wrap; }
.artifact .tag {
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  font-variation-settings: 'wdth' 100, 'wght' 500;
  border: 1px solid var(--hairline); padding: 4px 8px; border-radius: 2px;
  color: var(--olive);
}
/* ---------- the way in ----------
   Added 2026-08-28. The closed row used to carry a bare ( + ) at 12px olive,
   which named nothing: a stranger could not tell that sizes, stock and a buy
   button were folded inside, and no price was visible until they guessed.
   The row now states its price and carries a bordered control that names the
   reward. Earth on bone measures 5.92:1 and the inverted hover state measures
   the same, both clear of AA at this 11px label size. The pill's hairline is
   decoration; the label carries the meaning. */
.artifact .open-cue {
  justify-self: end; display: grid; justify-items: end; gap: 8px;
}
.artifact .open-cue .price {
  font-variation-settings: 'wdth' 100, 'wght' 600;
  font-size: 14px; letter-spacing: 0.04em; color: var(--earth);
  white-space: nowrap;
}
.artifact .cue-pill {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 14px; border: 1px solid var(--earth); border-radius: 2px;
  white-space: nowrap;
  transition: background-color 0.35s ease, color 0.35s ease;
}
.artifact .cue-label {
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--earth);
  transition: color 0.35s ease;
}
.artifact .plus {
  font-variation-settings: 'wdth' 100, 'wght' 600;
  font-size: 14px; line-height: 1; color: var(--earth);
  transition: color 0.35s ease;
}
.artifact-toggle:hover .cue-pill,
.artifact-toggle:focus-visible .cue-pill { background: var(--earth); }
.artifact-toggle:hover .cue-label,
.artifact-toggle:hover .plus,
.artifact-toggle:focus-visible .cue-label,
.artifact-toggle:focus-visible .plus { color: var(--bone); }
/* single placeholder frame: hover cycles the other shots, press opens the gallery */
.artifact .frame {
  position: relative; display: block; padding: 0;
  justify-self: stretch;
  aspect-ratio: 4 / 3;
  border-radius: 2px; overflow: hidden;
  background: var(--unbleached);
  transform: translateZ(0);
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.artifact .frame::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  border: 1px solid var(--hairline); border-radius: 2px;
}
.artifact .frame:hover, .artifact .frame:focus-visible { transform: scale(1.012); }
.artifact .frame:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }
.frame-stack { position: absolute; inset: 0; display: block; }
.frame-stack img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}
.frame-stack img.is-on { opacity: 1; }
.frame-stack img.crop-top { object-position: top; }
/* The black tee is shot 4:5 and the card is 4:3, so a centred crop spends its
   bottom third on chair legs and floor. Pushing the frame up the file drops
   the floor and lets the garment sit on the seat rail. Keyed to the file, not
   a class, because shop.js rebuilds this stack whenever a colourway changes. */
.frame-stack img[src$="fp-black-1-front.webp"] { object-position: 50% 19%; }
/* The tote is shot 4:5 and hangs low in frame, so a centred 4:3 crop cuts the
   bottom of the seal and loses the word. Each shot is pushed down the file to
   the point where the whole print clears the frame. */
.frame-stack img[src$="fp-tote-1-front.webp"]     { object-position: 50% 66%; }
.frame-stack img[src$="fp-tote-2-front-alt.webp"] { object-position: 50% 72%; }
.frame-stack img[src$="fp-tote-3-detail.webp"]   { object-position: 50% 100%; }
.frame-stack img[src$="fp-tote-4-back.webp"]     { object-position: 50% 72%; }
.frame-stack img[src$="fp-tote-5-gusset.webp"]   { object-position: 50% 78%; }
/* The hoodie is shot tall and the prints run vertically down the sleeves, so
   each frame is pulled to the point where the most of the print survives the
   landscape card. The sleeve text starts at "From" rather than ending on
   "Free": a phrase reads better running out of frame than starting mid-line. */
.frame-stack img[src$="fp-hoodie-1-front.webp"]       { object-position: 50% 30%; }
.frame-stack img[src$="fp-hoodie-2-back.webp"]        { object-position: 50% 22%; }
.frame-stack img[src$="fp-hoodie-3-sleeve-text.webp"] { object-position: 50% 50%; }
.frame-stack img[src$="fp-hoodie-4-sleeve-map.webp"]  { object-position: 50% 30%; }
.frame-cue {
  position: absolute; left: 14px; bottom: 12px; z-index: 2;
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: 10px; letter-spacing: 0.16em; color: var(--bone);
  padding: 5px 9px; border: 1px solid rgba(237, 230, 218, 0.5);
  border-radius: 2px; background: rgba(38, 34, 30, 0.3);
  opacity: 0; transform: translateY(6px);
  transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
.artifact .frame:hover .frame-cue,
.artifact .frame:focus-visible .frame-cue { opacity: 1; transform: translateY(0); }
.frame-meta {
  position: absolute; right: 14px; bottom: 12px; z-index: 2;
  display: flex; align-items: center; gap: 10px;
}
.frame-count {
  font-variation-settings: 'wdth' 80, 'wght' 700;
  font-size: 10px; letter-spacing: 0.12em; color: var(--bone);
  text-shadow: 0 1px 3px rgba(38, 34, 30, 0.55);
}
.frame-tick {
  display: block; width: 44px; height: 1px;
  background: rgba(237, 230, 218, 0.4); overflow: hidden;
}
.frame-tick i {
  display: block; width: 100%; height: 100%; background: var(--bone);
  transform: scaleX(0); transform-origin: left center;
}
.frame-tick i.run { transform: scaleX(1); transition: transform 1.5s linear; }
.artifact-body {
  overflow: hidden; height: 0;
  display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.6fr);
  gap: clamp(12px, 3vw, 40px);
}
.artifact-body .conviction {
  padding: 0 0 26px; color: var(--earth); max-width: 40ch;
}
.artifact-body .buy { padding: 0 0 26px; }

/* ---------- shop: the long copy under a conviction line ----------
   Only a product with written copy carries these; the rest keep the single
   conviction line, so the column reads the same either way. Earth on bone
   measures 5.2:1, clear of AA. */
.artifact-body .copy { max-width: 46ch; }
.artifact-body .copy .conviction { padding-bottom: 18px; }
.artifact-body .detail {
  color: var(--earth); padding-bottom: 14px;
}
.artifact-body .spec {
  list-style: none; margin: 8px 0 26px; padding: 0;
  border-top: 1px solid var(--hairline);
}
.artifact-body .spec li {
  padding: 9px 0; border-bottom: 1px solid var(--hairline);
  font-variation-settings: 'wdth' 100, 'wght' 450;
  font-size: 13px; line-height: 1.45; letter-spacing: 0.02em;
  color: var(--olive);
}
.price {
  font-variation-settings: 'wdth' 80, 'wght' 700;
  letter-spacing: 0.04em; white-space: nowrap;
}

/* buttons */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 14px 22px;
  border: 1px solid var(--soot); border-radius: 2px;
  font-variation-settings: 'wdth' 80, 'wght' 700;
  font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; font-size: 13px;
  transition: background 0.25s ease, color 0.25s ease;
}
.btn .arr { transition: transform 0.25s ease; }
.btn:hover .arr { transform: translate(2px, -2px); }
.btn--signal {
  background: var(--signal); border-color: var(--signal); color: var(--bone);
}
.btn--ghost:hover { background: var(--soot); color: var(--bone); }
.btn[disabled] { cursor: default; opacity: 0.85; }

/* ---------- shop: size picker (js/shop.js builds it) ---------- */
.buy .size-label { display: block; margin-bottom: 10px; }
.sizes { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.sizes .size {
  min-width: 46px; padding: 9px 12px;
  border: 1px solid var(--hairline); border-radius: 2px;
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--soot);
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.sizes .size:hover:not([disabled]) { border-color: var(--soot); }
.sizes .size.is-on { background: var(--soot); border-color: var(--soot); color: var(--bone); }
/* sold out reads as struck from the sheet. Struck, not dimmed: fading it
   would drop a real piece of information below AA contrast */
.sizes .size[disabled] {
  cursor: default; color: var(--olive);
  border-style: dashed;
  text-decoration: line-through; text-decoration-thickness: 1px;
}
.buy .buy-note { display: block; margin-top: 12px; color: var(--signal); }
.buy .buy-note:empty { margin-top: 0; }

/* ---------- shop: colourway picker (js/shop.js builds it) ----------
   Only rendered for a product carrying a Colour option with more than one
   value. The chip shows the cloth, the word carries it for anyone who cannot
   separate the two by eye, so colour is never the only channel. */
.colourway { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px; }
.colourway .cw {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 8px 14px 8px 9px;
  border: 1px solid var(--hairline); border-radius: 2px;
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--soot);
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.colourway .cw i {
  width: 15px; height: 15px; border-radius: 50%;
  border: 1px solid rgba(38, 34, 30, 0.3);
}
.colourway .cw:hover:not([disabled]) { border-color: var(--soot); }
.colourway .cw.is-on { background: var(--soot); border-color: var(--soot); color: var(--bone); }
.colourway .cw.is-on i { border-color: rgba(237, 230, 218, 0.55); }
.colourway .cw[disabled] {
  cursor: default; color: var(--olive);
  border-style: dashed;
  text-decoration: line-through; text-decoration-thickness: 1px;
}
.colourway .cw:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ---------- the bag ---------- */
#bag { position: fixed; inset: 0; z-index: 60; visibility: hidden; }
body.bag-open #bag { visibility: visible; }
.bag-scrim {
  position: absolute; inset: 0;
  background: rgba(38, 34, 30, 0.42);
  opacity: 0; transition: opacity 0.4s ease;
}
body.bag-open .bag-scrim { opacity: 1; }
.bag-panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(420px, 100vw);
  background: var(--bone);
  border-left: 1px solid var(--hairline);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
body.bag-open .bag-panel { transform: none; }
.bag-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px var(--gutter);
  border-bottom: 1px solid var(--hairline);
}
.bag-x {
  font-variation-settings: 'wdth' 100, 'wght' 500;
  font-size: 12px; letter-spacing: 0.14em; color: var(--olive);
}
.bag-x:hover { color: var(--soot); }
.bag-empty { padding: 40px var(--gutter); }
.bag-lines { list-style: none; overflow-y: auto; flex: 1; padding: 0 var(--gutter); }
.bag-lines li {
  display: grid; grid-template-columns: 64px 1fr auto;
  gap: 16px; align-items: center;
  padding: 18px 0; border-bottom: 1px solid var(--hairline);
  transition: opacity 0.2s ease;
}
.bag-lines li.is-busy { opacity: 0.4; }
.bag-lines img, .bag-noimg {
  width: 64px; height: 78px; object-fit: cover;
  border-radius: 2px; background: var(--unbleached);
}
.bag-meta h4 {
  font-variation-settings: 'wdth' 63, 'wght' 900;
  font-weight: 900; text-transform: uppercase;
  font-size: 17px; line-height: 1;
}
.bag-meta .label { display: block; margin: 5px 0 6px; }
.bag-meta .price { font-size: 14px; }
.bag-qty { display: flex; align-items: center; gap: 10px; }
.bag-qty button {
  width: 26px; height: 26px;
  border: 1px solid var(--hairline); border-radius: 2px;
  line-height: 1; color: var(--soot);
  transition: border-color 0.2s ease;
}
.bag-qty button:hover:not([disabled]) { border-color: var(--soot); }
.bag-qty button[disabled] { opacity: 0.35; cursor: default; }
.bag-qty span { font-size: 13px; min-width: 12px; text-align: center; }
.bag-foot { padding: 22px var(--gutter) 28px; border-top: 1px solid var(--hairline); }
.bag-sum { display: flex; align-items: baseline; justify-content: space-between; }
.bag-sum .price { font-size: 20px; }
.bag-note { display: block; margin: 10px 0 18px; }
/* the one dominant CTA on this surface */
.bag-go { width: 100%; justify-content: center; }

/* ---------- mobile buy sheet (js/shop.js builds it) ----------
   Under 760px the transaction leaves the accordion: the .buy panel moves
   into a dark sheet fixed to the bottom of the screen, so nobody scrolls
   past the copy to find a size. Bone chips on soot; the chosen size fills
   bone. One dominant CTA. Desktop never sees any of this. */
#buysheet { position: fixed; inset: 0; z-index: 55; visibility: hidden; }
body.sheet-open #buysheet { visibility: visible; }
.sheet-scrim {
  position: absolute; inset: 0;
  background: rgba(38, 34, 30, 0.42);
  opacity: 0; transition: opacity 0.3s ease;
}
body.sheet-open .sheet-scrim { opacity: 1; }
.sheet-panel {
  position: absolute; left: 0; right: 0; bottom: 0;
  max-height: 78vh; overflow-y: auto;
  background: var(--soot); color: var(--bone);
  border-radius: 6px 6px 0 0;
  padding: 20px var(--gutter) calc(24px + env(safe-area-inset-bottom, 0px));
  transform: translateY(100%);
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
body.sheet-open .sheet-panel { transform: none; }
.sheet-head {
  display: flex; align-items: baseline; gap: 12px;
  margin-bottom: 20px;
}
.sheet-name {
  font-variation-settings: 'wdth' 63, 'wght' 900;
  font-weight: 900; text-transform: uppercase;
  font-size: 20px; line-height: 1;
}
.sheet-price { margin-left: auto; font-size: 14px; }
.sheet-x {
  color: rgba(237, 230, 218, 0.7);
  font-size: 12px; letter-spacing: 0.14em;
  padding-left: 6px;
}
.sheet-x:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
/* the buy controls, restyled for the dark surface. Chips grow to true
   thumb size here; the fine desktop sizing stays desktop's. */
#buysheet .label { color: rgba(237, 230, 218, 0.62); }
#buysheet .sizes { margin-bottom: 18px; }
#buysheet .sizes .size,
#buysheet .colourway .cw {
  min-height: 46px; min-width: 58px; font-size: 13px;
  border-color: rgba(237, 230, 218, 0.4); color: var(--bone);
}
#buysheet .sizes .size.is-on,
#buysheet .colourway .cw.is-on {
  background: var(--bone); border-color: var(--bone); color: var(--soot);
}
#buysheet .sizes .size[disabled],
#buysheet .colourway .cw[disabled] {
  background: transparent; border-style: dashed;
  color: rgba(237, 230, 218, 0.55);
}
#buysheet .colourway .cw i { border-color: rgba(237, 230, 218, 0.4); }
#buysheet .colourway .cw.is-on i { border-color: rgba(38, 34, 30, 0.3); }
#buysheet .add {
  width: 100%; justify-content: center; min-height: 52px;
  background: var(--signal); border-color: var(--signal); color: var(--bone);
}
#buysheet .add[disabled] {
  background: transparent; opacity: 1;
  border-color: rgba(237, 230, 218, 0.4);
  color: rgba(237, 230, 218, 0.8);
}
/* the signal red is built for bone ground; on soot it needs a lift */
#buysheet .buy-note { color: #E39A87; }

@media (max-width: 760px) {
  .bag-panel { width: 100vw; }
  /* the inline panel retires on the phone; the sheet is the only door */
  .artifact-body .buy { display: none; }
  /* the bag joins the sheet's world: same dark surface, same chips,
     so buying and carrying read as one system */
  .bag-panel { background: var(--soot); color: var(--bone); border-left: none; }
  .bag-panel .label { color: rgba(237, 230, 218, 0.62); }
  .bag-head { border-bottom-color: rgba(237, 230, 218, 0.18); }
  .bag-lines li { border-bottom-color: rgba(237, 230, 218, 0.18); }
  .bag-foot { border-top-color: rgba(237, 230, 218, 0.18); }
  .bag-x { color: rgba(237, 230, 218, 0.7); }
  .bag-x:hover { color: var(--bone); }
  .bag-qty button { border-color: rgba(237, 230, 218, 0.4); color: var(--bone); }
  .bag-qty button:hover:not([disabled]) { border-color: var(--bone); }
  .bag-lines img, .bag-noimg { background: rgba(237, 230, 218, 0.12); }
}

@media (prefers-reduced-motion: reduce) {
  .bag-panel, .bag-scrim, .sheet-panel, .sheet-scrim { transition: none; }
  .sizes .size, .bag-qty button, .bag-lines li { transition: none; }
}

/* marquee */
#marquee { padding: clamp(50px, 8vh, 90px) 0; overflow: hidden; border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); }
.marquee-track {
  display: flex; gap: 0; width: max-content;
  animation: marquee 60s linear infinite;
}
#marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-track span {
  font-variation-settings: 'wdth' 63, 'wght' 900;
  font-weight: 900; text-transform: uppercase;
  font-size: clamp(40px, 7vw, 110px); line-height: 1; white-space: nowrap;
  color: transparent; -webkit-text-stroke: 1.5px var(--soot);
  padding-right: 0.6em;
}
/* each language is its own word: outline by default, solid on the alternates,
   so the belt reads as a rhythm of hollow/filled prints of the same name */
.marquee-track i {
  font-style: normal;
  -webkit-text-stroke: 0; color: transparent;
  background: none;
}
.marquee-track i:not(.solid) { -webkit-text-stroke: 1.5px var(--soot); color: transparent; }
.marquee-track i.solid { color: var(--soot); -webkit-text-stroke: 0; }
/* non-Latin scripts fall outside the condensed display face; give them a
   heavy system stack so they stay bold and sit on the same baseline */
.marquee-track i[lang="ar"],
.marquee-track i[lang="am"],
.marquee-track i[lang="ru"],
.marquee-track i[lang="el"],
.marquee-track i[lang="ko"],
.marquee-track i[lang="ja"],
.marquee-track i[lang="hi"] {
  font-variation-settings: normal;
  font-weight: 800;
  font-family: system-ui, "Segoe UI", "Noto Sans", sans-serif;
  text-transform: none;
}
.marquee-track i[lang="ar"] { font-family: "Segoe UI", "Noto Naskh Arabic", system-ui, sans-serif; }
.marquee-track i[lang="am"] { font-family: "Noto Sans Ethiopic", "Nyala", system-ui, sans-serif; }
.marquee-track i[lang="ja"] { font-family: "Yu Gothic", "Hiragino Sans", "Noto Sans JP", system-ui, sans-serif; }
.marquee-track i[lang="ko"] { font-family: "Malgun Gothic", "Noto Sans KR", system-ui, sans-serif; }
.marquee-track i[lang="hi"] { font-family: "Nirmala UI", "Noto Sans Devanagari", system-ui, sans-serif; }
.marquee-track i[lang="am"] { font-family: "Nyala", "Noto Sans Ethiopic", system-ui, sans-serif; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* universe */

/* out-there film band: footage dissolving into bone, riso ink running out at the sheet's edge */
.bleed {
  position: relative;
  margin: 0 calc(-1 * var(--gutter)) 44px;
  height: min(76vh, 640px);
  height: min(76svh, 640px);
  overflow: hidden;
  background: var(--unbleached);
}
.bleed video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}
.bleed .bleed-caption {
  position: absolute; left: var(--gutter); bottom: 16px; z-index: 2;
}
/* three interleaved opaque dot layers = a true dither density ramp, not a gray veil.
   pure paint, zero runtime */
.dissolve { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.dissolve::before, .dissolve::after { content: ""; }
.dissolve::before, .dissolve::after, .dissolve i {
  position: absolute; inset: 0; display: block;
}
.dissolve::before {
  background: radial-gradient(circle, var(--bone) 0.8px, transparent 1px) 0 0 / 5px 5px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 46%, var(--soot) 58%);
          mask-image: linear-gradient(to bottom, transparent 46%, var(--soot) 58%);
}
.dissolve::after {
  background: radial-gradient(circle, var(--bone) 1.2px, transparent 1.4px) 2px 3px / 5px 5px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 58%, var(--soot) 70%);
          mask-image: linear-gradient(to bottom, transparent 58%, var(--soot) 70%);
}
.dissolve i {
  background:
    linear-gradient(to bottom, transparent 86%, var(--bone) 97%),
    radial-gradient(circle, var(--bone) 1.7px, transparent 1.9px) 1px 1px / 5px 5px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 70%, var(--soot) 84%);
          mask-image: linear-gradient(to bottom, transparent 70%, var(--soot) 84%);
}

#universe .grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start;
}
#universe .grid figure { overflow: hidden; border-radius: 2px; }
#universe .grid img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 3 / 4; }
#universe figcaption { padding-top: 10px; }
#universe .history {
  margin-top: 56px; max-width: 52ch; color: var(--earth);
}

/* join / footer */
#join { padding-bottom: 0; }
#join h2 { font-size: clamp(34px, 6vw, 96px); max-width: 16ch; margin-bottom: 48px; }
#join form { display: flex; gap: 10px; max-width: 520px; flex-wrap: wrap; }
#join input[type="email"] {
  flex: 1 1 260px; padding: 14px 16px;
  background: transparent; border: 1px solid var(--soot); border-radius: 2px;
  font: inherit; color: var(--soot);
}
#join input[type="email"]::placeholder { color: var(--olive); }
#join .form-note { margin-top: 14px; }
.info-cols {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(24px, 4vw, 56px);
  margin-top: 72px;
}
.info-col .section-label { display: block; }
.info-col p { margin-top: 12px; max-width: 40ch; color: var(--earth); }
.info-col p a { color: var(--soot); border-bottom: 1px solid var(--hairline); }
.info-col p a:hover { border-bottom-color: var(--soot); }
.footer-nav {
  display: flex; gap: 28px; flex-wrap: wrap;
  margin: 72px 0 24px;
}
.seller-line { font-size: 10px; line-height: 1.8; margin-bottom: 40px; }
.big-wordmark {
  font-size: clamp(64px, 14.5vw, 260px);
  line-height: 0.9; text-align: center;
  margin: 0 calc(-1 * var(--gutter));
  padding-bottom: calc(var(--metabar-h) + 24px);
  user-select: none;
}

/* ---------- metadata bar ---------- */
#metabar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  height: var(--metabar-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: 18px; padding: 0 var(--gutter);
  background: var(--bone);
  border-top: 1px solid var(--hairline);
  font-size: 11px;
}
#metabar .label { font-size: 10px; }
#metabar .clock-dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--signal); margin-right: 6px;
  animation: blink 1.6s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0.15; } }
#red-thread {
  position: absolute; top: -1px; left: 0; height: 2px; width: 100%;
  background: var(--signal);
  transform: scaleX(0); transform-origin: left center;
}
#metabar .meta-right { display: flex; gap: 18px; align-items: center; }
#metabar .hide-sm { display: inline; }

/* cursor chip */
#cursor-chip {
  position: fixed; z-index: 45; top: 0; left: 0;
  padding: 8px 12px; border-radius: 2px;
  background: var(--soot); color: var(--bone);
  font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  font-variation-settings: 'wdth' 100, 'wght' 500;
  pointer-events: none; opacity: 0;
  transform: translate(-50%, -140%);
  white-space: nowrap;
}

/* reveals (JS adds .in) */
.reveal { opacity: 0; transform: translateY(28px); }
.reveal.in { opacity: 1; transform: none; transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1), transform 0.8s cubic-bezier(0.22, 1, 0.36, 1); }
.hairline {
  position: absolute; top: 0; left: var(--gutter); right: var(--gutter);
  height: 1px; background: var(--hairline);
}
.hairline-draw { transform-origin: left center; transform: scaleX(0); }
.hairline-draw.in { transform: scaleX(1); transition: transform 1s cubic-bezier(0.22, 1, 0.36, 1); }

/* ---------- lightbox ---------- */
body.lightbox-open { overflow: hidden; }
#lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity 0.4s ease;
}
#lightbox[hidden] { display: none; }
#lightbox.in { opacity: 1; }
#lightbox .lb-veil { position: absolute; inset: 0; background: rgba(38, 34, 30, 0.94); }
.lb-shell {
  position: relative; z-index: 1;
  width: min(1180px, 100%); height: 100%;
  padding: clamp(16px, 3vh, 30px) var(--gutter);
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
  gap: clamp(10px, 2vh, 20px);
}
.lb-top { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.lb-title { color: var(--bone); font-variation-settings: 'wdth' 63, 'wght' 900; font-size: 15px; }
.lb-close { color: var(--bone); padding: 6px 0; }
.lb-close:hover { color: var(--signal); }
/* The stage row must be definite, or .lb-img's max-height: 100% has nothing to
   resolve against and the image renders at natural size, overflowing the shell
   and pushing the film strip and the count off the bottom of the screen. */
.lb-stage {
  display: grid; grid-template-columns: 48px minmax(0, 1fr) 48px;
  grid-template-rows: minmax(0, 1fr); align-items: stretch; gap: 8px;
}
.lb-canvas { min-height: 0; display: flex; align-items: center; justify-content: center; }
.lb-img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  object-fit: contain; border-radius: 2px;
  opacity: 0; transform: scale(0.985);
  transition: opacity 0.45s ease, transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.lb-img.in { opacity: 1; transform: scale(1); }
.lb-nav {
  color: var(--bone); font-size: 30px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  align-self: center;
  height: 64px; width: 44px; border: 1px solid rgba(237, 230, 218, 0.22);
  border-radius: 2px; opacity: 0.72;
  transition: opacity 0.25s ease, border-color 0.25s ease;
}
.lb-nav:hover { opacity: 1; border-color: var(--signal); }
.lb-nav[hidden] { visibility: hidden; }
.lb-foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.lb-count {
  color: var(--bone); font-variation-settings: 'wdth' 80, 'wght' 700;
  flex: 0 0 auto; white-space: nowrap;
}
.lb-film { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; flex: 0 1 auto; min-width: 0; }
.lb-film::-webkit-scrollbar { display: none; }
.lb-film button {
  flex: 0 0 auto; width: 62px; height: 46px; padding: 0;
  border: 1px solid rgba(237, 230, 218, 0.24); border-radius: 2px; overflow: hidden;
  opacity: 0.45; transition: opacity 0.3s ease, border-color 0.3s ease;
}
.lb-film button img { width: 100%; height: 100%; object-fit: cover; }
.lb-film button:hover { opacity: 0.8; }
.lb-film button.is-on { opacity: 1; border-color: var(--bone); }
.lb-film[hidden] { display: none; }

/* ---------- mobile ---------- */
@media (max-width: 760px) {
  .artifact-head { grid-template-columns: 1fr; grid-template-rows: auto auto; }
  .artifact-toggle { grid-template-columns: 1fr auto; grid-template-rows: auto auto; }
  .artifact-toggle .tags { grid-column: 1 / -1; grid-row: 2; }
  /* on a phone the control sits beside the name and the tags drop under both,
     so the price and SIZES & BUY are still above the fold of the row */
  .artifact .open-cue { grid-column: 2; grid-row: 1; }
  /* the pill is what a thumb aims at, so it clears the 44px target on phones */
  .artifact .cue-pill { padding: 12px 14px; }
  .artifact .frame { grid-row: 2; margin-bottom: 4px; aspect-ratio: 5 / 4; }
  .artifact .frame-cue { opacity: 1; transform: none; }
  /* One column on a phone, but the arrows stay: a 62px thumbnail is a poor
     target and swipe alone leaves no visible way through the gallery. */
  .lb-stage { grid-template-columns: minmax(0, 1fr); position: relative; }
  .lb-nav {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
    height: 56px; width: 40px; opacity: 1;
    background: rgba(38, 34, 30, 0.55);
    -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  }
  .lb-prev { left: 2px; }
  .lb-next { right: 2px; }
  .artifact-body { grid-template-columns: 1fr; }
  .bleed { height: min(58vh, 480px); height: min(58svh, 480px); margin-bottom: 32px; }
  .dissolve::before {
    -webkit-mask-image: linear-gradient(to bottom, transparent 54%, var(--soot) 65%);
            mask-image: linear-gradient(to bottom, transparent 54%, var(--soot) 65%);
  }
  .dissolve::after {
    -webkit-mask-image: linear-gradient(to bottom, transparent 65%, var(--soot) 76%);
            mask-image: linear-gradient(to bottom, transparent 65%, var(--soot) 76%);
  }
  .dissolve i {
    -webkit-mask-image: linear-gradient(to bottom, transparent 76%, var(--soot) 88%);
            mask-image: linear-gradient(to bottom, transparent 76%, var(--soot) 88%);
  }
  #metabar .hide-sm { display: none; }
  #why .side-label { position: static; display: block; margin-top: 32px; }
  #hero .hero-row .label { flex-basis: 100%; }
  #cursor-chip { display: none; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
  #metabar .clock-dot { animation: none; }
  .reveal, .hairline-draw { opacity: 1 !important; transform: none !important; transition: none !important; }
  .page, body.menu-open .page { transition: none; }
  #menu { transition: none; }
  #cursor-chip { display: none; }
  #hero .hero-media > img { transition: none; }
  .artifact .frame, .frame-stack img, .frame-cue, .lb-img, #lightbox { transition: none !important; }
  .artifact .frame:hover { transform: none; }
  .frame-tick { display: none; }
}

/* the hero carries no headline: the picture speaks and the button answers.
   The h1 stays for search and screen readers only. */
.hero-h1-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
