/* ==========================================================================
   Duskline Barber Co.
   Type system: Tanker (condensed display + signage/buttons)
                / Melodrama (editorial didone, the shop's voice)
                / Erode (warm text serif, everything you read at length)
                / Switzer (grotesk micro-labels + form UI only)
   Melodrama's zero is slashed, so it never touches prices or clock times.

   Material system: the site is the inside of the shop after dark.
   Walnut wood walls, warm lamplight, oxblood leather (stitched cards),
   antique brass (frames + primary plaques), cream enamel (chips + guard
   plates), true red/cream/blue barber-pole stripes, checkerboard tile
   strips, barbicide blue only as a trace accent.
   ========================================================================== */

@font-face{font-family:"Tanker";src:url(/fonts/tanker-400-normal.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Melodrama";src:url(/fonts/melodrama-400-normal.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Erode";src:url(/fonts/erode-400-normal.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Erode";src:url(/fonts/erode-500-normal.woff2) format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Switzer";src:url(/fonts/switzer-400-normal.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Switzer";src:url(/fonts/switzer-500-normal.woff2) format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Switzer";src:url(/fonts/switzer-700-normal.woff2) format("woff2");font-weight:700;font-style:normal;font-display:swap}

:root{
  --wood:#171008; --wood2:#20160D;
  --line:rgba(242,230,208,.13); --line2:rgba(242,230,208,.22);
  /* .55 cream is the 4.5:1 contrast floor on this wood; micro-labels sit at
     or above it, never below */
  --cream:#F2E6CE; --cream2:rgba(242,230,206,.7); --mut:rgba(242,230,206,.55);
  --brass:#C28E3F; --brass2:#E4B963;
  --red:#A63730; --red2:#CB4A40;
  --blue:#4C82E8;

  --disp:"Tanker",Impact,Haettenschweiler,"Arial Narrow Bold",sans-serif;
  --edit:"Melodrama",Georgia,"Times New Roman",serif;
  --text:"Erode",Georgia,"Iowan Old Style",serif;
  --body:"Switzer",system-ui,-apple-system,"Segoe UI",sans-serif;

  /* one house curve, three durations. 150ms micro / 300ms interface / 600ms imagery.
     Ambient loops (pole, haze, motes, cue, pulse) are scenery, not transitions,
     and keep their own clocks. */
  --ease:cubic-bezier(.19,1,.22,1);
  --fast:150ms; --mid:300ms; --slow:600ms;

  --nav-h:64px;
  --pad:clamp(24px,5vw,72px);
  --maxw:1440px;
  /* the fixed preview pill owns the bottom of the screen. Anything anchored
     down there clears it by this much, or it gets covered on phones. */
  --pill-clear:calc(64px + env(safe-area-inset-bottom));

  /* five steps: d1 / d2 / d3 / body / lab. The hero wordmark is the one
     exception above the scale; everything else maps onto these. */
  --fs-hero:min(clamp(3.9rem,16.5vw,15rem),33vh);
  --fs-d1:clamp(2.6rem,7.5vw,6.4rem);
  --fs-d2:clamp(1.9rem,4.4vw,3.3rem);
  --fs-d3:clamp(1.4rem,2.6vw,2.1rem);
  --fs-body:clamp(1rem,.35vw + .92rem,1.12rem);
  /* micro-label floor: nothing on this site renders below 11px, at any width */
  --fs-lab:max(11px,.7rem);

  /* ---- the rhythm ----
     Section padding used to be symmetric, so every boundary between two
     sections summed BOTH paddings: 144px + 144px of undifferentiated brown.
     That is what read as crowded and floaty at the same time. The space now
     sits above the heading only (--sec-lead) with a short tail below
     (--sec-tail), so a boundary is one interval you can actually tune, and
     each heading sits nearer its own text than to the section before it.
     Both ends of every step are multiples of 8. */
  --sec-lead:clamp(56px,9vh,120px);   /*  7u ->  15u */
  --sec-tail:clamp(20px,3vh,36px);
}

*{margin:0;padding:0;box-sizing:border-box}
/* font-synthesis off: Tanker ships one weight and a faux-bold Tanker is the
   fastest way for the whole site to read cheap */
html{-webkit-text-size-adjust:100%;scrollbar-color:var(--brass) var(--wood);scrollbar-gutter:stable;font-kerning:normal;font-synthesis:none}
body{
  background-color:var(--wood);
  /* faint vertical wood grain, two offset frequencies so it never tiles visibly */
  background-image:
    repeating-linear-gradient(92deg,rgba(255,214,150,.02) 0 1px,transparent 1px 6px),
    repeating-linear-gradient(88deg,rgba(0,0,0,.05) 0 2px,transparent 2px 9px);
  color:var(--cream);
  font-family:var(--text);font-size:var(--fs-body);line-height:1.62;
  /* the whisper of tracking reopens counters that bloom on a dark ground */
  letter-spacing:.005em;
  font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overflow-x:hidden;
}
p{text-wrap:pretty}
h1,h2,h3,.d1,.d2,.d3,.quote{text-wrap:balance}
/* times, prices, and clock digits hold their columns */
.hrs,.pr,.mins,.stat,.tonight{font-variant-numeric:tabular-nums lining-nums}
body.lock{overflow:hidden}
a{color:inherit;text-decoration:none}
a,button{-webkit-tap-highlight-color:transparent;touch-action:manipulation}
img{display:block;max-width:100%}
button{font:inherit;background:none;border:none;color:inherit;cursor:pointer}
::selection{background:var(--brass);color:var(--wood)}
:focus-visible{outline:2px solid var(--brass2);outline-offset:3px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.wrap{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--pad)}
/* every in-page anchor clears the fixed nav */
[id]{scroll-margin-top:calc(var(--nav-h) + 24px)}

/* the house separator: a small red diamond, the same mark the signage rail
   uses. Middots are banned sitewide. */
.dsep{display:inline-block;color:var(--red2);font-size:.6em;vertical-align:.16em}
.tonight .dsep,.stat-live .dsep{color:inherit;opacity:.65}

/* --------------------------------------------------------- type primitives */
.lab{
  font-family:var(--body);font-weight:600;font-size:var(--fs-lab);
  letter-spacing:.3em;text-transform:uppercase;color:var(--mut);
}
.edit{font-family:var(--edit);font-weight:400;color:var(--brass2);line-height:1.16}
/* tracking follows the sign-flip law: negative above ~40px and scaling with
   size (gently, since Tanker is condensed), positive below 14px, wide on labels */
.d1{font-family:var(--disp);font-size:var(--fs-d1);line-height:.86;letter-spacing:-.012em;text-transform:uppercase}
.d2{font-family:var(--disp);font-size:var(--fs-d2);line-height:.9;letter-spacing:-.008em;text-transform:uppercase}
.d3{font-family:var(--disp);font-size:var(--fs-d3);line-height:.94;letter-spacing:-.004em;text-transform:uppercase}
.quote{font-family:var(--edit);font-size:var(--fs-d3);line-height:1.16;color:var(--brass2)}
.o{color:transparent;-webkit-text-stroke:1.5px var(--brass)}
.prose{color:var(--cream2);max-width:62ch;hyphens:none}
.prose p+p{margin-top:1.1em}

/* ------------------------------------------------------------ ambient layers
   The vignette carries the room: warm lamp falloff from above, brown
   shadow in the corners. It sits over content at very low alpha, which is
   what makes the light read as light ON surfaces rather than a backdrop. */
.grain{position:fixed;inset:0;z-index:6;pointer-events:none;opacity:.05;mix-blend-mode:overlay}
.vig{position:fixed;inset:0;z-index:5;pointer-events:none;background:
  radial-gradient(60% 42% at 50% 0%,rgba(224,166,74,.07),transparent 62%),
  radial-gradient(120% 90% at 50% 40%,transparent 55%,rgba(11,6,2,.55) 100%)}
/* scroll progress as a sliver of the pole itself */
#prog{position:fixed;top:0;left:0;height:3px;width:0;z-index:250;background:repeating-linear-gradient(-45deg,var(--red) 0 5px,var(--cream) 5px 10px,#3D6FB8 10px 15px,var(--cream) 15px 20px)}
main,footer{position:relative;z-index:3}

/* the pole: true red / cream / blue / cream, always at -45deg.
   Speed is the shop's pulse: working pace while the doors are open,
   a slow idle turn after close. The pole never quite stops. */
.stripe{background:repeating-linear-gradient(-45deg,var(--red) 0 8px,var(--cream) 8px 16px,#3D6FB8 16px 24px,var(--cream) 24px 32px);background-size:46px 46px}
:root{--pole-speed:5600ms}
html.shop-open{--pole-speed:1400ms}
.in-view .stripe{animation:pole var(--pole-speed) linear infinite}
@keyframes pole{to{background-position:45.3px 0}}

/* checkerboard tile strip: the shop floor, quoted as a divider */
.checks{height:14px;background:repeating-conic-gradient(#0D0805 0% 25%,#E9DCC2 0% 50%);background-size:28px 28px;border-top:1px solid rgba(0,0,0,.5);border-bottom:1px solid rgba(0,0,0,.5)}

.skip{position:fixed;top:-60px;left:16px;z-index:400;background:var(--brass);color:var(--wood);padding:8px 16px;border-radius:4px;font-family:var(--body);font-weight:600;transition:top var(--mid)}
.skip:focus{top:12px}

/* the cape: page transitions sweep up like a cape thrown over the chair.
   Leaving: it rises to cover. Arriving (flagged via sessionStorage): it
   starts covering and lifts away. Brass edge + pole stripe on the hem. */
.wipe{position:fixed;inset:0;z-index:320;pointer-events:none;transform:translateY(102%);background:linear-gradient(180deg,#241811,#171008 60%);border-top:2px solid var(--brass)}
.wipe::before{content:"";position:absolute;top:2px;left:0;right:0;height:7px;background:repeating-linear-gradient(-45deg,var(--red) 0 8px,var(--cream) 8px 16px,#3D6FB8 16px 24px,var(--cream) 24px 32px)}
.wipe.in{transform:translateY(0);transition:transform var(--mid) var(--ease)}
.wipe.cover{transform:translateY(0)}
.wipe.out{transform:translateY(-102%);transition:transform var(--slow) var(--ease) .06s}

/* ---------------------------------------------------------------------- nav
   Single row at EVERY width, height pinned to --nav-h. Sticky-nav overlap
   bugs come from a nav that silently grows; this one cannot. */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:240;height:var(--nav-h);
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:0 var(--pad);flex-wrap:nowrap;
  transition:background var(--mid),transform var(--mid) var(--ease),border-color var(--mid);
  border-bottom:1px solid transparent;
}
.nav.solid{background:rgba(23,16,8,.86);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border-bottom-color:var(--line)}
/* while the menu is open the bar carries the same wood as .solid, so the
   wordmark never sits naked over menu links scrolling under it */
body.menu-open .nav{background:rgba(23,16,8,.86);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border-bottom-color:var(--line)}
/* the menu is modal: the chat widget (z 300, above the overlay by its own
   config) steps off the floor while it is open and returns on close */
body.menu-open .mox{visibility:hidden}
.nav.hide{transform:translateY(-102%)}
.brand{
  font-family:var(--disp);font-size:1.3rem;letter-spacing:.02em;text-transform:uppercase;
  display:inline-flex;align-items:center;gap:8px;white-space:nowrap;flex-shrink:0;line-height:1;
}
.brand .pole{width:11px;height:24px;border-radius:3px;box-shadow:0 0 10px rgba(203,74,64,.45);flex-shrink:0}
.nav-links{display:flex;align-items:center;gap:clamp(16px,2.4vw,40px)}
.nav-links a{
  font-family:var(--body);font-weight:500;font-size:.72rem;letter-spacing:.24em;
  text-transform:uppercase;color:var(--cream2);white-space:nowrap;position:relative;padding:4px 0;
  transition:color var(--fast);
}
/* the house mark on the links: the same red diamond the signage rail uses.
   No chapter numbers anywhere on this site: a shop is not a table of
   contents. Desktop-only chrome (menu takes over under 940px). */
.nav-links a .ni{font-size:.5rem;color:var(--brass2);opacity:.55;margin-right:8px;vertical-align:2px;transition:opacity var(--fast),color var(--fast)}
.nav-links a:hover .ni,.nav-links a:focus-visible .ni{opacity:1}
.nav-links a[aria-current="page"] .ni{color:var(--red2);opacity:1}
.nav-links a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--brass);transform:scaleX(0);transform-origin:0 50%;transition:transform var(--mid) var(--ease)}
.nav-links a:hover{color:var(--cream)}
/* letter-roll: the label ducks out and its brass twin rolls in from below */
.nav-links a .rl{position:relative;display:inline-block;overflow:hidden;vertical-align:bottom}
.nav-links a .rl span{display:block;transition:transform var(--mid) var(--ease)}
.nav-links a .rl span+span{position:absolute;left:0;top:100%;color:var(--brass2)}
.nav-links a:hover .rl span{transform:translateY(-100%)}
.nav-links a:hover::after,.nav-links a[aria-current="page"]::after{transform:scaleX(1)}
.nav-links a[aria-current="page"]{color:var(--brass2)}
.nav-r{display:flex;align-items:center;gap:clamp(8px,1.6vw,24px);flex-shrink:0}
/* nav CTA: a small brass plate, not a pill. Brass shell + dark inlay;
   hovering (or focusing) lifts the inlay and shows the metal. */
.book-pill{
  position:relative;isolation:isolate;
  display:inline-flex;align-items:center;min-height:44px; /* 44px touch floor */
  font-family:var(--disp);font-size:max(12px,.82rem);letter-spacing:.1em;text-transform:uppercase;
  color:var(--brass2);background:linear-gradient(175deg,#EFC873,#B07E2E 60%,#A87A2C);
  border-radius:3px;padding:8px 16px;white-space:nowrap;transition:color var(--mid);
}
.book-pill::before{content:"";position:absolute;inset:1px;z-index:-1;border-radius:2px;background:linear-gradient(180deg,#241811,#180F08);transition:opacity var(--mid)}
.book-pill:hover,.book-pill:focus-visible{color:#221302}
.book-pill:hover::before,.book-pill:focus-visible::before{opacity:0}
.menu-btn{display:none;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--cream);padding:12px 8px;min-height:44px;align-items:center;gap:8px;white-space:nowrap}
.menu-btn .bars{display:inline-block;width:20px;height:9px;position:relative;flex-shrink:0}
.menu-btn .bars::before,.menu-btn .bars::after{content:"";position:absolute;left:0;right:0;height:2px;background:var(--cream);transition:var(--mid) var(--ease)}
.menu-btn .bars::before{top:0}.menu-btn .bars::after{bottom:0}
body.menu-open .menu-btn .bars::before{top:3.5px;transform:rotate(45deg)}
body.menu-open .menu-btn .bars::after{bottom:3.5px;transform:rotate(-45deg)}
@media(max-width:940px){
  .nav-links{display:none}
  .menu-btn{display:inline-flex}
}

/* --------------------------------------------------------------- menu overlay */
/* no backdrop-filter here: behind a .97 background the blur was invisible,
   and it made .menu the containing block for the fixed tile floor below,
   which glued the floor back onto the scrolling content */
.menu{position:fixed;inset:0;z-index:230;background:rgba(19,12,6,.97);clip-path:inset(0 0 100% 0);visibility:hidden;pointer-events:none;transition:clip-path var(--slow) var(--ease),visibility 0s var(--slow);display:flex;overflow-y:auto;-webkit-overflow-scrolling:touch}
.menu.open{clip-path:inset(0 0 0 0);visibility:visible;pointer-events:auto;transition:clip-path var(--slow) var(--ease)}
/* the tile floor at the foot of the menu. Fixed, not absolute: the menu is
   its own scroll container, so an absolute strip rides up with the content
   and cuts through the hours block on short screens. Pinned to the viewport
   it stays the floor. Fixed boxes ignore the ancestor clip-path wipe, so its
   own opacity is keyed to .open: the wipe passes, then the floor is laid. */
.menu::after{content:"";position:fixed;left:0;right:0;bottom:0;height:12px;background:repeating-conic-gradient(#0D0805 0% 25%,#E9DCC2 0% 50%);background-size:24px 24px;border-top:1px solid rgba(0,0,0,.5);opacity:0;transition:opacity var(--mid) var(--ease)}
.menu.open::after{opacity:1;transition-delay:.3s}
.menu .inner{width:100%;max-width:var(--maxw);margin:auto;padding:calc(var(--nav-h) + 32px) var(--pad) 56px;display:grid;grid-template-columns:1.6fr 1fr;gap:4vw;align-items:center;min-height:min-content}
.menu nav{display:flex;flex-direction:column}
.m-link{display:flex;align-items:center;gap:1.2vw;padding:.55vh 0;font-family:var(--disp);font-size:clamp(2.4rem,7vh,5rem);line-height:1.06;text-transform:uppercase;overflow:hidden}
/* each page gets its own little pole in the menu, a row of chairs on the
   wall. The pole beside the page you are on is the one that turns: in this
   shop a turning pole means the chair is being worked. */
.m-link .idx{width:10px;height:28px;border-radius:3px;flex-shrink:0;align-self:center;opacity:.55;transition:opacity var(--mid) var(--ease),box-shadow var(--mid) var(--ease)}
.m-link:hover .idx,.m-link:focus-visible .idx{opacity:1;animation:pole var(--pole-speed) linear infinite}
.m-link[aria-current="page"] .idx{opacity:1;box-shadow:0 0 10px rgba(203,74,64,.45);animation:pole var(--pole-speed) linear infinite}
.m-link[aria-current="page"]>.rl>span{color:var(--brass2)}
.m-link .rl{position:relative;display:inline-block;overflow:hidden}
.m-link .rl span{display:block;transition:transform var(--mid) var(--ease)}
.m-link .rl span+span{position:absolute;left:0;top:100%;color:var(--brass2)}
.m-link:hover .rl span{transform:translateY(-100%)}
.m-link>span.rl{transform:translateY(120%);transition:transform var(--slow) var(--ease)}
.menu.open .m-link>span.rl{transform:none}
.menu.open .m-link:nth-child(1)>span.rl{transition-delay:.28s}
.menu.open .m-link:nth-child(2)>span.rl{transition-delay:.34s}
.menu.open .m-link:nth-child(3)>span.rl{transition-delay:.40s}
.menu.open .m-link:nth-child(4)>span.rl{transition-delay:.46s}
.menu.open .m-link:nth-child(5)>span.rl{transition-delay:.52s}
.menu .m-side{opacity:0;transform:translateY(12px);transition:opacity var(--slow) var(--ease),transform var(--slow) var(--ease);color:var(--cream2);font-size:var(--fs-body);display:flex;flex-direction:column;gap:1.5rem}
.menu.open .m-side{opacity:1;transform:none;transition-delay:var(--mid)}
.m-side .lab{margin-bottom:.5rem}
@media(max-width:940px){.menu .inner{grid-template-columns:1fr;align-items:center;gap:2.5rem}.m-link{font-size:clamp(2.4rem,10.5vw,3.6rem);padding:.8vh 0}}

/* The chair-plate section head (CHAIR 1 + striped rule + THE CONSULT) was
   removed from every page on the owner's call: it put three small pieces of
   furniture in front of every section before you reached anything to read.
   Sections now open on their own display line, and the space above it does
   the work the label used to. Its rules are deleted rather than left
   orphaned; .stripe itself stays, it is still the pole and the menu index. */
/* padding-block only: these classes are combined with .wrap, and a padding
   shorthand here would clobber .wrap's horizontal gutters.
   Pacing is not uniform: the manifesto gets the most air (the room goes
   quiet), the teaser board sits tighter (a list, not a scene), everything
   else holds the base interval. All steps live on the 8px scale. */
.sec{padding-block:var(--sec-lead) var(--sec-tail)}
#consult{padding-block:clamp(64px,11vh,144px) var(--sec-tail)}
.teaser{padding-block:clamp(48px,7vh,96px) var(--sec-tail)}
/* .proof carries a wood panel and a rule top and bottom: a tail-only bottom
   would sit its caption on the border, so this one stays symmetric. */
.sec.proof{padding-block:clamp(48px,7vh,88px)}

/* ------------------------------------------------------------------ reveals */
.js .rv{opacity:0;transform:translateY(12px);transition:opacity var(--mid) var(--ease),transform var(--mid) var(--ease)}
.js .rv.on{opacity:1;transform:none}
/* the reveal transition list outranks element hover transitions; restate the
   intended interaction easings at reveal specificity once revealed */
.js .trow.rv.on,.js .crow.rv.on{transition:padding-left var(--mid) var(--ease),background var(--mid) var(--ease)}
.js .gcard.rv.on{transition:transform var(--mid) var(--ease),box-shadow var(--mid) var(--ease)}
.js .more.rv.on{transition:color var(--mid),border-color var(--mid),background var(--mid)}
/* hidden clip states hold a .5% sliver, never zero area: Chrome now clips
   IntersectionObserver geometry by clip-path, and a zero-area target can
   never reach any ratio threshold, so the reveal would wait for the 6s
   failsafe. The sliver is under 2px and reads as nothing. */
.js .rv-clip{clip-path:polygon(0 0,.5% 0,.5% 100%,0 100%);transition:clip-path var(--slow) var(--ease)}
.js .rv-clip.on{clip-path:polygon(0 0,100% 0,100% 100%,0 100%)}
.js .rv-clip img{transform:scale(1.15);transition:transform var(--slow) var(--ease)}
.js .rv-clip.on img{transform:scale(1)}
.js .rv-l{clip-path:inset(0 0 99.5% 0);transition:clip-path var(--slow) var(--ease)}
.js .rv-l.on{clip-path:inset(-8% -4% -12% -4%)}
/* proof figures: opacity reveals, but transform belongs to the scroll engine
   (inline drift), so the reveal transition must not fight it */
.js .proof figure.rv{transform:none;transition:opacity var(--mid) var(--ease)}
/* material chips file in one after another */
.js .mats.rv li{opacity:0;transform:translateY(12px);transition:opacity var(--mid) var(--ease),transform var(--mid) var(--ease)}
.js .mats.rv.on li{opacity:1;transform:none}
.js .mats.rv.on li:nth-child(2){transition-delay:.06s}
.js .mats.rv.on li:nth-child(3){transition-delay:.12s}
.js .mats.rv.on li:nth-child(4){transition-delay:.18s}
/* enamel plates settle onto the wall with a tilt, in sequence.
   The .on reset must be restated at this specificity or the offset wins. */
.js .gcard.rv{transform:translateY(12px) rotate(1deg)}
.js .gcard.rv.on{transform:none}
.js .gcard.rv:nth-child(2){transition-delay:.06s}
.js .gcard.rv:nth-child(3){transition-delay:.12s}
.js .gcard.rv:nth-child(4){transition-delay:.18s}
.js .gcard.rv:nth-child(5){transition-delay:.24s}
.btn .l{transition:transform var(--fast) var(--ease)}
.btn:hover .l{transform:translateX(3px)}

/* ------------------------------------------------------------------ buttons
   Not pills. Plaques: chamfered corners like a cast sign, engraved
   pinstripe rectangle inset, Tanker signage type.
   The keyline variant is built as brass shell + dark inlay 1px smaller,
   because a border would get cut open at the chamfers by the clip-path. */
.btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:16px 32px 15px;
  clip-path:polygon(10px 0,calc(100% - 10px) 0,100% 10px,100% calc(100% - 10px),calc(100% - 10px) 100%,10px 100%,0 calc(100% - 10px),0 10px);
  font-family:var(--disp);font-weight:400;font-size:max(13px,1rem);letter-spacing:.09em;text-transform:uppercase;
  isolation:isolate;cursor:pointer;border:none;
}
.btn .l{position:relative;z-index:3}
.btn::after{ /* engraved pinstripe: a plain rectangle inside the chamfered plate */
  content:"";position:absolute;inset:5px;z-index:2;border:1px solid transparent;pointer-events:none;
  transition:border-color var(--mid);
}
.btn:focus-visible{outline:none}
.btn:focus-visible::after{border-color:var(--blue);border-width:2px}
.btn-gold{
  /* dark stop holds 4.5:1 against the #221302 ink; the old #8F6425 read 3.46 */
  background:linear-gradient(175deg,#EFC873 0%,#D5A34A 38%,#B07E2E 64%,#A87A2C 100%);
  /* engraved physics, light from above: recess shadow above the glyph,
     catchlight below it */
  color:#221302;text-shadow:0 -1px 0 rgba(23,16,8,.28),0 1px 0 rgba(255,246,224,.45);
  box-shadow:inset 0 1px 0 rgba(255,246,224,.7),inset 0 -2px 0 rgba(60,32,4,.45);
}
.btn-gold::after{border-color:rgba(66,38,6,.5)}
.btn-gold:hover{filter:brightness(1.07)}
.btn-ghost{
  background:linear-gradient(175deg,#E4B963,#A87A2C);
  color:var(--cream);
}
.btn-ghost::before{content:"";position:absolute;inset:1px;z-index:1;background:linear-gradient(180deg,#241811,#180F08);clip-path:polygon(9.3px 0,calc(100% - 9.3px) 0,100% 9.3px,100% calc(100% - 9.3px),calc(100% - 9.3px) 100%,9.3px 100%,0 calc(100% - 9.3px),0 9.3px);transition:transform var(--mid) var(--ease)}
.btn-ghost::after{border-color:rgba(194,142,63,.4)}
/* hover: the dark inlay sweeps aside like a clean razor pass, brass beneath */
.btn-ghost:hover{color:#221302}
.btn-ghost:hover::before{transform:translateX(102%)}
.btn-ghost:hover::after{border-color:rgba(66,38,6,.5)}

/* --------------------------------------------------------------- page header
   Used by every page except home. Clears the nav by construction. */
/* the page head is a title block, not the first paragraph of the page.
   Its inner gaps stay tight (h1 and the script line are one utterance) and
   the space goes underneath it, so the content below starts after a clear
   break instead of crowding the title. */
.phead{padding-block:calc(var(--nav-h) + clamp(56px,11vh,112px)) clamp(56px,9vh,88px);position:relative;overflow:hidden}
.phead::before{content:"";position:absolute;inset:0;z-index:-1;background:radial-gradient(70% 90% at 16% 0%,rgba(224,166,74,.1),transparent 60%)}
.phead .eye{display:flex;align-items:center;gap:16px;margin-bottom:clamp(12px,2.4vh,24px)}
.phead .eye .bar{width:52px;height:6px;border-radius:2px;overflow:hidden;flex-shrink:0}
.phead h1{font-family:var(--disp);font-size:var(--fs-d1);line-height:.86;letter-spacing:-.012em;text-transform:uppercase}
.phead .sub{margin-top:clamp(20px,3.2vh,32px);max-width:52ch;color:var(--cream2)}
/* one accent word per page: Melodrama's lowercase inside the Tanker line,
   cap-height matched. Never more than one per heading. */
.acc{font-family:var(--edit);font-style:normal;font-weight:400;text-transform:none;color:var(--brass2);font-size:1.06em;letter-spacing:.01em}
.phead .edit{display:inline-block;font-size:var(--fs-d3);margin-top:clamp(10px,1.6vh,16px)}

/* ================================================================= HOME ==== */
.hero{position:relative;min-height:100svh;display:flex;flex-direction:column;justify-content:flex-end;overflow:hidden;
  /* the fixed preview pill lives at the bottom: never let type run under it */
  padding-bottom:calc(72px + env(safe-area-inset-bottom));
}
.hero .ph{position:absolute;inset:-8% 0;z-index:0;will-change:transform}
.hero .ph img{width:100%;height:100%;object-fit:cover;filter:sepia(.26) saturate(1.05) contrast(1.04) brightness(.66)}
.hero .ph::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(23,16,8,.5),rgba(23,16,8,.24) 45%,rgba(23,16,8,.94)),linear-gradient(90deg,rgba(23,16,8,.55) 0%,rgba(23,16,8,.12) 55%,rgba(23,16,8,0) 68%),radial-gradient(70% 60% at 78% 18%,rgba(224,166,74,.26),transparent 60%)}
.js .hero .ph img{transform:scale(1.15);transition:transform var(--slow) var(--ease)}
html.loaded .hero .ph img{transform:scale(1)}

/* ambient layer: a slow warm lamp breathing over the frame and a few motes of
   dust turning in the light. Decorative, sits above the photo and below the
   type, and is entirely disabled for reduced-motion (see the media block). */
.hero-amb{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden;display:none}
.hero-amb .haze{position:absolute;inset:-10%;background:
  radial-gradient(38% 30% at 74% 22%,rgba(230,176,92,.16),transparent 66%),
  radial-gradient(46% 40% at 30% 88%,rgba(120,60,30,.12),transparent 70%);
  mix-blend-mode:screen;opacity:.9;animation:haze 15s ease-in-out infinite}
@keyframes haze{0%,100%{opacity:.65;transform:translate3d(0,0,0) scale(1)}50%{opacity:1;transform:translate3d(-1.2%,-1.6%,0) scale(1.05)}}
.hero-amb i{position:absolute;bottom:-6%;width:3px;height:3px;border-radius:50%;
  background:radial-gradient(circle,rgba(240,214,160,.85),rgba(240,214,160,0) 70%);
  opacity:0;animation:mote linear infinite}
@keyframes mote{
  0%{opacity:0;transform:translate3d(0,0,0)}
  12%{opacity:.7}
  80%{opacity:.5}
  100%{opacity:0;transform:translate3d(14px,-62vh,0)}
}
.hero-amb i:nth-child(2){left:16%;animation-duration:17s;animation-delay:0s;transform:scale(1.1)}
.hero-amb i:nth-child(3){left:34%;animation-duration:22s;animation-delay:5s;width:2px;height:2px}
.hero-amb i:nth-child(4){left:57%;animation-duration:19s;animation-delay:9s}
.hero-amb i:nth-child(5){left:71%;animation-duration:25s;animation-delay:3s;width:2px;height:2px}
.hero-amb i:nth-child(6){left:83%;animation-duration:20s;animation-delay:12s;transform:scale(1.2)}
.hero-amb i:nth-child(7){left:46%;animation-duration:24s;animation-delay:15s;width:2px;height:2px}
@media (prefers-reduced-motion: no-preference){.hero-amb{display:block}}

.hero__in{position:relative;z-index:2;padding-top:calc(var(--nav-h) + 16px)}
/* status: a little wall plaque, not a pill */
/* the status plaque keeps quiet in daylight (brass edge); the ember edge
   belongs to after-dark, when the lamps come up. One peak per viewport:
   the hero's accent is the gold plate, and nothing else competes. */
.stat{display:inline-flex;align-items:center;gap:8px;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.22em;text-transform:uppercase;color:var(--cream2);border:1px solid var(--line);border-left:3px solid rgba(194,142,63,.6);border-radius:3px;padding:8px 16px;margin-bottom:8px;background:rgba(23,16,8,.5);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.stat .dot{width:7px;height:7px;border-radius:50%;background:var(--mut);flex-shrink:0}
.stat.open .dot{background:var(--blue);box-shadow:0 0 10px var(--blue);animation:pulse 2s infinite}
.stat.open{color:var(--cream)}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}
.hero h1{font-family:var(--disp);font-size:var(--fs-hero);line-height:.85;letter-spacing:-.008em;text-transform:uppercase;position:relative}
.hero h1 .ln{display:block;overflow:hidden}
.hero h1 .ln.out{margin-left:clamp(24px,9vw,176px);margin-top:-.05em}
.hero h1 .ch-s{display:inline-block}
.js .hero h1 .ch-s{transform:translateY(115%);transform-origin:0 100%}
.hero h1 .out .ch-s{color:transparent;-webkit-text-stroke:.022em var(--brass)}
/* the brass script under the wordmark. Lives inside the h1, so it must opt
   out of the h1's uppercase: Melodrama's character is all in its lowercase */
/* display:block, not inline-block: inside the h1 an inline-block rides an
   anonymous line box that carries the wordmark's 200px strut, which was
   140px of accidental air between LINE and the script and pushed the
   booking plaques through the fold at 1440x900. As a block its distance
   from the wordmark is the margin below, a chosen number. */
.hero .script{position:static;display:block;margin-top:clamp(6px,1.2vh,12px);font-family:var(--edit);font-size:var(--fs-d3);color:var(--brass2);text-transform:none;letter-spacing:.01em;transform:rotate(-2deg);transform-origin:0 50%;white-space:nowrap;text-shadow:0 2px 26px rgba(0,0,0,.75)}
.js .hero .script{opacity:0}
html.loaded .hero .script{animation:scriptIn var(--slow) var(--ease) .66s both}
@keyframes scriptIn{from{opacity:0}to{opacity:1}}
.hero .row{display:flex;justify-content:space-between;align-items:flex-end;gap:2rem;margin-top:1.5rem;flex-wrap:wrap}
.hero .sub{max-width:36ch;color:var(--cream2)}
.hero .cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:1.5rem}
/* hero entrance: a directed sequence, not a simultaneous fade. The kicker
   wipes in first like a fresh sign, the wordmark rises (chars mask-reveal per
   letter, from the JS runtime), then the supporting lines lift on an 80ms
   cadence so the frame feels choreographed the instant it paints. */
.js .hero [data-rise]{opacity:0;transform:translateY(12px);transition:opacity var(--slow) var(--ease),transform var(--slow) var(--ease);transition-delay:var(--rd,0s)}
html.loaded .hero [data-rise]{opacity:1;transform:none}
.js .hero .stat[data-rise]{transform:none;clip-path:inset(0 100% 0 0);transition:opacity var(--mid) var(--ease),clip-path var(--slow) var(--ease);transition-delay:.05s}
html.loaded .hero .stat[data-rise]{clip-path:inset(0 -10% 0 0)}
.js .hero .sub[data-rise]{--rd:.42s}
.js .hero .cta[data-rise]{--rd:.48s}
.js .hero-right[data-rise]{--rd:.54s}
/* vertical edge label: the hero's right margin belongs to the shop, not to
   the void. Desktop-only chrome. */
.hero-vert{position:absolute;right:clamp(16px,2.2vw,34px);top:50%;transform:translateY(-50%);writing-mode:vertical-rl;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.34em;text-transform:uppercase;color:var(--mut);z-index:2;white-space:nowrap}
@media(max-width:940px){.hero-vert{display:none}}

/* the creed: a quiet stacked column that fills the hero's right shoulder */
.hero-right{display:flex;flex-direction:column;align-items:flex-end;gap:1.5rem}
/* the chat dock parks bottom-right with its top edge about 110px off the
   floor; on desktop the creed column steps 56px up so no line sits under it */
@media(min-width:941px){.hero-right{margin-bottom:56px}}
.creed{font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.26em;text-transform:uppercase;color:var(--mut);text-align:right;line-height:2.3}
@media(max-width:700px){.creed{display:none}}
.scroll-cue{display:flex;align-items:center;gap:12px;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.3em;text-transform:uppercase;color:var(--mut)}
/* short desktop screens: the fold is already close and the chat dock owns
   that corner, so the cue stands down and the creed steps higher rather
   than either sitting under the dock */
@media(min-width:941px) and (max-height:860px){.scroll-cue{display:none}.hero-right{margin-bottom:88px}}
.scroll-cue .ln-v{width:1px;height:42px;background:var(--line);position:relative;overflow:hidden}
.scroll-cue .ln-v::after{content:"";position:absolute;left:0;top:-50%;width:100%;height:50%;background:var(--brass2);animation:cue 1800ms var(--ease) infinite}
@keyframes cue{to{top:110%}}

/* signage rail: scroll-linked (driven from app.js), not a stock marquee.
   Alternate words are stroked outline, echoing the DUSK/LINE wordmark. */
.marq{overflow:hidden;background:linear-gradient(180deg,#1D140C,#20160D);border-top:1px solid rgba(0,0,0,.5);box-shadow:inset 0 1px 0 rgba(242,230,206,.06),inset 0 -1px 0 rgba(242,230,206,.04)}
.marq .row{display:flex;white-space:nowrap;padding:16px 0;width:max-content;will-change:transform}
.marq .row+.row{border-top:1px solid var(--line)}
.marq .set{display:inline-flex;gap:32px;padding-right:32px;font-family:var(--disp);font-size:var(--fs-d3);letter-spacing:.03em;text-transform:uppercase;align-items:center}
.marq .set i{font-style:normal}
.marq .r1 .set i:nth-of-type(even){color:transparent;-webkit-text-stroke:1.2px var(--brass)}
.marq .set .s{color:var(--red2);font-size:.55em}
.marq .r2{color:var(--cream2)}
.marq .r2 .set{font-family:var(--body);font-weight:600;font-size:.7rem;letter-spacing:.32em}
.marq .r2 .set .s{color:var(--blue);font-size:1em}

/* consult / manifesto */
.mani{max-width:1000px}
.mani .big{font-family:var(--disp);font-size:var(--fs-d2);line-height:1.16;text-transform:uppercase;letter-spacing:.008em}
.mani .big .w{opacity:.42;transition:opacity var(--mid) linear}
.mani .big .w.lit{opacity:1}
.mani .big .w:last-child{background:linear-gradient(var(--brass2),var(--brass2)) no-repeat 0 100%/0% 3px;transition:opacity var(--mid) linear,background-size var(--slow) var(--ease) .15s;padding-bottom:8px}
.mani .big.done .w:last-child{background-size:100% 3px}
/* clears the manifesto's last-word underline; without it the quote collides */
.mani .quote{margin-top:clamp(2rem,4.5vh,3rem)}

/* the room: the interior, held still. Materials, not mechanics. */
.room-g{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(32px,6vw,88px);align-items:center}
.room-txt .prose{margin-top:1.5rem}
/* specimen tags: flat cream cards in a 2x2 grid, same family as the guard
   plates, one material swatch pinned to each */
.mats{list-style:none;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px;margin-top:2rem;padding:0;max-width:520px}
.mat{display:flex;align-items:center;gap:12px;background:linear-gradient(180deg,#F6ECD6,#E9DABB);border:1px solid rgba(0,0,0,.4);border-radius:4px;padding:8px 12px;box-shadow:inset 0 1px 0 rgba(255,255,255,.7),0 3px 12px rgba(0,0,0,.3)}
.sw{width:30px;height:30px;border-radius:3px;flex-shrink:0;border:1px solid rgba(0,0,0,.35)}
.sw-leather{background:radial-gradient(120% 120% at 30% 20%,#7E322B,#4E1B16 72%)}
.sw-brass{background:linear-gradient(150deg,#EFC873,#B07E2E 55%,#8F6425)}
.sw-towel{background:repeating-linear-gradient(90deg,#F2E6CE 0 4px,#E0D0AE 4px 8px)}
/* the Barbicide jar: where this site's every blue accent comes from */
.sw-jar{background:linear-gradient(180deg,#5B8FE0 0%,#3D6FD0 55%,#2C55A8 100%)}
.mat .mt{color:#3A2414}
.mat .mt i{color:#6B4A28}
.mat .mt{font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.14em;text-transform:uppercase}
.mat .mt i{display:block;font-style:normal;font-size:var(--fs-lab);letter-spacing:.12em;margin-top:2px}
.room-ph figcaption,.wall-ph figcaption,.mapcard figcaption{display:flex;justify-content:space-between;gap:8px;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--mut);margin-top:12px}
.room-ph figcaption .c2,.wall-ph figcaption .c2,.mapcard figcaption .c2{color:var(--cream2)}
/* the wall: one framed shot and a voice line, the house's own proof beat */
.wall-g{display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,5vw,72px);align-items:center}
.wall-txt .quote{display:block;max-width:18ch}
.wall-txt .more{margin-top:2rem}
@media(max-width:940px){.wall-g{grid-template-columns:1fr}}
/* the wayfinding tile: cream card, red route, the pole as the marker */
.mapcard{margin-top:clamp(24px,4vh,40px);max-width:420px}
.mapcard svg{display:block;width:100%;height:auto;border:1px solid rgba(0,0,0,.4);border-radius:4px;box-shadow:inset 0 1px 0 rgba(255,255,255,.6),0 8px 24px rgba(0,0,0,.35)}
.ph-line{font-family:var(--disp);font-size:var(--fs-d3);color:var(--brass2);letter-spacing:.04em;margin-top:.5rem}
@media(max-width:940px){.room-g{grid-template-columns:1fr}}

/* brass picture frame: shared by every photo on the site */
.frame,.proof .g,.phs .ph{
  padding:8px;border-radius:4px;
  background:linear-gradient(155deg,#E2B663,#A87833 45%,#6E4A1D);
  box-shadow:0 14px 34px rgba(0,0,0,.45),inset 0 1px 0 rgba(255,240,210,.55);
}
.frame img,.proof .g img,.phs .ph img{width:100%;height:auto;object-fit:cover;border:1px solid rgba(40,20,5,.55);border-radius:1px}
.frame img{aspect-ratio:4/3;filter:sepia(.22) contrast(1.05) brightness(.78)}

/* home cuts teaser */
.teaser .list{border-top:1px solid var(--line)}
.trow{display:grid;grid-template-columns:auto 1fr auto;gap:clamp(12px,3vw,32px);align-items:baseline;padding:clamp(16px,2.4vh,24px) 0;border-bottom:1px solid var(--line);transition:padding-left var(--mid) var(--ease),background var(--mid) var(--ease)}
.trow:hover{padding-left:12px;background:linear-gradient(90deg,rgba(43,29,17,.6),transparent 70%)}
/* the left column is time in the chair, not a chapter number: real data
   doing the index work. Stroked numeral, "min" etched underneath. */
.trow .n{font-family:var(--disp);font-size:var(--fs-d3);color:transparent;-webkit-text-stroke:1px var(--brass);line-height:.9}
.trow .n i,.crow .n i{display:block;font-style:normal;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--mut);-webkit-text-stroke:0;margin-top:4px}
/* price-board dot leaders: drawn, never typed periods */
.trow .nm{font-family:var(--disp);font-size:var(--fs-d3);text-transform:uppercase;line-height:.94;display:flex;align-items:baseline;gap:16px}
.trow .nm::after{content:"";flex:1;min-width:28px;border-bottom:2px dotted rgba(242,230,206,.26);transform:translateY(-.16em)}
/* the leader draws itself name-to-price as the row arrives: a razor pass */
.js .trow.rv .nm::after,.js .crow.rv .nm::after{clip-path:inset(0 100% 0 0);transition:clip-path var(--mid) var(--ease) .12s}
.js .trow.rv.on .nm::after,.js .crow.rv.on .nm::after{clip-path:inset(0)}
.trow .pr{font-family:var(--disp);font-size:var(--fs-d3);color:var(--brass2);line-height:.9}
.more{display:inline-flex;align-items:center;min-height:44px;margin-top:2.5rem;font-family:var(--disp);font-size:max(12px,.82rem);letter-spacing:.1em;text-transform:uppercase;color:var(--brass2);border:1px solid rgba(194,142,63,.45);border-radius:3px;padding:8px 16px;transition:color var(--mid),border-color var(--mid),background var(--mid)}
.more:hover{background:linear-gradient(175deg,#EFC873,#B07E2E 60%,#A87A2C);color:#221302;border-color:rgba(0,0,0,.35)}

/* the interlude: one viewport where oxblood owns the whole screen.
   The single place that color gets the floor to itself. */
.slam{position:relative;overflow:hidden;background:linear-gradient(160deg,#8E2C26,var(--red) 55%,#7E241F);border-block:1px solid rgba(0,0,0,.5);padding-block:clamp(80px,16vh,208px);box-shadow:inset 0 1px 0 rgba(255,240,210,.14)}
/* the signature scroll moment: a slow band of warm light travels across the
   banner exactly once as the section passes through the viewport, catching the
   letters like the shop sign lighting up at dusk. --sweep is driven from
   app.js; reduced-motion never sets it, so the band stays parked off-frame. */
.slam::before{content:"";position:absolute;top:0;bottom:0;width:46%;left:calc(var(--sweep,-.4) * 150% - 23%);
  background:linear-gradient(100deg,transparent,rgba(255,241,208,.15) 44%,rgba(255,244,214,.24) 52%,rgba(255,241,208,.12) 60%,transparent);
  transform:skewX(-9deg);mix-blend-mode:screen;pointer-events:none;will-change:left}
.slam-t{position:relative;font-family:var(--disp);font-size:var(--fs-d1);line-height:.9;letter-spacing:-.012em;text-transform:uppercase;color:var(--cream);text-align:center;padding:0 var(--pad)}
.slam-t .acc{color:#F6D9A0}

/* proof strip: framed photos hanging on the back wall */
.proof{background:var(--wood2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.proof .strip{display:flex;gap:24px;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;padding:clamp(24px,4vh,40px) var(--pad) 16px;cursor:grab;scroll-snap-type:x proximity}
.proof .strip::-webkit-scrollbar{display:none}
.proof .strip.drag{cursor:grabbing;scroll-snap-type:none}
.proof figure{flex:0 0 auto;width:min(66vw,380px);scroll-snap-align:center}
.proof .g{position:relative;overflow:hidden;transition:transform var(--mid) var(--ease),box-shadow var(--mid) var(--ease)}
.proof figure:hover .g{box-shadow:0 22px 46px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,240,210,.55)}
.proof .g img{aspect-ratio:3/4;filter:sepia(.38) saturate(.92) contrast(1.05) brightness(.76);transition:transform var(--slow) var(--ease),filter var(--mid);pointer-events:none}
.proof figure:hover .g img{transform:scale(1.04);filter:sepia(.15) contrast(1.03) brightness(.92)}
/* scroll drift rides --fy on the frame so captions keep a shared baseline */
.proof figure:nth-of-type(odd) .g{transform:rotate(-1.1deg) translateY(var(--fy,0px))}
.proof figure:nth-of-type(even) .g{transform:rotate(.9deg) translateY(var(--fy,0px))}
.proof figure:hover .g{transform:rotate(0) translateY(var(--fy,0px))}
.proof figcaption{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--mut);margin-top:12px}
/* chair stamps: the second caption reads as an inspector's mark */
.proof figcaption .c2{color:var(--mut);border:1px solid var(--line);border-radius:2px;padding:2px 8px;letter-spacing:.14em}
.proof .p-note{padding:16px var(--pad) 0;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--mut)}

/* ================================================================= CUTS ==== */
/* The board: a typographic price list. No photos, no cards. */
.board{border-top:1px solid var(--line2)}
.crow{
  display:grid;grid-template-columns:clamp(52px,7vw,104px) 1fr auto;
  column-gap:clamp(12px,3vw,40px);row-gap:0;align-items:start;
  padding-block:clamp(24px,4.4vh,48px);border-bottom:1px solid var(--line);
  position:relative;transition:padding-left var(--mid) var(--ease),background var(--mid) var(--ease);
}
.crow .n{grid-column:1;grid-row:1}
.crow .body{grid-column:2;grid-row:1}
.crow .right{grid-column:3;grid-row:1}
.crow .bk{grid-column:2;grid-row:2;justify-self:start}
.crow:hover{padding-left:12px;background:linear-gradient(90deg,rgba(43,29,17,.7),transparent 70%)}
.crow .n{font-family:var(--disp);font-size:var(--fs-d3);line-height:.85;color:transparent;-webkit-text-stroke:1.4px rgba(194,142,63,.5);transition:-webkit-text-stroke-color var(--fast)}
.crow:hover .n{-webkit-text-stroke-color:var(--brass2)}
.crow .nm{font-family:var(--disp);font-size:var(--fs-d2);text-transform:uppercase;line-height:.9;letter-spacing:-.008em;display:flex;align-items:baseline;gap:16px}
.crow .nm::after{content:"";flex:1;min-width:28px;border-bottom:2px dotted rgba(242,230,206,.22);transform:translateY(-.16em)}
.crow .d{color:var(--cream2);margin-top:.75rem;max-width:44ch;font-size:var(--fs-body)}
.crow .meta{display:flex;gap:8px;flex-wrap:wrap;margin-top:1rem}
/* inert descriptors must not dress like buttons: diamond microcopy, no box */
.crow .tag{display:inline-flex;align-items:center;gap:8px;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.18em;text-transform:uppercase;color:var(--mut)}
.crow .tag::before{content:"";width:5px;height:5px;background:var(--red2);transform:rotate(45deg);flex-shrink:0;opacity:.8}
/* the house cut carries the only accent panel on the board */
.crow.house{border-left:3px solid var(--red);padding-left:clamp(12px,2vw,24px);background:linear-gradient(90deg,rgba(126,50,43,.16),transparent 70%)}
.crow.house:hover{padding-left:clamp(16px,2.4vw,32px)}
.house-chip{display:inline-block;vertical-align:middle;margin-left:16px;white-space:nowrap;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.16em;text-transform:uppercase;color:#7E241F;background:linear-gradient(180deg,#F6ECD6,#E9DABB);border:1px solid rgba(0,0,0,.35);border-radius:3px;padding:4px 8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.7);transform:translateY(-.35em)}
.crow .right{text-align:right;flex-shrink:0}
.crow .pr{font-family:var(--disp);font-size:var(--fs-d2);color:var(--brass2);line-height:.9;transition:transform var(--mid) var(--ease)}
.crow:hover .pr{transform:translateX(-4px)}
.crow .bk{display:inline-flex;align-items:center;min-height:44px;margin-top:1rem;font-family:var(--disp);font-size:max(12px,.82rem);letter-spacing:.1em;text-transform:uppercase;color:var(--brass2);border:1px solid rgba(194,142,63,.45);border-radius:3px;padding:8px 16px;transition:color var(--mid),border-color var(--mid),background var(--mid)}
.crow:hover .bk{border-color:var(--brass2)}
.crow .bk:hover{background:linear-gradient(175deg,#EFC873,#B07E2E 60%,#A87A2C);color:#221302;border-color:rgba(0,0,0,.35)}
/* phones: price reads before the CTA, never after it */
@media(max-width:700px){
  .crow{grid-template-columns:auto 1fr}
  .crow .right{grid-column:2;grid-row:2;text-align:left;display:flex;align-items:baseline;gap:16px;margin-top:1rem}
  .crow .bk{grid-column:2;grid-row:3;margin-top:1rem}
}

/* guard chart: cream enamel number plates off the back bar */
.guards{display:grid;grid-template-columns:repeat(5,1fr);gap:clamp(8px,1.4vw,16px);margin-top:clamp(24px,4vh,40px)}
.gcard{border:1px solid rgba(0,0,0,.4);border-radius:6px;padding:clamp(12px,1.8vw,24px);background:linear-gradient(180deg,#F6ECD6,#E9DABB);color:#3A2414;position:relative;overflow:hidden;box-shadow:inset 0 1px 0 rgba(255,255,255,.7),0 3px 14px rgba(0,0,0,.35);transition:transform var(--mid) var(--ease),box-shadow var(--mid)}
.gcard::after{content:"";position:absolute;inset:5px;border:1px solid rgba(166,55,48,.35);border-radius:3px;pointer-events:none}
/* four screw heads: enamel plates are fixed to the wall, not floating */
.gcard::before{content:"";position:absolute;inset:0;pointer-events:none;background:
  radial-gradient(circle at 11px 11px,rgba(58,36,20,.55) 2px,rgba(58,36,20,0) 3px),
  radial-gradient(circle at calc(100% - 11px) 11px,rgba(58,36,20,.55) 2px,rgba(58,36,20,0) 3px),
  radial-gradient(circle at 11px calc(100% - 11px),rgba(58,36,20,.55) 2px,rgba(58,36,20,0) 3px),
  radial-gradient(circle at calc(100% - 11px) calc(100% - 11px),rgba(58,36,20,.55) 2px,rgba(58,36,20,0) 3px)}
.gcard:hover{transform:translateY(-3px);box-shadow:inset 0 1px 0 rgba(255,255,255,.7),0 8px 22px rgba(0,0,0,.4)}
/* the reveal state (.js .rv.on transform:none) outranks :hover; restore the lift */
.js .gcard.rv.on:hover{transform:translateY(-3px)}
.gcard .gg{font-family:var(--disp);font-size:var(--fs-d2);line-height:.86;color:var(--red)}
.gcard .gl{font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.16em;text-transform:uppercase;color:#6B4A28;margin-top:.5rem}
.gcard .bar{height:4px;border-radius:2px;background:linear-gradient(90deg,var(--red),var(--red2));margin-top:1rem;opacity:.75}
.gcard:nth-child(1) .bar{width:14%}
.gcard:nth-child(2) .bar{width:32%}
.gcard:nth-child(3) .bar{width:52%}
.gcard:nth-child(4) .bar{width:76%}
.gcard:nth-child(5) .bar{width:100%}
/* phones: a single ascending column so the red fill bars read as the scale */
@media(max-width:700px){.guards{grid-template-columns:1fr}}

/* ====================================================== PHOTO CONSULT ====== */
/* "Show us.": a photo of your hair, read back as a cut off the board.
   Every value below is a token already declared at the top of this file: no
   new colour, no new face, no new curve. Motion stays inside the house budget
   of 300ms / 12px / 60ms, on the one --ease. */
.dc-g{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(32px,6vw,88px);align-items:start}
@media(max-width:940px){.dc-g{grid-template-columns:1fr}}
/* the steps read as house microcopy, marked with the red diamond the rest of
   the site uses. No chapter numbers here either */
.dc-steps{list-style:none;display:grid;gap:16px;margin-top:2rem;padding:0;max-width:52ch}
.dc-steps li{display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:start}
.dc-steps li::before{content:"";width:6px;height:6px;background:var(--red2);transform:rotate(45deg);opacity:.85;margin-top:.62em;flex-shrink:0}
.dc-steps b{display:block;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.18em;text-transform:uppercase;color:var(--cream)}
.dc-steps i{display:block;font-style:normal;color:var(--cream2);margin-top:4px}
.js .dc-steps.rv li{opacity:0;transform:translateY(12px);transition:opacity var(--mid) var(--ease),transform var(--mid) var(--ease)}
.js .dc-steps.rv.on li{opacity:1;transform:none}
.js .dc-steps.rv.on li:nth-child(2){transition-delay:.06s}
.js .dc-steps.rv.on li:nth-child(3){transition-delay:.12s}

/* the tool sits on the leather plate the rest of the site uses for its
   ledgers; .dc-in clears the pole strip down the left edge */
.dc{width:100%}
/* every panel below sets its own display, which would otherwise out-rank the
   browser's [hidden] rule and leave all six states on screen at once. This
   restates it as an author rule so `hidden` means hidden, always. */
.dc [hidden]{display:none!important}
.dc-in{padding-left:8px;display:grid;gap:clamp(16px,2.4vh,24px)}
.dc-fb,.dc-tool{display:grid;gap:clamp(16px,2.4vh,24px)}
.dc h3{font-family:var(--disp);font-size:var(--fs-d3);text-transform:uppercase;line-height:.95}
.dc p{font-size:var(--fs-body)}
.dc .cta{display:flex;gap:12px;flex-wrap:wrap}

/* the privacy notice is a fixture, not a footnote: brass keyline, above the
   upload control, before anything has been picked */
.dc-privacy{border:1px solid rgba(194,142,63,.34);border-left:3px solid var(--brass);border-radius:3px;padding:16px;background:rgba(23,16,8,.5)}
.dc-privacy .lab{color:var(--brass2);margin-bottom:.5rem}
.dc-privacy p{color:var(--cream2)}
.dc-privacy b{color:var(--cream);font-weight:500}

/* pick or drop */
.dc-drop{display:grid;justify-items:center;gap:12px;text-align:center;padding:clamp(24px,4vw,40px) clamp(12px,3vw,24px);
  border:1px dashed rgba(194,142,63,.4);border-radius:6px;
  background:linear-gradient(180deg,rgba(36,24,17,.55),rgba(29,19,11,.55));
  transition:border-color var(--mid) var(--ease),background var(--mid) var(--ease)}
.dc-drop.over{border-color:var(--brass2);background:linear-gradient(180deg,rgba(52,34,20,.8),rgba(36,24,17,.8))}
.dc-drop svg{color:var(--brass);opacity:.75}
.dc-hint{font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.1em;text-transform:uppercase;color:var(--mut);max-width:44ch;line-height:1.7}
.dc-picks{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin-top:8px}
/* the input lies invisibly over its own plaque, so the plaque IS the control
   and the focus ring lands where the eye already is */
.dc-pick{position:relative;display:inline-flex}
.dc-pick input{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer;z-index:4}
.dc-pick input:focus-visible+.btn::after{border-color:var(--blue);border-width:2px}
.dc-cam{display:none}
@media(pointer:coarse){.dc-cam{display:inline-flex}}

/* the picked photo, in the same brass frame as every other picture here.
   Its own img rule: the visitor's photo is never cropped to 4/3 and never
   takes the sepia the shop's own photography wears. */
.dc-shot{padding:8px;border-radius:4px;background:linear-gradient(155deg,#E2B663,#A87833 45%,#6E4A1D);
  box-shadow:0 14px 34px rgba(0,0,0,.45),inset 0 1px 0 rgba(255,240,210,.55)}
.dc-shot img{width:100%;height:auto;max-height:52vh;object-fit:contain;background:#0D0805;border:1px solid rgba(40,20,5,.55);border-radius:1px}
.dc-prev{display:grid;gap:12px}
.dc-meta{font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.12em;text-transform:uppercase;color:var(--mut)}
.dc-acts{display:flex;gap:12px;flex-wrap:wrap}

/* the wait: the pole turns while the shop thinks. Scenery, on its own clock,
   exactly like every other pole on this site. */
.dc-wait{display:grid;justify-items:center;gap:16px;text-align:center;padding:clamp(24px,4vw,40px) 16px}
.dc-pole{width:14px;height:56px;border-radius:3px;box-shadow:0 0 14px rgba(203,74,64,.4);animation:pole var(--pole-speed) linear infinite}
.dc-say{font-family:var(--edit);font-size:var(--fs-d3);color:var(--brass2);line-height:1.16;transition:opacity var(--mid) var(--ease);max-width:30ch}
.dc-say.fade{opacity:0}
.dc-wait .dc-meta{max-width:40ch}

/* when the line is down */
.dc-err{display:grid;gap:12px;justify-items:start;border-left:3px solid var(--red2);border-radius:3px;padding:16px;background:linear-gradient(90deg,rgba(126,50,43,.2),transparent 80%)}
.dc-err p{color:var(--cream2)}

/* the read, and the conversation that grows underneath it */
.dc-out:empty{display:none}
.dc-out{display:grid;gap:clamp(16px,2.4vh,24px)}
.dc-read p{color:var(--cream)}
.dc-read p+p{margin-top:1.1em}
/* the named service, on a cream enamel chip, the same plate the board uses.
   Selector carries .dc-read so it out-ranks the cream body colour above it;
   without that the oxblood ink loses and the chip reads cream on cream. */
.dc-read .dc-chip{display:inline-block;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.16em;text-transform:uppercase;
  color:#7E241F;background:linear-gradient(180deg,#F6ECD6,#E9DABB);border:1px solid rgba(0,0,0,.35);border-radius:3px;
  padding:6px 12px;margin-bottom:1rem;box-shadow:inset 0 1px 0 rgba(255,255,255,.7);
  text-shadow:0 1px 0 rgba(255,255,255,.4)}
.dc-turn{border-left:2px solid var(--line2);padding-left:16px}
.dc-q{font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--mut)}
.dc-qt{color:var(--brass2);font-family:var(--edit);font-size:var(--fs-d3);line-height:1.16;margin-top:4px}
.dc-a{margin-top:.75rem;color:var(--cream2)}
.dc-a p+p{margin-top:1.1em}
.dc-bad{color:#E25B4E}

/* keep asking */
.dc-ask{display:grid;gap:8px;border-top:1px solid var(--line);padding-top:clamp(16px,2.4vh,24px)}
.dc-askrow{display:flex;gap:8px;flex-wrap:wrap}
.dc-askrow .inp{flex:1 1 200px;min-width:0}
.dc-askrow .more{margin-top:0;flex-shrink:0}
.dc-left{font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.14em;text-transform:uppercase;color:var(--mut)}
/* inline links inside the consult hold the same 44px floor the footer and the
   plates already hold */
.dc-left a,.dc-teaser a{display:inline-flex;align-items:center;min-height:44px;color:var(--brass2);border-bottom:1px solid rgba(194,142,63,.45);transition:border-color var(--fast)}
.dc-left a:hover,.dc-teaser a:hover{border-color:var(--brass2)}

/* the commercial point */
.dc-lead{display:grid;gap:clamp(12px,2vh,16px);border-top:1px solid var(--line);padding-top:clamp(16px,2.4vh,24px)}
.dc-two{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:560px){.dc-two{grid-template-columns:1fr}}
.dc-lead .btn{width:100%;justify-content:center}
.dc-sent{border-left:3px solid var(--brass);border-radius:3px;padding:16px;background:rgba(194,142,63,.1)}
.dc-sent p{color:var(--cream2);margin-top:.5rem}
.dc-sent:focus-visible{outline:2px solid var(--brass2);outline-offset:3px}
/* these three are scrolled to programmatically. The fixed call plaque owns the
   bottom of a phone screen, so they clear it by the same token the footer uses. */
.dc-out,.dc-err,.dc-sent{scroll-margin-bottom:var(--pill-clear)}

/* the honest line, always on screen, never tucked away. Sentence case and
   normal tracking: this one is meant to be read, not glanced at. */
.dc-note{border-top:1px solid var(--line);padding-top:12px;font-family:var(--body);font-size:max(12px,.78rem);
  line-height:1.6;letter-spacing:.005em;color:var(--mut);text-transform:none}
.dc-note b{color:var(--cream2);font-weight:600}
.dc-note .acc{font-size:1em;color:var(--brass2)}

/* ================================================================ SHOP ===== */
.story{display:grid;grid-template-columns:1.1fr 1fr;gap:clamp(32px,6vw,88px);align-items:start}
.rules{border-top:1px solid var(--line);margin-top:2rem}
.rule{display:grid;grid-template-columns:72px 1fr;gap:1rem;align-items:center;padding:clamp(16px,2.4vh,24px) 0;border-bottom:1px solid var(--line);transition:padding-left var(--mid) var(--ease)}
.rule:hover{padding-left:12px}
/* house rules are counted the way a barber counts: notches on the strop.
   One brass notch per rule, cut in as the rule arrives. */
.rule .n.tally{display:inline-flex;align-items:center;gap:4px}
.rule .tally i{width:2px;height:18px;border-radius:1px;background:var(--brass);opacity:.8;transform:skewX(-14deg)}
.js .rule.rv .tally i{transform:skewX(-14deg) scaleY(0);transform-origin:50% 100%;transition:transform var(--mid) var(--ease)}
.js .rule.rv.on .tally i{transform:skewX(-14deg) scaleY(1)}
.js .rule.rv.on .tally i:nth-child(2){transition-delay:.06s}
.js .rule.rv.on .tally i:nth-child(3){transition-delay:.12s}
.js .rule.rv.on .tally i:nth-child(4){transition-delay:.18s}
.js .rule.rv.on .tally i:nth-child(5){transition-delay:.24s}
.rule .t{font-family:var(--text);font-weight:500;font-size:var(--fs-body);line-height:1.5;color:var(--cream)}
.js .rule.rv{transform:translateX(-12px)}
.js .rule.rv.on{transform:none}
.rules .rule:nth-child(2){transition-delay:.06s}
.rules .rule:nth-child(3){transition-delay:.12s}
.rules .rule:nth-child(4){transition-delay:.18s}
.rules .rule:nth-child(5){transition-delay:.24s}
.phs{display:flex;flex-direction:column;gap:24px}
.phs .ph{position:relative;overflow:hidden}
.phs .ph img{filter:sepia(.24) contrast(1.04) brightness(.72)}
.phs .ph.a img{aspect-ratio:4/3}
@media(max-width:940px){.story{grid-template-columns:1fr}}

/* ================================================================ VISIT ==== */
/* Hours are the hero here: big type, drawn ledger lines. */
.hours{margin-top:clamp(8px,2vh,16px)}
.hours .row{display:flex;justify-content:space-between;align-items:baseline;gap:16px;padding:clamp(12px,2vh,24px) 0;border-bottom:1px solid var(--line);color:var(--cream2)}
.hours .row .day{font-family:var(--disp);font-size:var(--fs-d3);letter-spacing:.02em;text-transform:uppercase;color:var(--cream);line-height:.95}
.hours .row .hrs{font-family:var(--body);font-weight:500;font-size:var(--fs-body);color:var(--cream2);white-space:nowrap}
.hours .row.today .day{color:var(--brass2)}
.hours .row.today .day::after{content:"today";margin-left:12px;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--blue);vertical-align:middle}
.js .hours.rv .row{opacity:0;border-bottom-color:transparent;background:linear-gradient(var(--line),var(--line)) no-repeat 0 100%/0% 1px;transition:opacity var(--mid) var(--ease),background-size var(--slow) var(--ease)}
.js .hours.rv.on .row{opacity:1;background-size:100% 1px}
.js .hours.rv.on .row:nth-child(2){transition-delay:.12s}
.js .hours.rv.on .row:nth-child(3){transition-delay:.24s}
.tonight{margin-top:1.5rem;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.22em;text-transform:uppercase;color:var(--blue)}
.vgrid{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(32px,6vw,80px);align-items:start}
@media(max-width:940px){.vgrid{grid-template-columns:1fr}}
.infos{display:grid;gap:clamp(16px,3vh,32px)}
.info h3{font-family:var(--disp);font-size:var(--fs-d3);text-transform:uppercase;margin-bottom:.5rem;line-height:.95}
.info p{color:var(--cream2);font-size:var(--fs-body)}
/* the chair-leather card: oxblood, hand-stitched inset, brass warmth on top */
.plate{position:relative;overflow:hidden;border:1px solid rgba(0,0,0,.55);border-radius:12px;padding:clamp(16px,3vw,32px);
  background:radial-gradient(140% 100% at 20% 0%,#42221776 0%,transparent 55%),linear-gradient(160deg,#3B1E15,#2A130C 60%,#241009);
  box-shadow:inset 0 1px 0 rgba(255,214,150,.09),0 10px 30px rgba(0,0,0,.35);
}
.plate::after{content:"";position:absolute;inset:10px;border:1px dashed rgba(226,190,133,.35);border-radius:7px;pointer-events:none}
.plate .pole-strip{position:absolute;left:0;top:0;bottom:0;width:7px}
/* instrument line: coordinates etched at the plate's foot */
.plate-meta{margin-top:1.5rem;padding-top:12px;border-top:1px solid var(--line);font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--mut)}

/* ================================================================ BOOK ===== */
/* utility page: compact hero, the form starts inside the first screen */
/* the booking head runs on the same interval as .phead: one head rhythm
   across all five pages, so the form starts after the same break the
   board and the hours get. */
.bhead{position:relative;padding-block:calc(var(--nav-h) + clamp(56px,11vh,112px)) clamp(56px,9vh,88px);overflow:hidden}
.bhead::after{content:"";position:absolute;inset:0;z-index:0;background:radial-gradient(60% 90% at 50% 130%,rgba(224,166,74,.22),transparent 62%);pointer-events:none}
.bhead .in{position:relative;z-index:2}
.bhead h1{font-family:var(--disp);font-size:var(--fs-d1);line-height:.86;letter-spacing:-.012em;text-transform:uppercase}
.bhead h1 .o{color:transparent;-webkit-text-stroke:2px var(--brass)}
.bhead .edit{display:block;font-size:var(--fs-d3);margin-top:.75rem;transform:rotate(-2deg);transform-origin:0 50%;position:relative;z-index:3;max-width:max-content}
.bgrid{display:grid;grid-template-columns:1.25fr .75fr;gap:clamp(32px,5vw,72px);align-items:start;padding-bottom:clamp(72px,11vh,128px)}
@media(max-width:940px){.bgrid{grid-template-columns:1fr}}
.form{display:grid;gap:clamp(16px,2.4vh,24px)}
.field{display:grid;gap:8px}
.field>span.lab{color:var(--cream2)}
.opts{display:flex;gap:8px;flex-wrap:wrap}
.opt{position:relative}
.opt input{position:absolute;opacity:0;width:100%;height:100%;left:0;top:0;margin:0;cursor:pointer}
/* enamel chips: dark plate resting state, cream enamel with a red pinstripe
   when picked. Square shoulders, not pills. */
.opt span{display:inline-flex;align-items:center;min-height:44px;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.14em;text-transform:uppercase;color:var(--cream2);border:1px solid rgba(194,142,63,.3);border-radius:3px;background:linear-gradient(180deg,#241811,#1D130B);box-shadow:inset 0 1px 0 rgba(242,230,206,.05);padding:8px 16px;transition:var(--mid) var(--ease);pointer-events:none}
.opt input:checked+span{border-color:rgba(0,0,0,.4);color:#7E241F;background:linear-gradient(180deg,#F6ECD6,#E9DABB);box-shadow:inset 0 0 0 3px #F2E7CF,inset 0 0 0 4px rgba(166,55,48,.5),inset 0 1px 0 rgba(255,255,255,.7);text-shadow:0 -1px 0 rgba(23,16,8,.18),0 1px 0 rgba(255,255,255,.4)}
.opt input:focus-visible+span{outline:2px solid var(--brass2);outline-offset:3px}
.inp{width:100%;background:linear-gradient(180deg,#241811,#1D130B);border:1px solid rgba(194,142,63,.32);border-radius:3px;box-shadow:inset 0 1px 0 rgba(242,230,206,.06);padding:16px;color:var(--cream);font-family:var(--body);font-size:var(--fs-body);transition:border-color var(--fast)}
.inp.miss,.inp.miss:focus,.inp.miss:focus-visible{border-color:var(--red2)}
.inp::placeholder{color:var(--mut)}
.inp:focus{outline:none;border-color:var(--brass)}
.inp:focus-visible{outline:2px solid var(--brass2);outline-offset:2px}
select.inp{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--brass2) 50%),linear-gradient(135deg,var(--brass2) 50%,transparent 50%);background-position:calc(100% - 20px) 21px,calc(100% - 14px) 21px;background-size:6px 6px,6px 6px;background-repeat:no-repeat;padding-right:44px}
.form .send{justify-self:start;margin-top:.5rem}
/* error red is lifted above the accent red on purpose: #CB4A40 on this wood
   is 4.12:1 and fails AA at label size; #E25B4E clears 5:1 */
.form-err{color:#E25B4E;letter-spacing:.14em}
@media(max-width:700px){
  .form .send{justify-self:stretch;width:100%}
  .mani .quote{margin-top:1.5rem}
  .close-cta .wrap{padding-block:clamp(56px,9vh,80px) 48px}
}
.bnote{margin-top:1rem;font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.2em;text-transform:uppercase;color:var(--mut);border-top:1px solid var(--line);padding-top:12px;max-width:52ch}
/* the confirmation card is leather too, with a brass keyline instead of stitches */
.said{display:none;position:relative;overflow:hidden;border:1px solid rgba(0,0,0,.55);border-radius:12px;
  background:radial-gradient(140% 100% at 20% 0%,#42221776 0%,transparent 55%),linear-gradient(160deg,#3B1E15,#2A130C 60%,#241009);
  box-shadow:inset 0 1px 0 rgba(255,214,150,.09),0 10px 30px rgba(0,0,0,.35);
  padding:clamp(16px,2.6vw,24px)}
.said::after{content:"";position:absolute;inset:10px;border:1px dashed rgba(226,190,133,.35);border-radius:7px;pointer-events:none}
.said.on{display:block}
.said .d3{color:var(--brass2)}
.said p{color:var(--cream2);margin-top:.5rem;font-size:var(--fs-body)}
.said .btn{position:relative;z-index:4}

/* ====================================================== CLOSING MOMENT ===== */
/* every page (except the form itself) lands on one last big ask */
.close-cta{position:relative;overflow:hidden;border-top:1px solid var(--line);background:radial-gradient(70% 95% at 50% 118%,rgba(224,166,74,.16),transparent 62%)}
.close-cta .wrap{padding-block:clamp(80px,13vh,160px)}
/* the right column carries tonight's ledger: no half-viewport voids */
.cc-g{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(32px,5vw,80px);align-items:center}
.cc-plate{max-width:460px;justify-self:end;width:100%}
@media(max-width:940px){.cc-g{grid-template-columns:1fr}.cc-plate{justify-self:stretch;max-width:none;margin-top:1rem}}
.cc-t{font-family:var(--disp);font-size:var(--fs-d1);line-height:.86;letter-spacing:-.012em;text-transform:uppercase;margin-top:1rem}
.cc-t .o{display:inline-block;margin-left:clamp(1.5rem,6vw,5rem)}
.cc-sub{display:inline-block;font-size:var(--fs-d3);margin-top:1rem}
.close-cta .cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:2rem}
/* in the close, the gold plate is the only accent allowed to speak:
   the live line reads in cream, its diamond still carrying the mark */
.cc-live{margin-top:1rem;color:var(--cream2)}
/* the ask never fades in as one slab: its pieces file in on a 60ms cadence */
.js .close-cta .cc-t.rv{transition-delay:.06s}
.js .close-cta .cc-sub.rv{transition-delay:.12s}
.js .close-cta .cta.rv{transition-delay:.18s}
.js .close-cta .cc-plate.rv{transition-delay:.24s}

/* ============================================================== FOOTER ===== */
.foot{padding:0 0 calc(72px + env(safe-area-inset-bottom));border-top:1px solid rgba(0,0,0,.4);position:relative;overflow:hidden;background:var(--wood2)}
.foot .fin{padding-top:clamp(56px,8vh,104px)}
.foot-top{display:flex;justify-content:space-between;flex-wrap:wrap;gap:2rem;position:relative;z-index:2}
.foot h3{font-family:var(--disp);font-size:var(--fs-d2);text-transform:uppercase;letter-spacing:.02em;line-height:.9}
/* the phone number is the single most important line on a barbershop site:
   display size, brass, and always a live tel: link */
.foot-tel{font-family:var(--disp);font-size:var(--fs-d3);color:var(--brass2);letter-spacing:.04em;margin-top:1rem}
.foot-tel a,.ph-line a,.m-tel a,.plate-tel a{color:inherit;border-bottom:1px solid rgba(194,142,63,.45);padding-bottom:2px;transition:border-color var(--fast)}
.foot-tel a:hover,.ph-line a:hover,.m-tel a:hover,.plate-tel a:hover{border-color:var(--brass2)}
.foot-tel a{display:inline-flex;align-items:center;min-height:44px}
.foot-live{margin-top:.5rem}
.foot .col a{font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.14em;text-transform:uppercase}
.foot .cols{display:flex;gap:clamp(2rem,5vw,4rem);flex-wrap:wrap}
.foot .col h4{margin-bottom:.75rem}
.foot .col p{color:var(--cream2);font-size:var(--fs-body);padding:4px 0}
/* footer links hold the 44px floor like everything else tappable */
.foot .col a{color:var(--cream2);transition:color var(--fast);display:inline-flex;align-items:center;min-height:44px}
.foot .col a:hover{color:var(--brass2)}
.foot .col p:has(a){padding:0}
.foot-bot{margin-top:5vh;padding-top:3vh;border-top:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem;font-size:.76rem;font-family:var(--body);color:var(--mut);position:relative;z-index:2}
.foot-bot a{color:var(--brass2);display:inline-flex;align-items:center;min-height:44px}

/* preview pill: SOLID base. Giant footer type must never bleed through it. */
.demo{
  position:fixed;bottom:calc(10px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);
  z-index:200;background:linear-gradient(rgba(194,142,63,.16),rgba(194,142,63,.16)),#180F08;
  border:1px solid var(--brass);color:var(--brass2);
  display:flex;align-items:center;gap:8px;min-height:44px; /* the link inside must be tappable */
  font-family:var(--body);font-weight:600;font-size:var(--fs-lab);letter-spacing:.1em;text-transform:uppercase;
  padding:8px 16px;border-radius:3px;white-space:nowrap;
  max-width:calc(100vw - 20px);overflow:hidden;text-overflow:ellipsis;
}
.demo a{color:var(--cream);text-decoration:underline;padding:8px 2px}

/* on phones the bottom slot belongs to the business, not the studio:
   a gold call plaque takes it, the demo pill yields, and the preview
   disclosure moves into the menu + footer (still on every page). */
.call-pill{display:none}
@media(max-width:700px){
  .demo{display:none}
  .call-pill{
    position:fixed;bottom:calc(10px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);
    z-index:200;display:inline-flex;align-items:center;gap:12px;min-height:48px;
    font-family:var(--disp);font-size:max(13px,.95rem);letter-spacing:.08em;text-transform:uppercase;
    color:#221302;background:linear-gradient(175deg,#EFC873 0%,#D5A34A 38%,#B07E2E 64%,#A87A2C 100%);
    text-shadow:0 -1px 0 rgba(23,16,8,.28),0 1px 0 rgba(255,246,224,.45);
    box-shadow:inset 0 1px 0 rgba(255,246,224,.7),inset 0 -2px 0 rgba(60,32,4,.45),0 12px 28px rgba(0,0,0,.5);
    padding:8px 24px;border-radius:3px;white-space:nowrap;
  }
  .call-pill .pole{width:9px;height:20px;border-radius:2px;flex-shrink:0;animation:pole var(--pole-speed) linear infinite;box-shadow:0 0 8px rgba(23,16,8,.35)}
}

/* ---- the bottom docks yield while you read ----
   Both docks are position:fixed, so on a phone they sat over the copy at
   every scroll position: over body text, over prices, over the hero's own
   Book button. html.docked (set by the scroll handler in app.js) drops them
   out of the way on the way down, and they come back the moment you scroll
   up, so the bottom of the screen belongs to the page while you are reading
   and to the shop the moment you go looking for it.

   This uses the `translate` longhand rather than `transform`, because .demo
   and the wide-screen .call-pill already spend their transform on
   translateX(-50%) to centre themselves. Overwriting that would throw them
   sideways on the way out. `translate` composes ahead of `transform`, so the
   centring survives untouched.

   Neither dock is ever unreachable: they hold still at the top of the page,
   at the very bottom, while the chat panel is open, while anything inside
   them has focus, and under reduced motion. */
.call-pill,.demo,.mox{transition:translate var(--mid) var(--ease),opacity var(--mid) var(--ease)}
html.docked .call-pill,html.docked .demo,html.docked .mox{
  translate:0 calc(100% + 28px + env(safe-area-inset-bottom));opacity:0;pointer-events:none}
/* keyboard focus is not blocked by pointer-events, so a tabbed-to dock
   pulls itself back into view instead of acting from off screen */
html.docked .call-pill:focus-within,html.docked .demo:focus-within,
html.docked .mox:focus-within,html.docked .mox[data-open="true"]{
  translate:none;opacity:1;pointer-events:auto}
@media (prefers-reduced-motion: reduce){
  html.docked .call-pill,html.docked .demo,html.docked .mox{
    translate:none;opacity:1;pointer-events:auto}
}

/* phone lines outside the footer: menu overlay and the closing plates.
   Same signage voice as .foot-tel: the number always reads like the sign. */
.m-tel,.plate-tel{font-family:var(--disp);font-size:var(--fs-d3);color:var(--brass2);letter-spacing:.04em}
.m-tel{margin-top:.5rem}
.plate-tel{margin-top:1rem}
.m-tel a,.plate-tel a{display:inline-flex;align-items:center;min-height:44px}
.m-side .m-note a{color:var(--brass2);border-bottom:1px solid var(--line);padding-bottom:2px}

/* evenings: the lamps come up a touch */
html.after-dark .stat{border-left-color:var(--red2)}
html.after-dark .vig{background:
  radial-gradient(60% 42% at 50% 0%,rgba(224,166,74,.1),transparent 62%),
  radial-gradient(120% 90% at 50% 40%,transparent 55%,rgba(11,6,2,.6) 100%)}
html.after-dark .hero .ph::after{background:linear-gradient(180deg,rgba(23,16,8,.55),rgba(23,16,8,.42) 45%,rgba(23,16,8,.95)),radial-gradient(70% 60% at 78% 18%,rgba(224,166,74,.3),transparent 62%)}
html.after-dark .bhead::after{background:radial-gradient(60% 90% at 50% 130%,rgba(224,166,74,.3),transparent 64%)}

/* ============================================================== MOBILE ===== */
@media(max-width:700px){
  :root{--nav-h:58px}
  .brand{font-size:1.12rem}
  .brand .pole{width:9px;height:21px}
  .book-pill{padding:8px 16px;letter-spacing:.08em}
  .menu-btn{letter-spacing:.14em;gap:8px}
  .hero h1{font-size:min(31vw,25vh)}
  .hero .script{font-size:1.5rem}
  .hero .row{margin-top:1.5rem}
  /* phones: keep the photo alive deeper into the screen */
  .hero .ph::after{background:linear-gradient(180deg,rgba(23,16,8,.5),rgba(23,16,8,.22) 58%,rgba(23,16,8,.94)),radial-gradient(70% 60% at 78% 18%,rgba(224,166,74,.24),transparent 60%)}
  .scroll-cue{display:none}
  /* the status line is long (place + clock + open state): hold 11px and buy
     the room back from tracking rather than shrinking the text */
  /* the strip lost its location tag and now carries clock, state and next
     opening. Three facts will not fit one line inside the width the pole
     leaves it, so it is set as a compact two-line plaque rather than a
     one-line pill with body leading pulling it 54px tall. */
  .stat{letter-spacing:.05em;padding:7px 12px;line-height:1.34}
  .marq .set{font-size:1.25rem}
  .btn{padding:16px 24px 15px;font-size:max(13px,.95rem)}
  .checks{height:12px;background-size:24px 24px}
  .frame,.proof .g,.phs .ph{padding:8px}
  .foot-top{gap:1.5rem}
  /* mobile pacing: desktop air reads as dead brown on a phone.
     The rhythm holds: manifesto widest, teaser tightest. */
  :root{--sec-lead:clamp(48px,8vh,80px);--sec-tail:clamp(16px,2.5vh,28px)}
  .sec{padding-block:var(--sec-lead) var(--sec-tail)}
  #consult{padding-block:clamp(56px,10vh,96px) var(--sec-tail)}
  .teaser{padding-block:clamp(40px,6vh,64px) var(--sec-tail)}
  .sec.proof{padding-block:clamp(40px,6vh,72px)}
  .close-cta .wrap{padding-block:clamp(64px,10vh,112px)}
  .mani .big{font-size:clamp(1.5rem,6.4vw,2.2rem)}
  .rule{grid-template-columns:44px 1fr;gap:1rem}
  .crow .bk{display:flex;justify-content:center;justify-self:stretch;text-align:center;padding:8px 16px}
  .more{display:flex;justify-content:center;text-align:center;padding:8px 16px}
  .close-cta .btn{width:100%;justify-content:center}
  .house-chip{display:inline-block;margin-left:8px;transform:translateY(-.2em)}
  /* the consult on a phone: one column, plaques full width, and the photo
     never allowed to eat the whole screen */
  .dc-picks .btn,.dc-acts .btn{width:100%;justify-content:center}
  .dc-pick,.dc-picks,.dc-acts{width:100%}
  .dc-shot img{max-height:44vh}
  .dc-askrow .inp{flex:1 1 100%}
  .dc-askrow .more{width:100%}
  .dc-in{padding-left:4px}
}
/* narrow phones: shorten the CTA label instead of shrinking the type */
.book-pill .bp-short{display:none}
@media(max-width:430px){
  .book-pill .bp-long{display:none}
  .book-pill .bp-short{display:inline}
  .brand{font-size:1rem;gap:8px}
  .book-pill{padding:8px 12px}
  .menu-btn .bars{width:18px}
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001s!important;animation-iteration-count:1!important;transition-duration:.001s!important;transition-delay:0s!important;animation-delay:0s!important}
  .js .rv,.js .hero [data-rise],.js .hero h1 .ch-s{opacity:1!important;transform:none!important}
  .js .hero .stat[data-rise]{clip-path:none!important}
  .hero-amb{display:none!important}
  .js .rv-l{clip-path:none!important}
  .js .hours.rv .row{opacity:1!important;background-size:100% 1px!important}
  .js .mats.rv li{opacity:1!important;transform:none!important}
  .js .trow.rv .nm::after,.js .crow.rv .nm::after{clip-path:none!important}
  .js .rule.rv .tally i{transform:skewX(-14deg)!important}
  /* the consult: steps arrive already in place, the waiting pole holds still
     (the JS also stops rotating its copy), and nothing fades */
  .js .dc-steps.rv li{opacity:1!important;transform:none!important}
  .dc-pole{animation:none!important}
  .dc-say{opacity:1!important}
}




/* ==========================================================================
   THE PRESS  ::  touch feedback, Duskline Barber Co.
   ==========================================================================
   Paired with haptics.js. That file vibrates on Android and finds nothing to
   vibrate with on iOS, because Apple has never shipped a web haptics API and
   there is no way around that. So on an iPhone this block is the whole of the
   tactile feedback, and it is written to carry that weight on its own.

   Same selector list as haptics.js, deliberately: nothing on either site
   buzzes without visibly pressing, and nothing visibly presses without
   buzzing where buzzing is possible.

   The press is a 2.8% scale down with the lift taken away: the control goes
   into the surface rather than lighting up. It lands with a 0ms transition and
   releases over 150ms, because a press that eases in feels late and a release
   that snaps feels cheap.

   Under prefers-reduced-motion the scale is dropped and only the colour shift
   survives, so the feedback is still there for anyone who asked for stillness.
   -------------------------------------------------------------------------- */
/* kills the 300ms tap delay that made every one of these feel late */
a,button,summary,label,[role="button"],input,select,textarea{touch-action:manipulation}
@media (hover:none){
  a,button,summary,label,[role="button"]{-webkit-tap-highlight-color:transparent}
}
  .btn,.m-link,.book-pill,
  .cta,.more,.bk,
  .crow,.trow,.gcard,
  .house,.rule,.menu-btn,
  .brand,a[href],button,
  summary,[role="button"]{
  transition-property:transform,opacity,color,background-color,border-color,box-shadow;
  transition-duration:150ms;
  transition-timing-function:cubic-bezier(.4,0,.2,1);
}
  .btn,.m-link,.book-pill,
  .cta,.more,.bk,
  .crow,.trow,.gcard,
  .house,.rule,.menu-btn,
  .brand,a[href],button,
  summary,[role="button"]{
  -webkit-user-select:none;user-select:none;
}
@media (prefers-reduced-motion:no-preference){
    .btn:active,.m-link:active,.book-pill:active,
    .cta:active,.more:active,.bk:active,
    .crow:active,.trow:active,.gcard:active,
    .house:active,.rule:active,.menu-btn:active,
    .brand:active,a[href]:active,button:active,
    summary:active,[role="button"]:active{
    transform:scale(.972);
  }
    .work-card:active,.plan:active,.pour:active,.gcard:active,.house:active{
    transform:scale(.994);
  }
}
  .btn:active,.m-link:active,.book-pill:active,
  .cta:active,.more:active,.bk:active,
  .crow:active,.trow:active,.gcard:active,
  .house:active,.rule:active,.menu-btn:active,
  .brand:active,a[href]:active,button:active,
  summary:active,[role="button"]:active{
  color:#E4B963;opacity:1;
}
.btn:active,.q-h:active,.menu-btn:active,.menu-toggle:active,
.burger:active,.copychip:active{
  background-color:rgba(226,185,99,.10);box-shadow:none;
}
/* the press itself is instant; only the release is timed */
  .btn:active,.m-link:active,.book-pill:active,
  .cta:active,.more:active,.bk:active,
  .crow:active,.trow:active,.gcard:active,
  .house:active,.rule:active,.menu-btn:active,
  .brand:active,a[href]:active,button:active,
  summary:active,[role="button"]:active{transition-duration:0ms}

/* ==== Moxireel pass, crowding and the bottom docks ====
   Two gold pills were parked over the booking form: the call plaque fixed
   bottom-centre and the chat launcher bottom-right, covering the phone
   field a customer is trying to type into. The bottom edge now has two
   small docks: call bottom-left, chat bottom-right, and the page keeps
   enough clear floor that no field ever sits underneath either. */
@media(max-width:640px){
  .call-pill{left:calc(12px + env(safe-area-inset-left));right:auto;transform:none;
    min-height:46px;gap:8px;font-size:12px;padding:0 14px}
  main{padding-bottom:calc(84px + env(safe-area-inset-bottom))}
}

/* ==========================================================================
   THE SIGNATURE MOMENT: A BARBER POLE IN REAL 3D.  ->  .pole3d

   Twenty vertical faces arranged in a cylinder, each carrying its slice of
   the diagonal stripe, with brass caps top and bottom. It idles at a slow
   professional turn; grab it and it spins with your hand and keeps your
   momentum when you let go. All transforms, one rAF loop, no library.
   This is the "included free" signature and the proof of it.
   ========================================================================== */
/* Placement: it floats in the hero's dark upper right, clear of the
   headline, the stat pill, the vertical caption and both bottom docks.
   The first placement stacked it at the bottom of hero-right, where it
   collided with the call plaque on phones and clipped at the fold on
   desktop. Absolute against the hero, high and right, fixes both screens
   with one rule each. */
.pole3d{position:absolute;z-index:4;width:92px;height:230px;
  right:clamp(56px,7vw,120px);top:16%;
  perspective:640px;cursor:grab;touch-action:pan-y;user-select:none}
.pole3d:active{cursor:grabbing}
.p3-drum{position:absolute;inset:18px 0;transform-style:preserve-3d}
.p3-drum b{position:absolute;left:50%;top:0;width:16px;height:100%;margin-left:-8px;
  /* each face gets its slice of stripe via background-position set inline */
  background-image:repeating-linear-gradient(55deg,
    #A63730 0 14px, var(--cream) 14px 28px, #3D6FB8 28px 42px, var(--cream) 42px 56px);
  backface-visibility:hidden;
  box-shadow:inset 0 0 0 .5px rgba(23,16,8,.08)}
/* glass tube highlight over the whole drum */
.p3-drum::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(23,16,8,.42) 0%,rgba(255,255,255,0) 22%,
    rgba(255,255,255,.34) 46%,rgba(255,255,255,0) 70%,rgba(23,16,8,.46) 100%);
  border-radius:10px}
.p3-cap{position:absolute;left:6px;right:6px;height:22px;border-radius:9px;
  background:linear-gradient(180deg,var(--brass2),var(--brass) 55%,#8a6224);
  box-shadow:0 3px 10px rgba(23,16,8,.5), inset 0 1px 0 rgba(255,255,255,.35)}
.p3-top{top:0}.p3-bot{bottom:0}
.p3-hint{position:absolute;left:50%;bottom:-22px;transform:translateX(-50%);
  font-family:var(--disp);font-size:11px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--brass2);white-space:nowrap;opacity:.85}
/* placement: desktop it stands above the creed. On phones the hero is tight,
   so it docks smaller and the hint carries the invitation. */
@media(max-width:900px){
  .pole3d{width:58px;height:150px;right:14px;top:172px} /* beside DUSK, clear of everything */
  .p3-cap{height:16px;border-radius:7px}
  .p3-drum{inset:13px 0}
  .p3-hint{font-size:9px;bottom:-18px}
  /* the status plaque grows with the live clock text ("closed, opens 10am
     tomorrow" wraps it to two lines) and was running under the pole. Cap it
     so its right edge always stops 24px short of the pole's column:
     100vw - pad(left gutter) - 58(pole) - 14(pole right) - 24(air) */
  .hero .stat{max-width:calc(100vw - var(--pad) - 96px)}
}
@media(prefers-reduced-motion:reduce){
  .pole3d{cursor:default}
}
