/* DOART. Tokens, type, the one button, the one nav, contact, footer. Values come from DESIGN.md; do not add colours here. */
@font-face{font-family:"Archivo";src:url(../assets/fonts/archivo.woff2) format("woff2");font-weight:100 900;font-stretch:62% 125%;font-display:block}
@font-face{font-family:"Archivo";src:url(../assets/fonts/archivo-italic.woff2) format("woff2");font-weight:400 500;font-style:italic;font-display:swap}   /* label titles only; fetched when a painting first opens */
@font-face{font-family:"Geist";src:url(../assets/fonts/geist.woff2) format("woff2");font-weight:100 900;font-display:swap}
@font-face{font-family:"Geist Mono";src:url(../assets/fonts/geist-mono.woff2) format("woff2");font-weight:100 900;font-display:swap}

:root{
  --night:#0F0E0D;      /* page ground, unlit wall */
  --raised:#181715;     /* nav pill, panels, secondary button fill */
  --line:#34312D;       /* decorative 1px structure only */
  --ctl:#7A756C;        /* secondary control borders, 4.2:1 on night */
  --ink:#EEEAE3;        /* primary text + primary button fill, 16.1:1 */
  --ink-2:#ABA59B;      /* secondary text, 7.9:1 */
  --ink-3:#8F897F;      /* tertiary (working-name suffix, slot text), 5.6:1 */
  --btn-ink:#141311;    /* label on the bone button, 15.5:1 */
  --sig:#E8A92C;        /* his painted O, the mark only. Never UI. */
  --board:#E0DCD2; --board-2:#CFCABF;   /* museum label: lit end, far end (the light falls off across it) */
  --board-ink:#161513;                  /* label ink: 13.3:1 lit end, 11.2:1 far end */
  --board-top:#EFEBE3; --board-side:#8E887C;   /* 1px top face, 1px bottom face (its 4mm thickness) */
  --light:255,226,186;  /* 2900K picture light */
  --lamp:#B9A47C;
  --ease:cubic-bezier(.19,1,.22,1);        /* house expo-out: reveals, settles */
  --ease-cam:cubic-bezier(.2,.7,.2,1);     /* camera square-up */
  --gut:56px;
  /* layers: wall HUD 10, open painting 30, nav 40, skip link 50 */
}
*{box-sizing:border-box;margin:0;padding:0}
/* overscroll-behavior-x: a sideways trackpad swipe must not turn into the browser's Back/Forward gesture.
   scrollbar-gutter: locking the page while a painting is open must not shift the layout. */
html{background:var(--night);-webkit-text-size-adjust:100%;overscroll-behavior-x:none;scrollbar-gutter:stable}
body{overscroll-behavior-x:none;background:var(--night);color:var(--ink);font-family:"Geist",sans-serif;font-size:16px;-webkit-font-smoothing:antialiased;overflow-x:clip}
/* body clips sideways instead of hiding: with overflow-x:hidden, locking html would turn body into its own scroller
   and the sticky wall stage would jump back to the top of its section the moment a painting opens */
html.locked{overflow:hidden}
::selection{background:var(--sig);color:var(--night)}
a{color:inherit}
img{display:block}
:focus{outline:none}
:focus-visible{outline:2px solid var(--ink);outline-offset:4px}

/* ---------- the one button ---------- */
.btn{display:inline-flex;align-items:center;gap:14px;height:52px;padding:0 6px 0 24px;border-radius:999px;border:0;cursor:pointer;
  background:var(--ink);color:var(--btn-ink);font:600 16px/1 "Geist",sans-serif;text-decoration:none;white-space:nowrap;
  box-shadow:0 12px 24px -14px rgba(0,0,0,.9);transition:transform .5s var(--ease)}
.btn i{width:40px;height:40px;border-radius:50%;background:var(--btn-ink);color:var(--ink);display:grid;place-items:center;transition:transform .5s var(--ease)}
.btn i svg{width:16px;height:16px}
/* the arrow answers the fill sweep: an up-right arrow turns 45deg to point right, a right arrow nudges right.
   350ms on the same strong ease-out as the sweep; transform only. */
