/* ============================================================
   FORTY-FIRST — Western Interior Design Studio Monograph
   Layout, typography, baseline grid, hairlines, reveals.
   All spacing derives from the 8px baseline (--bl).
   ============================================================ */

:root{
  /* palette */
  --cream:#F4EFE7;
  --ink:#2A2620;
  --ink-soft:rgba(42,38,32,.62);
  --earth:#8C6A4A;              /* muted tobacco / saddle tan */
  --hairline:rgba(42,38,32,.12);

  /* baseline grid + content margins */
  --bl:8px;                                    /* the baseline unit */
  --margin:clamp(20px, 6vw, 96px);             /* content margins (hairlines sit here) */

  /* type — one humanist sans carrying hierarchy through weight alone.
     System variable fonts (SF Pro / Segoe UI Variable) animate font-weight
     smoothly. To ship a guaranteed variable font, drop Inter woff2 in
     /fonts and uncomment the @font-face below. */
  --sans:system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI", Helvetica, Arial, sans-serif;
  --mono:ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* the unified warm image grade — a touch of warmth, a whisper of contrast */
  --grade:sepia(.08) saturate(1.05) contrast(1.02) brightness(1.01);

  /* motion — one easing personality: clean weighted ease-out */
  --ease:cubic-bezier(.215,.61,.355,1);        /* power3.out */
  --wipe-dur:.9s;                              /* image clip-path reveal timing */
}
/*
@font-face{
  font-family:"InterVar";
  src:url("../fonts/InterVariable.woff2") format("woff2-variations");
  font-weight:100 900; font-display:swap;
}
*/

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:auto}
body{
  background:var(--cream); color:var(--ink);
  font-family:var(--sans); font-weight:410;
  font-size:16px; line-height:calc(var(--bl)*3);   /* 24px — on the baseline */
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
img{display:block;width:100%;height:100%;object-fit:cover;filter:var(--grade)}
a{color:inherit;text-decoration:none}
::selection{background:var(--earth);color:var(--cream)}
.mono{font-family:var(--mono);font-size:11px;letter-spacing:.08em;font-weight:400;color:var(--ink-soft)}

/* ---------- hairlines at the content margins ---------- */
.hairline{position:fixed;top:0;bottom:0;width:1px;background:var(--hairline);z-index:1;pointer-events:none}
.hl-l{left:var(--margin)} .hl-r{right:var(--margin)}

/* ---------- grain — fine paper stock ---------- */
#grain{
  position:fixed;inset:0;z-index:70;pointer-events:none;opacity:.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.92' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- custom cursor ---------- */
#dot{
  position:fixed;top:0;left:0;width:8px;height:8px;margin:-4px 0 0 -4px;border-radius:50%;
  background:var(--ink);z-index:90;pointer-events:none;display:none;
  transition:width .3s var(--ease),height .3s var(--ease),margin .3s var(--ease),background .3s;
}
#dot.hot{width:40px;height:40px;margin:-20px 0 0 -20px;background:rgba(140,106,74,.28)}
body.fine-cursor{cursor:none}
body.fine-cursor a{cursor:none}
body.fine-cursor #dot{display:block}

/* ---------- loader ---------- */
#loader{
  position:fixed;inset:0;z-index:100;background:var(--cream);
  display:flex;align-items:flex-end;
  clip-path:inset(0 0 0 0);
  transition:clip-path 1s var(--ease);           /* the upward cut — no fade */
}
#loader.done{clip-path:inset(0 0 100% 0);pointer-events:none}
.l-inner{width:100%;padding:0 var(--margin) calc(var(--bl)*8)}
.l-count{font-size:12px;margin-bottom:calc(var(--bl)*1)}
.l-rule{height:1px;background:var(--hairline);position:relative;overflow:hidden}
.l-rule i{position:absolute;inset:0;background:var(--earth);transform:scaleX(0);transform-origin:left;display:block}

/* ---------- catalog furniture: ribbon + running folio ---------- */
#ribbon{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:66;
  background:var(--earth);transform:scaleX(0);transform-origin:left;
  pointer-events:none;
}
#folio{
  position:fixed;left:50%;bottom:calc(var(--bl)*1.5);transform:translateX(-50%);
  z-index:60;pointer-events:none;white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
