/* =========================================================================
   Esther's - home.css
   Homepage: hero, credibility strip, featured work gallery, image slots
   Uses the tokens defined in base.css; defines no new palette.
   ========================================================================= */

/* =====================================================================
   1. HERO
   Two columns on desktop: the pitch on the left, a real photograph on
   the right. The photo is the argument, so it gets equal weight.
   ===================================================================== */

.hero {
  position: relative;
  padding-block: clamp(56px, 8vw, 108px);
  overflow: hidden;
  display: block;
  min-height: 0;
}

.hero__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(32px, 5vw, 76px);
  align-items: center;
}
@media (max-width: 940px) {
  .hero__grid { grid-template-columns: 1fr; gap: 36px; }
}

.hero__copy { max-width: 54ch; }

/* The logo at full size, above the eyebrow. Width and height on the element
   reserve the box before the artwork arrives, so nothing below it moves. */
.hero__logo { margin: 0 0 clamp(20px, 2.4vw, 30px); }
.hero__logo img {
  display: block;
  width: min(30vw, 380px);
  height: auto;
}
@media (max-width: 940px) {
  .hero__logo img { width: min(78vw, 340px); }
}

/* The global display size is set for a full-width heading. In a half-width
   column it shatters into one word per line, so the hero steps it down. */
.hero .display {
  font-size: clamp(2.4rem, 4.3vw, 4rem);
  line-height: 1.06;
  margin-bottom: 24px;
  text-wrap: balance;
}
.hero .lede { max-width: 48ch; }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 32px;
}

/* Establishment line - small, factual, sits under the buttons */
.hero__since {
  margin-top: 26px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-faint);
  line-height: 1.8;
}

/* --- hero photograph --- */

.hero__figure {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  aspect-ratio: 4 / 5;
  max-height: 620px;
  box-shadow: 0 40px 90px -50px rgba(0, 0, 0, 1);
}
@media (max-width: 940px) { .hero__figure { aspect-ratio: 4 / 3; } }

.hero__figure img { width: 100%; height: 100%; object-fit: cover; }

/* Caption plate over the bottom of the hero photo */
.hero__figure-cap {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 44px 22px 20px;
  background: linear-gradient(180deg, transparent, rgba(6, 7, 8, 0.86));
  font-size: 12.6px;
  color: var(--ink-muted);
  line-height: 1.5;
}
.hero__figure-cap strong {
  display: block;
  color: var(--ink);
  font-weight: 400;
  font-size: 13.6px;
  margin-bottom: 3px;
}

/* =====================================================================
   2. CREDIBILITY STRIP
   Four verifiable facts. No stat is invented, so none of them are
   dressed up as a big number.
   ===================================================================== */

.creds {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(216px, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border-block: 1px solid var(--line-soft);
}

.cred {
  background: var(--bg);
  padding: 28px 26px 30px;
  transition: background var(--dur) var(--ease);
}
.cred:hover { background: var(--bg-panel); }

.cred__label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 13px;
  display: block;
}
.cred__value {
  font-family: var(--font-display);
  font-size: 1.16rem;
  font-weight: 400;
  letter-spacing: -0.018em;
  line-height: 1.28;
  margin-bottom: 9px;
  text-wrap: balance;
}
.cred__note { font-size: 12.6px; color: var(--ink-dim); line-height: 1.6; }

/* =====================================================================
   3. FEATURED WORK
   ===================================================================== */

/* Three across rather than one wide lead tile: the source photographs are
   between 700 and 1080px on the long edge, so a full-bleed tile would be
   upscaled and soft. At three columns every tile renders under its native
   resolution. */
/* Desktop: a plain grid, three across. Six projects fall as two tidy rows. */
.work-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2vw, 24px);
}

/* Tablet and phone: one swipeable row instead of a tall column.

   Six cards stacked is a long scroll past the same thing six times, and a
   visitor on a phone gives up before they reach the bottom. Sideways, the
   whole gallery is a couple of flicks and the sections below it stay
   within reach.

   Deliberately CSS and nothing else - the browser's own scrolling is
   smoother than any script, keeps momentum on iOS, and cannot break.

   The card widths below are chosen so the next one is always partly
   visible. That sliver is the entire affordance: it is what tells a
   visitor there is more without a caption saying "swipe". */