.btn .ar{transition:transform .35s cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){
  .btn:hover i{transform:scale(1.05)}
  .btn:hover .ar-out{transform:rotate(45deg)}
  .btn:hover .ar-r{transform:translateX(2px)}
}
.btn:focus-visible .ar-out{transform:rotate(45deg)}
.btn:focus-visible .ar-r{transform:translateX(2px)}
.btn:active{transform:scale(.98)}
.btn.sm{height:42px;padding:0 5px 0 18px;font-size:14px;gap:10px}.btn.sm i{width:32px;height:32px}
.btn2{display:inline-flex;align-items:center;gap:10px;height:52px;padding:0 22px;border-radius:999px;cursor:pointer;
  border:1.5px solid var(--ctl);background:var(--raised);color:var(--ink);font:500 16px/1 "Geist",sans-serif;text-decoration:none;white-space:nowrap;transition:transform .5s var(--ease)}
.btn2:active{transform:scale(.98)}
/* hover fill: a strip of his Orange Blue Pour sweeps in left to right (clip-path, 450ms, strong ease-out), back on leave.
   fill-light.jpg is the pour mixed 52% with bone: the dark label holds 4.7:1 on its darkest pixel.
   fill-dark.jpg is the pour mixed 62% with night: bone text holds 4.6:1 on its lightest pixel.
   Pointer hover only; keyboard focus shows the same fill; reduced motion fills instantly. */
.btn,.btn2{position:relative;isolation:isolate}
.btn::before,.btn2::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;
  background:url(../assets/ui/fill-light.jpg) 0 50%/cover;clip-path:inset(0 100% 0 0 round 999px);transition:clip-path .45s cubic-bezier(.23,1,.32,1)}
.btn2::before{background-image:url(../assets/ui/fill-dark.jpg)}
@media (hover:hover) and (pointer:fine){
  .btn:hover::before,.btn2:hover::before{clip-path:inset(0 0 0 0 round 999px)}
}
.btn:focus-visible::before,.btn2:focus-visible::before{clip-path:inset(0 0 0 0 round 999px)}
.nav a.l:focus-visible,.nav a.l[aria-current]{color:var(--ink)}
.nav a.l[aria-current]::after{transform:scaleX(1);background:var(--ink)}   /* the current page: a bone hairline; his yellow is for hover */
.kbd{display:inline-grid;place-items:center;min-width:30px;height:24px;padding:0 6px;border:1px solid var(--ctl);border-radius:6px;font-size:12px;color:var(--ink-2)}

/* ---------- the one nav: a floating solid island, top-left ---------- */
.nav{position:fixed;z-index:40;left:20px;top:20px;display:flex;align-items:center;gap:6px;padding:5px 5px 5px 8px;border-radius:999px;
  background:rgba(24,23,21,.94);border:1px solid var(--line);box-shadow:0 18px 40px -20px rgba(0,0,0,.9);transition:opacity .3s var(--ease)}
.nav .brand{position:relative;display:grid;align-items:center;height:42px;padding:0 12px 0 10px;text-decoration:none;border-radius:999px}
.nav .brand>*{grid-area:1/1}
/* during the hero the brand is the lone O; past it the lockup wipes in. Going back, the lockup wipes out right to left and
   only then the O grows back in (delays on the base state), so the two never overlap. No width or layout animation. */
.nav .brand .lock{font-size:19px;clip-path:inset(-.4em 100% -.4em 0);opacity:0;transition:clip-path .55s var(--ease),opacity .25s var(--ease) .4s}
.nav.named .brand .lock,html:not(.js) .nav .brand .lock{clip-path:inset(-.4em -.2em -.4em 0);opacity:1;transition:clip-path .7s var(--ease),opacity .4s var(--ease)}
.nav .brand .mk{height:30px;width:auto;justify-self:start;transition:opacity .35s var(--ease) .3s,transform .5s var(--ease) .3s}
.nav.named .brand .mk,html:not(.js) .nav .brand .mk{opacity:0;transform:scale(.7);transition:opacity .2s var(--ease),transform .3s var(--ease)}
/* text links: the word rolls up and a bone copy rolls in from below (one span + text-shadow, no clone markup), while a
   hairline of his yellow draws in under it left to right. 500ms strong ease-out; leaving runs it back. */