@media(max-width:640px){#folio{display:none}}

/* ---------- masthead ---------- */
.masthead{
  position:fixed;top:0;left:0;right:0;z-index:60;
  display:flex;justify-content:space-between;
  padding:calc(var(--bl)*3) var(--margin);
}

/* ============================================================
   Reveals.
   .masked > .ln  — overflow-mask line reveals (stagger via --i)
   [data-fade]    — soft rise
   .wipe-l/.wipe-r — crisp clip-path wipes for image plates
   Initial hidden states are gated on html.js so content is
   always visible without JS (resilience) and under
   prefers-reduced-motion (instant states).
   ============================================================ */
/* .ln is the overflow mask; JS wraps its contents in .li (the shim that
   rises out of the mask). Without JS there is no .js class and no wrapping —
   the text is simply visible. */
.masked .ln{display:block;overflow:hidden;--i:0}
.masked .ln:nth-child(2){--i:1}.masked .ln:nth-child(3){--i:2}.masked .ln:nth-child(4){--i:3}
.masked .li{display:block;will-change:transform}
.js .masked:not(.in) .li{transform:translateY(112%)}
.js .masked.in .li{transform:translateY(0);
  transition:transform .9s var(--ease) calc(var(--i)*.09s)}
.js [data-fade]{opacity:0;transform:translateY(calc(var(--bl)*2));
  transition:opacity 1s var(--ease),transform 1s var(--ease)}
.js [data-fade].in{opacity:1;transform:none}

.plate{overflow:hidden;position:relative;background:linear-gradient(160deg,#E7DECF,#D9CCB6)} /* warm fallback under every plate */
.plate img{will-change:transform}
.js .wipe-l:not(.in){clip-path:inset(0 100% 0 0)}
.js .wipe-r:not(.in){clip-path:inset(0 0 0 100%)}
.js .wipe-l.in,.js .wipe-r.in{clip-path:inset(0 0 0 0);transition:clip-path var(--wipe-dur) var(--ease)}

/* ============================================================
   1 · HERO
   ============================================================ */
#hero{position:relative;min-height:100vh;min-height:100svh;display:flex;flex-direction:column;justify-content:center;padding:calc(var(--bl)*12) var(--margin) calc(var(--bl)*14)}
#wall{position:absolute;inset:0;width:100%;height:100%;z-index:-1}
.kicker{margin-bottom:calc(var(--bl)*4)}
#mark{
  font-size:clamp(120px,26vw,380px);   /* the numeral mark — four glyphs, generous */
  font-weight:560;letter-spacing:.01em;line-height:.98;
}
/* SplitText-style char masks (built by JS): each char sits in an overflow mask */
#mark .ch{display:inline-block;overflow:hidden;vertical-align:top}
#mark .ch i{display:inline-block;font-style:normal;will-change:transform;transform:translateY(112%)}
#mark.in .ch i{transform:translateY(0);transition:transform 1.1s var(--ease) calc(var(--ci)*.035s)}
html:not(.js) #mark .ch i{transform:none}
.hero-line{
  margin-top:calc(var(--bl)*4);max-width:52ch;
  font-size:17px;font-weight:430;color:var(--ink-soft);
}
.vol{margin-top:calc(var(--bl)*3);color:var(--earth)}
.hero-foot{
  position:absolute;left:var(--margin);bottom:calc(var(--bl)*5);
  display:flex;align-items:center;gap:calc(var(--bl)*2);
}
.arrow{color:var(--earth)}

/* ============================================================
   section heads
   ============================================================ */
section{position:relative}
.sec-head{display:flex;align-items:baseline;gap:calc(var(--bl)*3);padding:0 var(--margin);margin-bottom:calc(var(--bl)*8)}
.sec-no{color:var(--earth)}
h2{font-size:clamp(28px,4vw,54px);font-weight:540;letter-spacing:-.01em;line-height:1.1}
h3{font-size:clamp(26px,3.2vw,44px);font-weight:540;letter-spacing:-.01em;line-height:1.12}

/* ============================================================
   2 · THE LEDGER
   ============================================================ */
#ledger{padding:calc(var(--bl)*22) 0 calc(var(--bl)*20)}
.rows{list-style:none}
.row{border-top:1px solid var(--hairline)}
.row:last-child{border-bottom:1px solid var(--hairline)}
.row a{
  display:grid;grid-template-columns:calc(var(--bl)*8) auto 1fr auto auto auto;
  align-items:baseline;gap:calc(var(--bl)*3);
  padding:calc(var(--bl)*4) var(--margin);
}
/* TOC leader dots — the contents-page dotted rule to the page reference */
.leader{
  display:block;height:2px;align-self:center;min-width:calc(var(--bl)*4);
  background:repeating-linear-gradient(to right, rgba(42,38,32,.34) 0 2px, transparent 2px 9px);
  background-position:0 50%;background-size:100% 2px;background-repeat:no-repeat;
  opacity:.7;
}
.pg{color:var(--earth);font-variant-numeric:tabular-nums}
@media(max-width:640px){.leader{min-width:calc(var(--bl)*2)}.row .place{display:none}}
.row .name{
  font-size:clamp(20px,2.6vw,34px);
  font-weight:400;letter-spacing:-.005em;line-height:1.15;
  transition:font-weight .45s var(--ease),color .45s var(--ease),font-variation-settings .45s var(--ease);
}
.row .area{display:none}
@media(min-width:980px){.row .area{display:block}}
/* hover: the hovered name STRENGTHENS on the weight axis; others soften */
@media(hover:hover){
  .rows:hover .row .name{color:var(--ink-soft)}
  .row:hover .name{color:var(--earth);font-weight:640;font-variation-settings:"wght" 640}
  .rows:hover .row:not(:hover) a{opacity:.55}
  .row a{transition:opacity .45s var(--ease)}
  .thumb{display:none}
}
/* touch: inline thumbnails, no floating preview */
@media(hover:none){
  .thumb{display:block;margin:0 var(--margin) calc(var(--bl)*4);height:calc(var(--bl)*24);overflow:hidden}
  #preview{display:none!important}
}
/* the cursor-following preview */
#preview{
  position:fixed;z-index:40;width:min(30vw,380px);aspect-ratio:4/3;
  pointer-events:none;overflow:hidden;opacity:0;
  transition:opacity .35s var(--ease);
  will-change:transform;
  box-shadow:0 24px 60px rgba(42,38,32,.22);
}
#preview.on{opacity:1}
#preview img{position:absolute;inset:0;transition:opacity .4s var(--ease)}
#preview img.b{opacity:0}
#preview.swap img.a{opacity:0}
#preview.swap img.b{opacity:1}

/* ============================================================
   3 · FEATURED — pinned full-bleed (CSS sticky pin, JS scrub)
   ============================================================ */
/* dynamic viewport units: steady on iOS Safari as the URL bar collapses */
.pin-300{height:300vh;height:300dvh}
.pin-400{height:400vh;height:400dvh}
.pin-300 .sticky,.pin-400 .sticky{position:sticky;top:0;height:100vh;height:100dvh;overflow:hidden}
#featured .plate.full{position:absolute;inset:0}
#featured .plate.full img{transform:scale(1.06)}   /* settles to 1 via JS scrub */
.feat-cap{
  position:absolute;left:var(--margin);bottom:calc(var(--bl)*8);z-index:2;
  color:#FBF8F2;max-width:44ch;
  text-shadow:0 1px 30px rgba(30,24,16,.4);
}
.feat-cap .cap-no .ln{color:#E8D9BC}
.feat-cap h3{font-size:clamp(34px,4.6vw,64px);font-weight:560;color:#FBF8F2;margin:calc(var(--bl)*2) 0}
.feat-cap p{font-weight:420;font-size:16px;color:rgba(251,248,242,.88)}
#featured .sticky::after{
  content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(to top,rgba(30,24,16,.42),transparent 55%);
}

/* ============================================================
   4 · SPREADS — generous, residential spacing
   ============================================================ */
.spread{
  display:grid;grid-template-columns:1fr 1.15fr;
  gap:calc(var(--bl)*10);align-items:center;
  padding:calc(var(--bl)*20) var(--margin);
}
.spread.flip{grid-template-columns:1.15fr 1fr}
.spread.flip .col.txt{order:2}
/* plates are mounted, not edge-bled: a cream mat and a hairline frame */
.spread .plate{
  aspect-ratio:4/3;
  padding:calc(var(--bl)*1.5);
  border:1px solid var(--hairline);
  background:var(--cream);
}
.spread .plate img{outline:1px solid var(--hairline);outline-offset:-1px}
/* the fine caption beneath each plate */
.plate-cap{
  margin-top:calc(var(--bl)*2);
  padding-top:calc(var(--bl)*1);
  border-top:1px solid var(--hairline);
  color:var(--earth);
}
.spread .col.txt .sec-no{display:block;margin-bottom:calc(var(--bl)*3)}
.spread .meta{margin:calc(var(--bl)*2) 0 calc(var(--bl)*4)}
.spread .body{max-width:44ch;color:var(--ink-soft);font-weight:420}
@media(max-width:860px){
  .spread,.spread.flip{grid-template-columns:1fr;gap:calc(var(--bl)*5);padding:calc(var(--bl)*12) var(--margin)}
  .spread.flip .col.txt{order:0}
}

/* ============================================================
   5 · THE ROOMS — pinned cinematic cross-dissolve
   ============================================================ */
#rooms .frames{position:absolute;inset:0}
#rooms .frame{position:absolute;inset:0;opacity:0}
#rooms .frame:first-child{opacity:1}
#rooms .frame img{transform:scale(1.12)}          /* collective Ken-Burns zoom-out via JS */
.rooms-hud{
  position:absolute;left:var(--margin);right:var(--margin);bottom:calc(var(--bl)*6);z-index:2;
  display:flex;justify-content:space-between;gap:calc(var(--bl)*3);flex-wrap:wrap;
}
.rooms-hud #rooms-count{white-space:nowrap}
.rooms-hud .mono{color:rgba(251,248,242,.92);text-shadow:0 1px 20px rgba(30,24,16,.5)}
.rooms-static-caps{display:none}

/* ============================================================
   6 · STATEMENT
   ============================================================ */
#statement{padding:calc(var(--bl)*28) var(--margin);text-align:left}
#statement .sec-no{display:block;margin-bottom:calc(var(--bl)*4)}
.statement{font-size:clamp(26px,3.6vw,52px);font-weight:480;letter-spacing:-.01em;line-height:1.22;max-width:26ch}
.statement .em{color:var(--earth);font-weight:560}

/* ============================================================
   7 · FOOTER — magnetic "Let's Talk"
   ============================================================ */
footer{padding:calc(var(--bl)*12) var(--margin) calc(var(--bl)*6);border-top:1px solid var(--hairline)}
#talk{
  display:grid;place-items:center;margin:0 auto calc(var(--bl)*10);
  width:calc(var(--bl)*24);height:calc(var(--bl)*24);border-radius:50%;
  border:1px solid var(--earth);color:var(--earth);
  font-weight:520;font-size:15px;letter-spacing:.02em;
  will-change:transform;transition:background .4s var(--ease),color .4s var(--ease);
}
#talk:hover{background:var(--earth);color:var(--cream)}
/* colophon — the back page */
.colophon{
  display:grid;grid-template-columns:repeat(3,1fr);gap:calc(var(--bl)*6);
  border-top:1px solid var(--hairline);
  padding:calc(var(--bl)*6) 0;margin-bottom:calc(var(--bl)*4);
}
.colophon .c-h{display:block;color:var(--earth);margin-bottom:calc(var(--bl)*1)}
.colophon p{max-width:38ch}
.colophon a{border-bottom:1px solid var(--earth);color:var(--ink)}
@media(max-width:860px){.colophon{grid-template-columns:1fr;gap:calc(var(--bl)*4)}}
.foot-row{display:flex;justify-content:space-between;gap:calc(var(--bl)*2);flex-wrap:wrap;border-top:1px solid var(--hairline);padding-top:calc(var(--bl)*3)}
.foot-row a{color:inherit}

/* ============================================================
   Reduced motion — native scroll, instant states, no pins,
   static shader frame, stacked Rooms captions, no cursor.
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  .js .masked:not(.in) .li{transform:none}
  .js [data-fade]{opacity:1;transform:none;transition:none}
  .js .wipe-l:not(.in),.js .wipe-r:not(.in){clip-path:none}
  #mark .ch i{transform:none!important;transition:none!important}
  .pin-300,.pin-400{height:auto}
  .pin-300 .sticky,.pin-400 .sticky{position:relative;height:100vh}
  #rooms .frames{position:relative;inset:auto}
  #rooms .frame{position:relative;opacity:1;height:60vh;margin-bottom:2px}
  #rooms .frame img{transform:none}
  .rooms-hud{display:none}
  .rooms-static-caps{display:block;position:relative;padding:calc(var(--bl)*3) var(--margin)}
  #featured .plate.full img{transform:none}
  #preview{display:none!important}
  body.fine-cursor{cursor:auto}
  body.fine-cursor #dot{display:none}
  #loader{transition:none}
}