@media (max-width: 999px) {
  .work-grid {
    display: flex;
    grid-template-columns: none;
    overflow-x: auto;
    /* Contains the sideways scroll to this row. The page itself never
       scrolls horizontally - checked at every width. */
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    /* Room for the card's own hover lift and shadow, so neither is clipped
       by the scroll box. */
    padding-block: 4px;
  }

  .work-grid > .work {
    flex: 0 0 min(78vw, 320px);
    scroll-snap-align: start;
  }

  /* Two and a bit at tablet width. */
  @media (min-width: 640px) {
    .work-grid > .work { flex-basis: min(44vw, 340px); }
  }

  /* A thin, quiet scrollbar. Hiding it is tempting and wrong: on a desktop
     browser at a narrow window it is the only thing that says this row
     moves, and some people scroll by dragging it. */
  .work-grid { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
  .work-grid::-webkit-scrollbar { height: 6px; }
  .work-grid::-webkit-scrollbar-track { background: transparent; }
  .work-grid::-webkit-scrollbar-thumb {
    background: var(--line-strong);
    border-radius: 999px;
  }

  /* Keyboard focus on the scroll box itself. app.js gives it tabindex only
     when it actually overflows, so there is no dead tab stop otherwise. */
  .work-grid:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
    border-radius: var(--radius);
  }
}

/* Arrow keys and any future scrollIntoView glide rather than jump - unless
   the visitor has asked for less movement. */
@media (max-width: 999px) and (prefers-reduced-motion: no-preference) {
  .work-grid { scroll-behavior: smooth; }
}

.work {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--bg-panel);
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease-out);
}
.work:hover { border-color: var(--line-strong); transform: translateY(-3px); }

/* Square frames: the three photographs are landscape, portrait and square,
   and a 1:1 crop treats all of them evenly instead of gutting one. */
.work__frame {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--bg-raised);
}
@media (max-width: 639px) { .work__frame { aspect-ratio: 4 / 3; } }

.work__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.work:hover .work__frame img { transform: scale(1.03); }

.work figcaption {
  padding: 18px 20px 22px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
}
.work__title { font-size: 14.6px; letter-spacing: -0.005em; }
.work__meta {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* =====================================================================
   4. IMAGE SLOTS
   Every photograph on the page degrades to a labelled plate when the
   file is missing, so the layout holds before the photos are added and
   nobody ever sees a broken-image icon.
   ===================================================================== */

.slot { position: relative; }

.slot__ph {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 24px;
  text-align: center;
  background:
    repeating-linear-gradient(
      -45deg,
      rgba(255, 255, 255, 0.017) 0px,
      rgba(255, 255, 255, 0.017) 10px,
      transparent 10px,
      transparent 20px),
    var(--bg-raised);
}
/* JS sets data-missing once the image fails to load */
.slot[data-missing="true"] img { visibility: hidden; }
.slot[data-missing="true"] .slot__ph { display: flex; }

.slot__ph-icon {
  width: 30px; height: 30px;
  color: var(--ink-faint);
}
.slot__ph-label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
  line-height: 1.7;
}
.slot__ph-file {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--accent);
  word-break: break-all;
}

/* =====================================================================
   5. PROCESS
   Genuinely sequential, so it is numbered.
   ===================================================================== */

.process {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(238px, 1fr));
  gap: clamp(18px, 2.4vw, 30px);
  counter-reset: step;
}

.step {
  position: relative;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}
.step__num {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  display: block;
  margin-bottom: 14px;
}
.step__title { font-size: 1.06rem; margin-bottom: 10px; letter-spacing: -0.015em; }
.step__body { font-size: 13.2px; color: var(--ink-dim); line-height: 1.66; }

/* =====================================================================
   6. CONTACT - VISIT OUR SHOPS
   Two location cards. No new palette: the cards are the same raised
   surface, hairline and radius the work tiles use, and the only accent
   is the one already cascading from the material selector.
   ===================================================================== */

.loc-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(18px, 2.2vw, 26px);
}
@media (min-width: 900px) { .loc-grid { grid-template-columns: repeat(2, 1fr); } }

.loc {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: clamp(22px, 2.4vw, 32px);
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background: var(--bg-panel);
  transition: border-color var(--dur) var(--ease);
}
.loc:hover { border-color: var(--line-strong); }

/* The main branch is marked, not shouted about: one hairline of accent
   along the top edge, and a small label in the badge row. */