.nav a.l{position:relative;color:var(--ink-2);text-decoration:none;font-size:15px;padding:0 12px;height:42px;display:grid;place-items:center;border-radius:999px;transition:color .5s cubic-bezier(.23,1,.32,1)}
.nav a.l .r{display:block;overflow:hidden;line-height:1.3;height:1.3em}
.nav a.l .r>span{display:block;text-shadow:0 1.3em 0 var(--ink);transition:transform .5s cubic-bezier(.23,1,.32,1)}
.nav a.l::after{content:"";position:absolute;left:12px;right:12px;bottom:9px;height:1px;background:#E8A92C;transform:scaleX(0);transform-origin:100% 50%;transition:transform .5s cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){
  .nav a.l:hover .r>span{transform:translateY(-1.3em)}
  .nav a.l:hover::after{transform:scaleX(1);transform-origin:0 50%}
}
.nav a.l:focus-visible .r>span{transform:translateY(-1.3em)}
.nav a.l:focus-visible::after{transform:scaleX(1);transform-origin:0 50%}
.skip{position:fixed;z-index:50;left:20px;top:20px;height:52px;padding:0 22px;display:inline-flex;align-items:center;border-radius:999px;
  border:1.5px solid var(--ctl);background:var(--raised);color:var(--ink);font:500 16px/1 "Geist",sans-serif;text-decoration:none;transform:translateY(-200%)}
.skip:focus{transform:none}

/* ---------- PHONE MENU (<768): templates/nav.html, js/nav.js ----------
   The pill gains a Menu button beside Inquire; it opens a solid night sheet behind the pill's own controls (the sheet
   is the pill's child at z-index -1, so brand, Inquire and the button stay on top and the button becomes the close X).
   Links come in with a short stagger, transform and opacity only; closing is a quick fade with no stagger. */
.nav .mb,.nav .sheet{display:none}
@media (max-width:767px){
  html.js .nav .mb{display:grid;place-items:center;align-content:center;gap:5px;width:44px;height:44px;margin-left:-2px;border-radius:50%;cursor:pointer;
    border:1.5px solid var(--ctl);background:var(--raised);color:var(--ink);transition:transform .16s cubic-bezier(.23,1,.32,1)}
  .nav .mb:active{transform:scale(.96)}
  .nav .mb i{display:block;width:16px;height:1.5px;border-radius:1px;background:currentColor;transition:transform .3s cubic-bezier(.23,1,.32,1)}
  html.menu .nav .mb i:first-child{transform:translateY(3.25px) rotate(45deg)}
  html.menu .nav .mb i:last-child{transform:translateY(-3.25px) rotate(-45deg)}
  html.menu{overflow:hidden}   /* scroll lock: the scroll position stays put (no position:fixed body), scrollbar-gutter keeps the width */
  html.menu .nav{box-shadow:none;border-color:transparent;background:transparent}
  .nav .sheet:not([hidden]){display:flex;flex-direction:column;position:fixed;z-index:-1;inset:0;height:100vh;height:100dvh;overflow-y:auto;overscroll-behavior:contain;
    padding:max(104px,calc(env(safe-area-inset-top) + 92px)) 20px max(28px,env(safe-area-inset-bottom));background:var(--night);
    opacity:0;transition:opacity .15s ease-out}
  html.menu .nav .sheet{opacity:1;transition:opacity .2s cubic-bezier(.23,1,.32,1)}
  .sheet ol{list-style:none;border-top:1px solid var(--line)}
  .sheet li{border-bottom:1px solid var(--line)}
  .sheet ol a{display:flex;align-items:center;min-height:76px;color:var(--ink);text-decoration:none;
    font:800 clamp(36px,10.5vw,46px)/1 "Archivo",sans-serif;font-stretch:112%;letter-spacing:-.03em;
    opacity:0;transform:translateY(14px);transition:opacity .15s ease-out,transform .15s ease-out}
  .sheet ol a>span{position:relative;padding-bottom:6px}
  .sheet ol a[aria-current]>span::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--ink)}   /* the current page: a bone hairline, as on desktop */
  .sheet ol a:not([aria-current]){color:var(--ink-2)}
  .sheet ol a:active{transform:scale(.98)}
  html.menu .sheet ol a{opacity:1;transform:none;transition:opacity .26s cubic-bezier(.23,1,.32,1),transform .26s cubic-bezier(.23,1,.32,1)}
  html.menu .sheet li:nth-child(2) a{transition-delay:40ms}
  html.menu .sheet li:nth-child(3) a{transition-delay:80ms}
  html.menu .sheet li:nth-child(4) a{transition-delay:120ms}
  .sheet .handle{margin-top:auto;padding-top:32px;align-self:flex-start;display:inline-flex;align-items:center;min-height:44px;font-size:15px;color:var(--ink-2);
    text-decoration:underline;text-decoration-color:var(--ctl);text-underline-offset:4px}
  html.menu .sheet .handle{color:var(--ink)}
}
@media (max-width:767px) and (prefers-reduced-motion:reduce){
  .nav .mb,.nav .mb i,.sheet ol a,html.menu .sheet ol a{transition:opacity .15s ease}
  .sheet ol a,.sheet ol a:active,html.menu .sheet ol a{transform:none}
  html.menu .sheet li a{transition-delay:0ms!important}
}

