/* ==========================================================================
   The Urban Shave
   One system: one token set, one panel, one radius scale, one motion language.
   ========================================================================== */

@font-face {
  font-family: 'Anton';
  src: url('assets/fonts/anton-latin.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('assets/fonts/archivo-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('assets/fonts/archivo-italic-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

:root {
  /* Surfaces. Flat near-black reads cheap on a photograph; every step carries a
     little blue so the dark has depth instead of looking like an empty div. */
  --bg: #0b0d11;
  --surface: #14171d;
  --surface-hi: #1a1e26;
  --line: #262b34;
  --line-hi: #39404c;

  /* Ink */
  --text: #f4f5f7;
  --muted: #98a0ad;

  /* One accent, the shop's red */
  --red: #e03a3d;
  --red-soft: rgba(224, 58, 61, 0.13);

  /* One radius scale */
  --r: 16px;
  --r-sm: 10px;

  /* One motion language. Strong custom curves: the stock CSS easings are too
     weak to read as intentional, and ease-in is never used because it delays
     the exact moment the eye is watching. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease: var(--ease-out);
  --press: 140ms;
  --fast: 180ms;
  --slow: 620ms;
  --reveal: 900ms;

  --shell: 1180px;
  --pad: clamp(1.25rem, 4vw, 2.5rem);
  --gap: clamp(1rem, 1.6vw, 1.25rem);

  --display: 'Anton', 'Arial Narrow', sans-serif;
  --sans: 'Archivo', system-ui, -apple-system, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, p, figure, blockquote, ul { margin: 0; }
ul { padding: 0; list-style: none; }
img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
  border-radius: 4px;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad);
}

/* ---------- Motion ----------
   Two reveals, and only two. Text and blocks rise; images are wiped open with
   clip-path so a photograph is uncovered rather than faded in. */

.anim .rise, .anim .card, .anim .line {
  opacity: 0;
  transform: translateY(18px);
}
.anim .rise.in, .anim .card.in, .anim .line.in {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--slow) var(--ease-out) calc(var(--i, 0) * 60ms),
    transform var(--slow) var(--ease-out) calc(var(--i, 0) * 60ms);
}

.line-mask { display: block; overflow: hidden; padding-bottom: 0.06em; }
.line { display: block; }
.anim .line { transform: translateY(100%); }
.anim .line.in { transform: none; }

/* Image wipe. The frame uncovers from the bottom while the photo inside
   settles from a slight overscale, so the picture appears to be revealed by
   the edge rather than sliding as one flat object. */
.anim .frame.wipe {
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--reveal) var(--ease-in-out) calc(var(--i, 0) * 60ms);
}
.anim .frame.wipe > img {
  transform: scale(1.08);
  transition: transform 1400ms var(--ease-out) calc(var(--i, 0) * 60ms);
}
.anim .frame.wipe.in { clip-path: inset(0 0 0 0); }
.anim .frame.wipe.in > img { transform: scale(1); }

/* ---------- Buttons: one shape, two weights ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.95rem 1.7rem;
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--fast) var(--ease),
              border-color var(--fast) var(--ease),
              transform var(--fast) var(--ease);
}
.btn-sm { padding: 0.6rem 1.2rem; font-size: 0.875rem; }

.btn-primary { background: var(--red); color: #fff; }
.btn-ghost { border-color: var(--line-hi); color: var(--text); }

.btn:active { transform: scale(0.97); }
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { background: #ee4649; }
  .btn-ghost:hover { border-color: var(--text); background: rgba(255, 255, 255, 0.04); }
}

/* ---------- Nav ---------- */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  height: 68px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  transition: background-color 300ms var(--ease), border-color 300ms var(--ease);
}
.nav.stuck {
  background: rgba(11, 13, 17, 0.85);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--line);
}
.nav-inner {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}
.nav-brand {
  font-family: var(--display);
  font-weight: 400;
  font-size: 1.05rem;
  white-space: nowrap;
}
.brand-the { font-size: 0.62em; color: var(--muted); }
.brand-shave { color: var(--red); }