.loc--primary {
  position: relative;
  background: linear-gradient(180deg, var(--bg-elevated), var(--bg-panel) 42%);
}
.loc--primary::before {
  content: "";
  position: absolute;
  top: -1px; left: clamp(22px, 2.4vw, 32px); right: clamp(22px, 2.4vw, 32px);
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}

.loc__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; }

.loc__primary {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  padding: 4px 10px 3px;
  line-height: 1;
}

.loc__name {
  font-size: clamp(1.3rem, 1.9vw, 1.6rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.loc__address {
  font-style: normal;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-muted);
}

.loc__rows { display: flex; flex-direction: column; gap: 18px; }

/* Label column on the left at desktop width, stacked on a phone. */
.loc__row { display: grid; gap: 4px 18px; }
@media (min-width: 480px) { .loc__row { grid-template-columns: 96px minmax(0, 1fr); } }

.loc__row-label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding-top: 4px;
}

/* Phone and email stay as text so they can be read and copied, and are
   underlined on hover rather than dressed up as buttons. */
.loc__link {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line-strong);
  padding-bottom: 1px;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  overflow-wrap: anywhere;
}
.loc__link:hover { color: var(--accent); border-color: var(--accent-line); }
.loc__link--phone {
  font-size: 1.12rem;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
}

.loc__people { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.loc__person { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.loc__person-name { font-size: 14.5px; color: var(--ink); }
.loc__person .loc__link { font-size: 13.5px; color: var(--ink-muted); }
.loc__person .loc__link:hover { color: var(--accent); }

.loc__spec { margin: 0; font-size: 13.8px; line-height: 1.62; color: var(--ink-dim); }

.loc__cta { align-self: flex-start; }
.loc__cta svg { width: 16px; height: 16px; }

/* --- the map ---
   Held to a strip so it supports the address rather than taking the
   section over. The frame is desaturated and stepped down a little so a
   bright map does not punch a hole in a dark page - light enough that the
   Google attribution inside it stays legible. */
.loc__map {
  position: relative;
  margin-top: auto;
  aspect-ratio: 16 / 7;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--bg-raised);
}
.loc__map iframe {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  /* Desaturated and stepped down so a bright map does not punch a hole in a
     dark page - light enough that the Google attribution stays legible. */
  filter: grayscale(0.34) brightness(0.9) contrast(1.02);
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.loc__map iframe.is-ready { opacity: 1; }

/* Sits under the frame, so a blocked or slow map shows the address on the
   page's own surface instead of a white rectangle. */
.loc__map-fallback {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 20px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.8;
  color: var(--ink-faint);
  background:
    repeating-linear-gradient(-45deg,
      rgba(255, 255, 255, 0.017) 0px, rgba(255, 255, 255, 0.017) 10px,
      transparent 10px, transparent 20px),
    var(--bg-raised);
}

.loc__map-fallback svg { width: 22px; height: 22px; color: var(--ink-faint); }

/* A quiet line between the intro and the cards, not a third card. Sits on the
   page ground with no box and no border, at the size the footer small print
   uses, so it reads as a helpful aside rather than another thing to act on.

   The spacing does the work of saying which half it belongs to: it sits close
   under the intro, as a continuation of it, and further from the cards, so it
   never reads as a caption on the first card. That is why the section head's
   own bottom margin is pulled in here - the full 36-64px would have cast the
   line adrift between the two. */
#contact .section-head { margin-bottom: clamp(16px, 1.9vw, 22px); }

.loc-help {
  margin: 0 0 clamp(30px, 3.6vw, 44px);
  max-width: 62ch;
  font-size: 14px;
  line-height: 1.66;
  color: var(--ink-dim);
  /* Keeps the last line from ending up a single orphaned word. */
  text-wrap: pretty;
}
/* With no note to sit under, the head keeps its normal distance. */
#contact .section-head:has(+ .loc-help[hidden]) { margin-bottom: clamp(36px, 5vw, 64px); }
.loc-help__phone {
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.loc-help__phone:hover { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .loc { transition: none; }
}

/* =====================================================================
   7. RESPONSIVE
   ===================================================================== */

@media (max-width: 620px) {
  .hero__actions .btn { width: 100%; justify-content: center; }
  .work figcaption { padding: 15px 16px 18px; }
}