/* ---------- CONTACT + FOOTER ---------- */
.contact{position:relative;min-height:calc(100vh - 66px);min-height:calc(100svh - 66px);display:grid;grid-template-columns:1.1fr .9fr;align-items:center;gap:40px;padding:120px var(--gut) 72px;overflow:hidden}
.contact h2{font-family:"Archivo",sans-serif;font-weight:800;font-stretch:112%;font-size:clamp(56px,8vw,128px);line-height:.9;letter-spacing:-.04em}
.contact p{margin-top:26px;font-size:18px;line-height:1.55;color:var(--ink-2);max-width:38ch}
.contact .row{display:flex;gap:14px;margin-top:34px;flex-wrap:wrap}
.contact p.fine{margin-top:18px;font-size:14px;max-width:none}
.contact .bigo{width:auto;height:min(280px,40vh);justify-self:center;will-change:transform}
.foot{margin:0 var(--gut);padding:18px 0 28px;display:flex;justify-content:space-between;gap:8px 24px;flex-wrap:wrap;font-size:13px;line-height:1.5;color:var(--ink-2);border-top:1px solid var(--line)}
/* the footer's links (on phones a second way to the studio and the story, beside the menu) */
.foot .fl{color:var(--ink);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;cursor:pointer;transition:text-decoration-thickness .2s ease}
.foot .fl:hover{text-decoration-thickness:2px}
.foot .fls{display:flex;flex-wrap:wrap;gap:4px 24px}

/* ---------- PHONE (<768): designed, not shrunk ---------- */
@media (max-width:767px){
  :root{--gut:20px}
  .nav{left:12px;top:12px}
  .nav a.l{display:none}
  .skip{left:12px;top:12px}
  .contact{grid-template-columns:1fr;padding:110px 20px 72px;min-height:0}
  .contact h2{font-size:clamp(44px,14vw,56px)}
  .contact .bigo{justify-self:start;height:200px}
}
@media (max-width:1023px){html.open .nav{opacity:0;pointer-events:none}}   /* the stacked open painting owns the top edge */
/* home, 768-1279: the full pill would run onto the hero's paint panel (it starts at 44% of the width). The hero CTA
   already says "Walk the wall" and scrolling reaches the story, so the pill keeps the mark, Studio and Inquire.
   Measured at 768: pill ends 334, panel starts 338; at 1280 the full pill ends 523, panel 563. */
@media (min-width:768px) and (max-width:1023px){body:not(.studio-page):not(.read-page) .nav a.l:is(.wl,.st){display:none}}
@media (min-width:1024px) and (max-width:1279px){body:not(.studio-page):not(.read-page) .nav a.l.wl{display:none}}
@media (max-width:767px),(pointer:coarse){.nav .brand,.nav a.l,.btn.sm{height:44px}.foot .fl{display:inline-flex;align-items:center;min-height:44px;margin:-12px 0}}   /* 44px touch targets */
@media (prefers-reduced-motion:reduce){
  .btn,.btn i,.btn2,.btn::before,.btn2::before,.btn .ar,.nav a.l .r>span,.nav a.l::after{transition:none}
  .nav .brand .lock{clip-path:none;transition:opacity .2s var(--ease)}
  .nav.named .brand .lock{clip-path:none}
  html{scroll-behavior:auto}
}
html.instant *{transition:none!important}

/* QA capture mode (?debug + a scroll flag only): headless --screenshot paints a blank frame for a scrolled window,
   so deterministic states scroll #page instead. Same layout, same sticky behaviour. Never active for visitors. */
html.shot,html.shot body{height:100%;overflow:hidden}
html.shot #page{height:100vh;overflow-y:auto}
html.shot *{transition:none!important}
html.shot [data-reveal]{opacity:1;translate:none}