.nav-links { display: flex; gap: 2rem; }
.nav-links a {
  position: relative;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--muted);
  transition: color var(--fast) var(--ease);
}
.nav-links a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 1px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 260ms var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .nav-links a:hover { color: var(--text); }
  .nav-links a:hover::after { transform: scaleX(1); }
}

/* ---------- Hero: full bleed ---------- */

.hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  padding-block: clamp(7rem, 14vh, 9rem) clamp(4rem, 10vh, 7rem);
  overflow: hidden;
}
.hero-media { position: absolute; inset: 0; }
.hero-media img,
.hero-media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transform: scale(1.04);
  animation: hero-settle 2.4s var(--ease) forwards;
}
@keyframes hero-settle { to { transform: scale(1); } }

/* Holds the type legible on the left while the chair stays lit on the right,
   and lands the bottom edge on the page colour so the section has no seam. */
.hero-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(95deg, rgba(11,13,17,0.94) 0%, rgba(11,13,17,0.82) 32%, rgba(11,13,17,0.34) 62%, rgba(11,13,17,0.12) 100%),
    linear-gradient(180deg, rgba(11,13,17,0.7) 0%, transparent 26%, transparent 62%, var(--bg) 100%);
}
.hero-copy { position: relative; z-index: 1; }
/* Display type earns its presence from scale and weight, not from a novelty
   face. Geometric sans needs negative tracking once it gets this large. */
.hero-title {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(3.6rem, 11.5vw, 10rem);
  line-height: 0.9;
  letter-spacing: 0.005em;
  text-transform: uppercase;
}
.hero-title em { font-style: normal; color: var(--red); }
.hero-sub {
  margin-top: 1.5rem;
  max-width: 42ch;
  font-size: 1.08rem;
  color: var(--muted);
}
.hero-cta { margin-top: 2rem; display: flex; flex-wrap: wrap; gap: 0.75rem; }

.hero-status {
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.5rem;
  font-size: 0.9rem;
  color: var(--muted);
}
.status { display: inline-flex; align-items: center; gap: 0.55rem; color: var(--text); font-weight: 600; }
.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #35c17b;
  box-shadow: 0 0 0 4px rgba(53, 193, 123, 0.16);
}
.status.closed .status-dot { background: var(--muted); box-shadow: 0 0 0 4px rgba(155, 155, 164, 0.14); }
.hero-rating { display: inline-flex; align-items: center; gap: 0.5rem; }
.stars { color: var(--red); letter-spacing: 0.14em; font-size: 0.85rem; }

/* ---------- The frame: every image and video on the page sits in one ---------- */

.frame {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}
.frame img, .frame video, .frame iframe {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
}

/* ---------- Sections ---------- */

.section { padding-block: clamp(4.5rem, 10vw, 9rem); }
.section-head { margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section-title {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2.6rem, 7vw, 5.6rem);
  line-height: 0.94;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-wrap: balance;
}
.section-lede {
  margin-top: 1.1rem;
  color: var(--muted);
  font-size: 1.06rem;
  max-width: 46ch;
}

/* ---------- The card: one panel used by every section ---------- */

.card-grid { display: grid; gap: var(--gap); }
.cols-2 { grid-template-columns: repeat(2, 1fr); }
.cols-3 { grid-template-columns: repeat(3, 1fr); }
.cols-5 { grid-template-columns: repeat(5, 1fr); }

.card {
  display: flex;
  position: relative;
  flex-direction: column;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  transition:
    opacity var(--slow) var(--ease) calc(var(--i, 0) * 70ms),
    transform var(--slow) var(--ease) calc(var(--i, 0) * 70ms),
    border-color var(--fast) var(--ease),
    background-color var(--fast) var(--ease);
}
.card.in:active { transform: scale(0.99); }
@media (hover: hover) and (pointer: fine) {
  a.card:hover { border-color: var(--line-hi); background: var(--surface-hi); }
  a.card:hover .barber-book { color: var(--red); }
}

