/* ---------------------------------------------------------------------- *
   Satiate Studio — house stylesheet
   Direction: "Manifesto" (the type does the work, the products are
   evidence, motion is scrubbed by the reader's own scrolling).
   Used by every page under site/.
   ---------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

:root {
  --void: #0a0a09;
  --void-2: #131211;
  --bone: #f2ece0;
  --bone-2: #a8a093;
  --bone-3: #857d70;   /* 4.87:1 on the void — the old #6e675c was 3.52:1 */
  --line: #26241f;
  --settee: #d69a6a;
  --collectd: #5bb661;
  --display: 'Bricolage Grotesque', 'Inter', sans-serif;
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}

html { background: var(--void); scroll-behavior: smooth; }
/* Only `html` carries the background. A `background` on `body` paints over the
   fixed hero canvas — a negative z-index child paints behind its parent's
   background, so the plotter would be drawn and then covered. That is exactly
   the bug that cost a round on the sketch. */
body {
  margin: 0; color: var(--bone);
  font-family: var(--sans); font-size: 17px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
img, canvas, video { max-width: 100%; }
.wrap { width: min(1240px, 100% - 3rem); margin-inline: auto; }

/* Cross-document view transitions: the wordmark keeps its identity across
   navigations, so the mark morphs instead of the page flashing. Chromium 126
   and Safari 18.2 support this; everywhere else it is a normal page load. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .32s; }

/* ------------------------------------------------------------------- head */
header.bar { position: fixed; inset: 0 0 auto 0; z-index: 30; border-bottom: 1px solid color-mix(in oklab, var(--line) 60%, transparent); background: color-mix(in oklab, var(--void) 72%, transparent); backdrop-filter: blur(12px); }
header.bar .wrap { display: flex; align-items: center; gap: 1rem; padding: .8rem 0; font-size: .86rem; }
/* The wordmark is the company name set in the display face at text size — no
   badge, no monogram. It runs larger than the nav on purpose: on this site the
   name is the brand, so it does not need a mark to lean on. */
.wordmark { font-family: var(--display); font-weight: 500; font-size: 1.12rem; letter-spacing: .005em; text-decoration: none; display: inline-flex; align-items: center; white-space: nowrap; view-transition-name: studio-mark; }
header.bar nav { margin-left: auto; display: flex; gap: 1.2rem; flex-wrap: wrap; }
header.bar nav a { color: var(--bone-2); text-decoration: none; }
header.bar nav a:hover, header.bar nav a[aria-current='page'] { color: var(--bone); }
@media (max-width: 720px) {
  header.bar .wrap { flex-wrap: wrap; }
  header.bar nav { margin-left: 0; width: 100%; gap: .9rem; font-size: .82rem; order: 3; }
}

/* ------------------------------------------------------------------- stage */
/* The hero plotter (hero-plotter.js): one fixed canvas behind the page, scrubbed
   by the reader's scrolling and faded out below the hero. It starts at opacity 0
   and JS is what reveals it, so with scripting off or the module failing there
   is simply no plotter — nothing is hidden and nothing is lost.
   z-index -1 puts it behind the content but in front of html's background, which
   is the only element on this site allowed to carry one. */
.stage { position: fixed; inset: 0; display: block; width: 100%; height: 100%; z-index: -1; pointer-events: none; opacity: 0; }

/* -------------------------------------------------------------------- hero */
.hero { min-height: 100svh; display: grid; align-content: center; gap: 2rem; padding: 7rem 0 4rem; position: relative; }
.hero::before {
  /* a wash that only moves when the page is scrolled — see the animation below.
     Inset is 0 horizontally on purpose: bleeding it -10% each side added 10px
     to the document width, which `overflow-x: hidden` on body was masking. */
  content: ''; position: absolute; inset: -20% 0 auto 0; height: 120%;
  background:
    radial-gradient(60% 55% at 18% 30%, color-mix(in oklab, var(--collectd) 22%, transparent), transparent 70%),
    radial-gradient(50% 45% at 82% 18%, color-mix(in oklab, var(--settee) 20%, transparent), transparent 72%);
  filter: blur(30px); opacity: .5; pointer-events: none; z-index: -1;
}
.hero--short { min-height: auto; padding: 9rem 0 3rem; }
.kicker { font-size: .78rem; letter-spacing: .18em; text-transform: uppercase; color: var(--bone-3); margin: 0; }
h1.display {
  font-family: var(--display); font-weight: 300; margin: 0;
  font-size: clamp(2.9rem, 12vw, 9.4rem); line-height: .92; letter-spacing: -.03em;
  text-transform: uppercase;
  font-variation-settings: 'wght' 260, 'wdth' 88;
}
h1.display span { display: block; }
h1.display .l2 { color: var(--bone-2); }
.page-head { padding: 9rem 0 2.5rem; display: grid; gap: 1.1rem; }
.page-head h1 {
  font-family: var(--display); font-weight: 300; margin: 0; text-transform: uppercase;
  font-size: clamp(2.4rem, 8vw, 6rem); line-height: .94; letter-spacing: -.03em;
  font-variation-settings: 'wght' 300, 'wdth' 90;
}
.lede { margin: 0; color: var(--bone-2); font-size: clamp(1.04rem, 1.6vw, 1.3rem); max-width: 46ch; }
.hero-foot { display: flex; flex-wrap: wrap; gap: 2rem 3rem; align-items: flex-end; justify-content: space-between; margin-top: 1rem; }
.hero-foot p { margin: 0; max-width: 44ch; color: var(--bone-2); font-size: 1.04rem; }
.scroll-cue { display: flex; align-items: center; gap: .6rem; font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; color: var(--bone-3); }
.scroll-cue i { display: block; width: 44px; height: 1px; background: var(--bone-3); }
.btn { display: inline-flex; align-items: center; gap: .5rem; padding: .8rem 1.3rem; border-radius: 999px; background: var(--bone); color: var(--void); border: 1px solid var(--bone); text-decoration: none; font-size: .95rem; font-weight: 600; transition: transform .18s ease; }
.btn:hover { transform: translateY(-2px); }
.btn.ghost { background: transparent; color: var(--bone); border-color: var(--line); }
.btn-row { display: flex; gap: .6rem; flex-wrap: wrap; }

/* ----------------------------------------------------------------- marquee */
.marquee {
  border-block: 1px solid var(--line); padding: 1rem 0; overflow: hidden;
  /* the strip runs off both edges on purpose, so fade the edges instead of
     letting a word look chopped in half at rest */
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.track { display: flex; gap: 2.4rem; width: max-content; font-family: var(--display); font-weight: 600; text-transform: uppercase; letter-spacing: -.01em; font-size: clamp(1.2rem, 2.6vw, 2.1rem); color: var(--bone-2); }
.track b { color: var(--bone); font-weight: 700; }
.track span { display: inline-flex; align-items: center; gap: 2.4rem; }
.track span::after { content: '◆'; color: var(--bone-3); font-size: .7em; }

/* --------------------------------------------------------------- statement */
.statement { padding: clamp(5rem, 12vh, 9rem) 0; position: relative; }
.statement p {
  font-family: var(--display); font-weight: 300; margin: 0;
  font-size: clamp(1.5rem, 3.6vw, 3rem); line-height: 1.18; letter-spacing: -.02em;
  max-width: 30ch; color: var(--bone-2);
}
.statement p em { font-style: normal; color: var(--bone); }
/* Cursor spotlight: two CSS variables written by one pointermove handler.
   No canvas, no library, and it costs one composited layer. */
.statement::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(220px 220px at var(--mx, 50%) var(--my, 40%), color-mix(in oklab, var(--bone) 9%, transparent), transparent 70%);
  opacity: 0; transition: opacity .3s ease;
}
.statement:hover::after { opacity: 1; }

/* ---------------------------------------------------------------- products */
.subhead { font-size: .78rem; letter-spacing: .18em; text-transform: uppercase; color: var(--bone-3); margin: 0 0 1rem; }
.products { border-top: 1px solid var(--line); padding-top: 1.75rem; }
.row { border-bottom: 1px solid var(--line); }
/* The last row's border-bottom lands exactly on the next section's border-top
   (measured: 0px apart), so the two rules read as one 2px line. Let the next
   section draw the single rule instead. */
.products .row:last-of-type { border-bottom: 0; }
.row-head { display: grid; grid-template-columns: 4.5rem 1fr auto; gap: 1rem; align-items: baseline; padding: 1.7rem 0; cursor: pointer; }
@media (min-width: 860px) { .row-head { grid-template-columns: 7rem 1fr 20rem auto; } }
.row-index { font-family: var(--display); color: var(--bone-3); font-size: .95rem; }
.row-title { font-family: var(--display); font-weight: 600; font-size: clamp(1.6rem, 4vw, 3rem); letter-spacing: -.02em; margin: 0; text-transform: uppercase; }
.row-accent { width: 1.6rem; height: .28rem; border-radius: 999px; display: inline-block; background: var(--row); }
.row--settee { --row: var(--settee); }
.row--collectd { --row: var(--collectd); }
.row-one { color: var(--bone-2); font-size: .95rem; margin: 0; }
.row-toggle { border: 1px solid var(--line); background: transparent; color: var(--bone-2); border-radius: 999px; width: 2.1rem; height: 2.1rem; font: inherit; cursor: pointer; line-height: 1; }
.row-toggle:hover { color: var(--bone); border-color: var(--bone-3); }
.row-detail { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .34s cubic-bezier(.2,.7,.2,1); }
.row-detail > div { overflow: hidden; }
.row.open .row-detail { grid-template-rows: 1fr; }
.row-detail-inner { display: grid; gap: 1.2rem; padding: 0 0 2rem; }
@media (min-width: 860px) { .row-detail-inner { grid-template-columns: 1.2fr 1fr; padding-left: 8rem; } }
.row-detail p { margin: 0; color: var(--bone-2); }
.facts { display: grid; gap: .5rem; font-size: .9rem; color: var(--bone-3); }
.facts span { border-top: 1px solid var(--line); padding-top: .5rem; }
.row-more a { color: var(--bone); text-decoration: none; }
.row-more a:hover { text-decoration: underline; }

/* ----------------------------------------------------------------- numbers */
.numbers { display: grid; gap: 2rem; padding: clamp(4rem, 9vh, 7rem) 0; border-top: 1px solid var(--line); }
@media (min-width: 760px) { .numbers { grid-template-columns: repeat(3, 1fr); } }
.numbers b { display: block; font-family: var(--display); font-weight: 300; font-size: clamp(2.4rem, 6vw, 4.6rem); line-height: 1; letter-spacing: -.03em; }
.numbers span { color: var(--bone-3); font-size: .9rem; }

/* ------------------------------------------------------------------- cards
   Container queries: these cards are used at three different widths (the
   product page, the gallery, the home page), so each one decides its own
   layout from its own width rather than the viewport's. */
.grid { display: grid; gap: 1rem; }
@media (min-width: 720px) { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
.card { container-type: inline-size; border: 1px solid var(--line); border-radius: 14px; padding: 1.3rem; background: var(--void-2); display: grid; gap: .8rem; align-content: start; }
.card h3 { font-family: var(--display); font-weight: 600; margin: 0; font-size: 1.15rem; letter-spacing: -.01em; }
.card p { margin: 0; color: var(--bone-2); font-size: .95rem; }
.card .tags { display: flex; flex-wrap: wrap; gap: .4rem; }
.card .tags span { font-size: .74rem; letter-spacing: .06em; text-transform: uppercase; color: var(--bone-3); border: 1px solid var(--line); border-radius: 999px; padding: .18rem .55rem; }
@container (min-width: 380px) {
  .card { padding: 1.5rem; }
  .card--wide { grid-template-columns: 1fr auto; align-items: center; }
}
@container (min-width: 560px) { .card h3 { font-size: 1.3rem; } }
.edge { height: .26rem; width: 2.4rem; border-radius: 999px; background: var(--edge, var(--bone-3)); display: block; }
.edge--settee { --edge: var(--settee); }
.edge--collectd { --edge: var(--collectd); }


/* --------------------------------------------------------------- spec list */
.spec { display: grid; gap: .6rem; margin: 0; padding: 0; list-style: none; }
.spec li { display: grid; grid-template-columns: 1.4rem 1fr; gap: .6rem; color: var(--bone-2); font-size: .95rem; }
.spec li b { font-family: var(--mono); font-weight: 500; color: var(--bone-3); }
.spec li kbd { font-family: var(--mono); font-size: .82rem; color: var(--bone); background: var(--void-2); border: 1px solid var(--line); border-radius: 6px; padding: .05rem .35rem; }

/* --------------------------------------------------------------- step rail
   The five steps of the loop as an ordered list. The numbering carries the
   sequence, so nothing else is drawn on the cards — decoration that looks like
   data is worse than no decoration. Fits the container at desktop widths and
   scrolls horizontally below that. */
.rail { border-block: 1px solid var(--line); padding: 2rem 0; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: thin; }
.rail ol { display: flex; gap: 1rem; margin: 0; padding: 0; list-style: none; width: max-content; }
/* 13.5rem wide so all five cards fit the 1240px container; below that the rail
   scrolls, and the edge fade signals it rather than looking clipped. */
.rail li { width: 13.5rem; scroll-snap-align: start; border: 1px solid var(--line); border-radius: 12px; padding: 1rem; display: grid; gap: .5rem; align-content: start; background: var(--void-2); }
@media (max-width: 1199px) {
  .rail { mask-image: linear-gradient(90deg, #000 88%, transparent); -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent); }
}
.rail li b { font-family: var(--mono); font-size: .78rem; color: var(--bone-3); }
.rail li strong { font-family: var(--display); font-weight: 600; font-size: 1.05rem; }
/* no min-height: it was only ever there to reserve room for the progress bars,
   and with those gone it just pads every card with dead space */
.rail li p { margin: 0; color: var(--bone-2); font-size: .88rem; }


/* --------------------------------------------------------------------- cta */
.cta { padding: clamp(4rem, 10vh, 8rem) 0; border-top: 1px solid var(--line); display: grid; gap: 1.6rem; }
.cta h2 { font-family: var(--display); font-weight: 300; text-transform: uppercase; letter-spacing: -.03em; font-size: clamp(2rem, 7vw, 5rem); line-height: .95; margin: 0; }
footer { border-top: 1px solid var(--line); padding: 2rem 0 3rem; color: var(--bone-3); font-size: .84rem; }
.foot-grid { display: flex; flex-wrap: wrap; gap: 1.4rem; justify-content: space-between; }
footer a { color: var(--bone-2); text-decoration: none; }
footer a:hover { text-decoration: underline; }

/* ------------------------------------------------------------ motion layer
   All of it is scroll-scrubbed or a pointer effect, and none of it runs under
   `prefers-reduced-motion`. Where `animation-timeline` is missing (Firefox
   today) the hero simply sits at its declared weight and `.reveal` content is
   visible from the start — the page degrades, it doesn't disappear. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes swell { from { font-variation-settings: 'wght' 260, 'wdth' 86; } to { font-variation-settings: 'wght' 720, 'wdth' 96; } }
  @keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }
  @keyframes lift { from { transform: translateY(0); } to { transform: translateY(-40px); } }
  @keyframes rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
  .track { animation: slide 26s linear infinite; }
  @supports (animation-timeline: scroll()) {
    .hero h1.display { animation: swell linear both; animation-timeline: scroll(root block); animation-range: 0 60vh; }
    .hero::before { animation: lift linear both; animation-timeline: scroll(root block); animation-range: 0 100vh; }
  }
  @supports (animation-timeline: view()) {
    .reveal { animation: rise linear both; animation-timeline: view(); animation-range: entry 0% entry 80%; }
  }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition-duration: .01ms !important; animation: none !important; }
}