/* Services. The price is the answer people scroll for, so it is set as display
   type and given the top of the card, with the name beneath it. Same hover
   language as the roster: the card you are on comes forward while its
   neighbours ease back. */
.card-grid.services-grid { gap: clamp(0.75rem, 1.4vw, 1.25rem); }

.service {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  gap: 0;
  padding: clamp(1.5rem, 2.6vw, 2.25rem);
  transition: border-color 320ms var(--ease-out), transform 420ms var(--ease-out), box-shadow 420ms var(--ease-out);
}
.service::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(200deg, rgba(224, 58, 61, 0.20), rgba(224, 58, 61, 0.04) 45%, transparent 72%);
  opacity: 0;
  transition: opacity 460ms var(--ease-out);
}

.service-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}
.service h3 {
  order: 2;
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  font-weight: 650;
  letter-spacing: -0.015em;
  align-self: flex-end;
  text-align: right;
  max-width: 11ch;
}
.price {
  order: 1;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(3.2rem, 5.4vw, 5rem);
  line-height: 0.82;
  color: var(--red);
  transition: transform 420ms var(--ease-out);
}
.service p {
  margin-top: 1.4rem;
  color: var(--muted);
  font-size: 1rem;
  max-width: 40ch;
}
.chip {
  align-self: flex-start;
  margin-top: 1.5rem;
  padding: 0.32rem 0.75rem;
  border: 1px solid var(--line-hi);
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--muted);
  text-transform: uppercase;
  transition: border-color 260ms var(--ease-out), color 260ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .services-grid:hover .service { transform: scale(0.99); }
  .services-grid .service:hover {
    border-color: var(--line-hi);
    transform: scale(1.03) translateY(-6px);
    z-index: 2;
    box-shadow: 0 26px 60px rgba(0, 0, 0, 0.5);
  }
  .service:hover::before { opacity: 1; }
  .service:hover .price { transform: translateY(-3px); }
  .service:hover .chip { border-color: var(--red); color: var(--text); }
}
.services-grid .service:active { transform: scale(1.005) translateY(-2px); }

/* Barbers. Cards, but shaped like a person rather than a tile: tall portrait
   frames with the content anchored at the bottom the way a poster is, so a
   headshot drops in behind the name later without moving anything. The initial
   sits large and nearly transparent as texture, not as a placeholder shouting
   that a photo is missing. */
/* The grid reaches past the text column so five frames can be genuinely large
   without dropping a barber to a second row. Clamped, so it never exceeds the
   viewport on narrower screens. */
.chairs {
  --over: clamp(0px, calc((100vw - 3rem - var(--shell)) / 2), 300px);
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(0.75rem, 1.4vw, 1.25rem);
  margin-inline: calc(var(--over) * -1);
}

.chair {
  position: relative;
  display: flex;
  align-items: flex-end;
  aspect-ratio: 5 / 7;
  padding: clamp(1.25rem, 2.2vw, 2.1rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  isolation: isolate;
  transition: border-color 320ms var(--ease-out), transform 420ms var(--ease-out), box-shadow 420ms var(--ease-out);
}

/* Ghosted initial, cropped by the frame so it reads as texture. */
.chair-mark {
  position: absolute;
  z-index: -2;
  top: -0.18em;
  right: -0.06em;
  font-family: var(--display);
  font-size: 19rem;
  line-height: 0.8;
  color: #fff;
  opacity: 0.045;
  pointer-events: none;
  transition: opacity 420ms var(--ease-out), transform 620ms var(--ease-out);
}

/* The red wash rises from the bottom, the direction the eye is already
   travelling toward the name. */
.chair::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(0deg, rgba(224, 58, 61, 0.34), rgba(224, 58, 61, 0.06) 46%, transparent 76%);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 520ms var(--ease-out);
}

.chair-body { display: grid; gap: 0.5rem; }
.chair-name {
  font-family: var(--display);
  font-size: clamp(1.8rem, 2.9vw, 3.1rem);
  line-height: 0.95;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  transition: transform 420ms var(--ease-out);
}
.chair-go {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--muted);
  transition: color 260ms var(--ease-out), transform 420ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .chairs:hover .chair { transform: scale(0.985); }
  .chair:hover,
  .chairs .chair:hover { border-color: var(--line-hi); transform: scale(1.055) translateY(-8px); z-index: 2; box-shadow: 0 26px 60px rgba(0, 0, 0, 0.55); }
  .chair:hover::before { transform: scaleY(1); }
  .chair:hover .chair-mark { opacity: 0.11; transform: translateY(8px) scale(1.06); }
  .chair:hover .chair-name { transform: translateY(-2px); }
  .chair:hover .chair-go { color: #fff; transform: translateX(0.3rem); }
}
.chair:active, .chairs .chair:active { transform: scale(1.01) translateY(-4px); }

@media (max-width: 1000px) { .chairs { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 640px)  { .chairs { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 400px)  { .chairs { grid-template-columns: 1fr; } .chair { aspect-ratio: 16 / 7; } }

/* Work: a wall of real cuts. Two full-bleed tracks drift in opposite
   directions, which reads as a working shop rather than a static grid, and
   suits portrait phone photography far better than a uniform row. */
.work .section-head { margin-bottom: clamp(2rem, 4vw, 3rem); }

.wall {
  display: grid;
  gap: var(--gap);
  padding-block: 0.5rem;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.track {
  display: flex;
  gap: var(--gap);
  width: max-content;
  animation: drift 80s linear infinite;
  will-change: transform;
}
@keyframes drift { to { transform: translateX(-50%); } }

.shot {
  flex: 0 0 auto;
  width: clamp(260px, 30vw, 440px);
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}
.shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.shot { transition: border-color var(--fast) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .shot:hover { border-color: var(--line-hi); }
}


.link-arrow {
  display: inline-block;
  margin-top: 2rem;
  font-weight: 600;
  color: var(--muted);
  transition: color var(--fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .link-arrow:hover { color: var(--red); }
}

/* Reviews. No boxes: a card grid turns fifteen human voices into fifteen
   identical UI components. These run as editorial columns instead, each quote
   opened by a short red rule, with four set at pull-quote scale so the eye has
   somewhere to land and the wall reads as a page rather than a table. */

.say {
  display: block;
  margin: 0 0 clamp(2.25rem, 3.5vw, 3.25rem);
}
.say::before {
  content: '';
  display: block;
  width: 34px;
  height: 2px;
  margin-bottom: 1.1rem;
  background: var(--red);
}
.say p {
  font-size: 1.02rem;
  line-height: 1.6;
  color: #d9dbe0;
  text-wrap: pretty;
}
.say footer { margin-top: 0.9rem; }
.say cite {
  font-style: normal;
  font-weight: 700;
  font-size: 0.9rem;
  letter-spacing: 0.01em;
}

/* The feature quotes. Larger, brighter, and set tighter so they read as
   headlines rather than body copy. */
.say.lead p {
  font-size: clamp(1.3rem, 1.9vw, 1.7rem);
  line-height: 1.35;
  font-weight: 500;
  letter-spacing: -0.014em;
  color: var(--text);
}
.say.lead::before { width: 56px; height: 3px; }
.say.lead cite { font-size: 0.95rem; }

/* Stars are rhythm, not decoration, so they stay small and only the feature
   quotes get them at full strength. */
.say-stars {
  display: block;
  margin-bottom: 0.7rem;
  color: var(--red);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  opacity: 0.55;
}
.say.lead .say-stars { font-size: 0.85rem; opacity: 1; }

/* Reviews scroll on their own. Three columns run continuously at different
   speeds, the middle one against the other two, inside a fixed window with the
   top and bottom edges masked so quotes arrive and leave rather than popping.
   Each column holds its set twice, so translateY(-50%) returns to an identical
   frame and the loop has no seam. */
.says {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  height: clamp(520px, 62vh, 680px);
  margin-bottom: 3rem;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
}
.col {
  display: flex;
  flex-direction: column;
  animation: reel 70s linear infinite;
  will-change: transform;
}
.col[style*="--c:1"] { animation-duration: 88s; animation-direction: reverse; }
.col[style*="--c:2"] { animation-duration: 78s; }
@keyframes reel { to { transform: translateY(-50%); } }

/* Every screen gets the full wall: three columns, same reel, same mask.
   Small screens just tighten the gap and type so three columns stay readable. */
@media (max-width: 640px) {
  .says { gap: 0.9rem; height: clamp(400px, 56vh, 480px); }
  .say p { font-size: 0.8rem; line-height: 1.5; }
  .say.lead p { font-size: 0.92rem; line-height: 1.4; }
  .say::before { width: 24px; margin-bottom: 0.7rem; }
  .say.lead::before { width: 36px; }
  .say cite { font-size: 0.75rem; }
  .say-stars { font-size: 0.6rem; }
  .say.lead .say-stars { font-size: 0.68rem; }
}

/* Visit. The map runs edge to edge and the details sit on it, so the section
   reads as a place rather than a form beside a picture. The card is a solid
   panel, not glass, because address and hours have to stay legible over
   whatever the map happens to render underneath. */
.place {
  position: relative;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
  min-height: clamp(420px, 56vh, 580px);
  display: flex;
  align-items: center;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.place-map { position: absolute; inset: 0; overflow: hidden; }
.place-map iframe {
  width: 100%;
  height: 100%;
  border: 0;
  filter: grayscale(1) invert(0.92) contrast(0.82) brightness(1.04);
  pointer-events: none;
}

/* The embed's own pin is grey once the map is desaturated, so the shop is
   marked properly instead. The map is not pannable, which keeps this marker
   locked to the shop and stops the iframe swallowing scroll on a phone; the
   whole map is a link to real directions. */
.place-map-hit { position: absolute; inset: 0; z-index: 3; }

.pin {
  position: absolute;
  left: 50%;
  top: calc(50% - 16px);
  z-index: 2;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
  background: var(--red);
  border: 3px solid #fff;
  box-shadow: 0 0 0 1px rgba(224, 58, 61, 0.6), 0 10px 26px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}
/* One ring pushing outward, so the eye is drawn to it without the map moving. */
.pin::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
  border: 2px solid var(--red);
  animation: pin-pulse 2.6s var(--ease-out) infinite;
}
@keyframes pin-pulse {
  0%   { transform: scale(1);   opacity: 0.75; }
  70%  { transform: scale(3.4); opacity: 0; }
  100% { transform: scale(3.4); opacity: 0; }
}
@media (hover: hover) and (pointer: fine) {
  .place-map-hit:hover ~ .pin,
  .place-map:hover .pin { box-shadow: 0 0 0 1px rgba(224,58,61,.6), 0 14px 34px rgba(0,0,0,.7); }
}
/* Fades the map into the page on both edges so it does not end on a hard line. */
.place-map::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(90deg, var(--bg) 4%, rgba(11, 13, 17, 0.55) 42%, transparent 78%);
}

.place-card {
  position: relative;
  z-index: 4;
  width: min(420px, calc(100% - 2 * var(--pad)));
  margin-inline: max(var(--pad), calc((100% - var(--shell)) / 2 + var(--pad)));
  padding: clamp(1.75rem, 3vw, 2.5rem);
  display: grid;
  gap: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.55);
}

.place-address { font-style: normal; display: grid; gap: 0.2rem; }
.place-street {
  font-family: var(--display);
  font-size: clamp(2.1rem, 3.4vw, 3rem);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}
.place-city { color: var(--muted); }

.place-phone {
  font-family: var(--display);
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  line-height: 1;
  color: var(--red);
  letter-spacing: 0.01em;
  transition: opacity var(--fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) { .place-phone:hover { opacity: 0.75; } }

.hours { display: grid; gap: 0.6rem; font-size: 0.95rem; }
.hours li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--line);
}
.hours li:last-child { border-bottom: 0; padding-bottom: 0; }
.hours li span:first-child { color: var(--muted); }

.place-cta { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.place-cta .btn { flex: 1 1 auto; }

@media (max-width: 760px) {
  .place { min-height: 0; flex-direction: column; align-items: stretch; }
  .place-map { position: relative; height: 300px; }
  .pin { top: calc(45% - 16px); }
  .place-map::after { background: linear-gradient(180deg, transparent 55%, var(--bg)); }
  .place-card { width: auto; margin: -3.5rem var(--pad) var(--pad); }
}

/* ---------- Footer ---------- */

/* Instagram is the shop's live channel, so it gets a permanent home here
   rather than only a link inside the work section. */
.footer-social a {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: 0.4rem;
  padding: 0.55rem 1.1rem;
  border: 1px solid var(--line-hi);
  border-radius: 999px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  transition: color var(--fast) var(--ease-out), border-color var(--fast) var(--ease-out);
}
.footer-social a:active { transform: scale(0.97); }

.footer {
  border-top: 1px solid var(--line);
  padding-block: 3rem;
}
.footer-inner { display: grid; gap: 0.6rem; text-align: center; }
.footer-brand { font-family: var(--display); font-weight: 400;
  font-size: 1.15rem; }
.footer-meta { color: var(--muted); font-size: 0.9rem; }
.footer-meta a { color: var(--text); }
@media (hover: hover) and (pointer: fine) {
  .footer-meta a:hover { color: var(--red); }
  .footer-social a:hover { color: var(--red); border-color: var(--red); }
}

/* ---------- Mobile book bar ---------- */

.mobile-bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 60;
  display: none;
  gap: 0.6rem;
  padding: 0.75rem var(--pad) calc(0.75rem + env(safe-area-inset-bottom));
  background: rgba(11, 13, 17, 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--line);
  transform: translateY(110%);
  transition: transform 320ms var(--ease);
}
.mobile-bar.show { transform: none; }
.mobile-bar .btn { flex: 1; }

/* ---------- Responsive ---------- */

@media (max-width: 1000px) {
  .cols-5 { grid-template-columns: repeat(3, 1fr); }
  .visit-grid { grid-template-columns: 1fr; }
  .map-frame { min-height: 300px; }
}

@media (max-width: 760px) {
  .nav-links { display: none; }
  .cols-2, .cols-3 { grid-template-columns: 1fr; }
  .cols-5 { grid-template-columns: repeat(2, 1fr); }
  .mobile-bar { display: flex; }
  body { padding-bottom: 4.5rem; }
  /* Portrait screens: pull the frame toward the chair so it is not cropped out */
  .hero-media img { object-position: 72% center; }
  .hero-scrim {
    background:
      linear-gradient(180deg, rgba(11,13,17,0.72) 0%, rgba(11,13,17,0.55) 40%, rgba(11,13,17,0.86) 78%, var(--bg) 100%);
  }
}

@media (max-width: 420px) {
  .cols-5 { grid-template-columns: 1fr; }
}

/* ---------- Reduced motion ---------- */

/* Reduced motion keeps the opacity changes that aid comprehension and drops
   every movement, wipe, blur, and looping timer. */
@media (prefers-reduced-motion: reduce) {
  .rise, .card, .line {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .rail-item img, .btn, .nav, .card { transition: none; }
  .mobile-bar { transition: none; }
  .hero-media img { animation: none; transform: none; }
  .pin::after { animation: none; opacity: 0; }
  .track { animation: none; }
  .wall { overflow-x: auto; }
  .says { height: auto; overflow: visible; -webkit-mask-image: none; mask-image: none; }
  .col { animation: none; }
  .col .say[aria-hidden="true"] { display: none; }
  .frame.wipe { clip-path: none; transition: none; }
  .frame.wipe > img { transform: none; transition: none; }
}
