/* Interior pages: projects, services, about, contact.
   Loaded after components.css and pages/home.css. */

/* ══ Page hero ═════════════════════════════════════════════════════════
   Deliberately typographic rather than a second photo hero — the homepage
   hero is the site's one big moment, and repeating it everywhere flattens it. */

.page-hero {
  padding-block: var(--space-12) var(--space-13);
  border-bottom: var(--hairline) solid var(--rule-on-ink);
}

.page-hero__eyebrow { color: var(--label-on-ink); }

.page-hero__title {
  margin-top: var(--space-5);
  font-size: var(--size-display-l);
  max-width: 18ch;
}

.page-hero__lede {
  margin-top: var(--space-6);
  font-size: var(--size-body-l);
  line-height: 1.5;
  max-width: 54ch;
  color: var(--ink-300);
}

/* ══ Service header photo ══════════════════════════════════════════════
   A band BELOW the opener, never behind it. .page-hero above is deliberately
   typographic, so the client's header photo gets its own full-bleed strip
   rather than overturning that decision.

   Services carry no width/height columns, so the ratio is fixed here and the
   markup's width/height match it: the space is reserved before the photograph
   arrives, and object-fit crops whatever was uploaded. Deeper on a phone,
   where 16:7 is a letterbox slit and the photograph is the entire point. */

.service-hero__media {
  display: block;
  aspect-ratio: 16 / 7;
  overflow: hidden;
  background: var(--ink-200);
}

.service-hero__media picture {
  display: block;
  height: 100%;
}

.service-hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 768px) {
  .service-hero__media { aspect-ratio: 3 / 2; }
}

/* ══ Service area ══════════════════════════════════════════════════════
   Moved to components.css. The band renders on the home page as well, and
   home.blade.php does not load this file — so every rule here was unreachable
   there and nineteen villages rendered as a default bulleted list. Exactly the
   stranding that put the testimonial stars in the wrong stylesheet. */

/* ══ Breadcrumbs ═══════════════════════════════════════════════════════ */

.crumbs { margin-bottom: var(--space-8); }

.crumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--size-eyebrow);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.crumbs li + li::before {
  content: "/";
  margin-right: var(--space-2);
  color: var(--ink-500);
}

.crumbs a { color: var(--ink-400); text-decoration: none; }
.crumbs a:hover { color: var(--ocean-300); text-decoration: underline; }
.crumbs [aria-current="page"] { color: var(--paper); }

/* ══ Project list ══════════════════════════════════════════════════════ */

.project-list {
  display: grid;
  gap: var(--space-11);
  margin-top: var(--space-9);
}

/* A grid item defaults to min-width: auto, so a child that establishes a wide
   min-content size pushes the 1.25fr track past its declared size. The media
   was a plain <img> until a comparison slider could sit there; layout.css:122
   and the rooms grid below already carry this for the same reason. */
.project-list > * { min-width: 0; }

.project-card {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: var(--space-9);
  align-items: start;
}

.project-card:nth-child(even) { direction: rtl; }
.project-card:nth-child(even) > * { direction: ltr; }

.project-card__media {
  display: block;
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--ink-200);
}

.project-card__media picture { position: absolute; inset: 0; display: block; }

.project-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms var(--ease);
}

.project-card__media:hover .project-card__img { transform: scale(1.03); }

@media (prefers-reduced-motion: reduce) {
  .project-card__media:hover .project-card__img { transform: none; }
}

/* The comparison variant. .compare brings its own ratio, its own overflow and
   its own ink ground, so the wrapper stops imposing them — otherwise the two
   4/3 boxes nest and the inner one is cropped by the outer.

   The explicit width is the trap documented in docs/responsive.md:162-175, not
   defensive noise: .compare carries aspect-ratio, and in a grid track whose
   cross size is definite the browser derives its WIDTH from that height and
   overhangs the column. That put the slider 103px over its 587px track on the
   homepage and hid the panel text behind it. home.css:111 and .work__room
   below carry the same line for the same reason. */
.project-card__media--compare {
  aspect-ratio: auto;
  overflow: visible;
  background: none;
}

.project-card .compare { width: 100%; }

.project-card__body { padding-top: var(--space-2); }

.project-card__title { margin-top: var(--space-4); font-size: var(--size-heading); }
.project-card__title a { color: inherit; text-decoration: none; }
.project-card__title a:hover { color: var(--brand-text); }

.project-card__excerpt {
  margin-top: var(--space-4);
  line-height: 1.6;
  color: var(--muted);
  max-width: 48ch;
}

.project-card__sheet { margin-top: var(--space-7); }

.project-card__more {
  margin-top: var(--space-6);
  font-weight: 700;
}

/* ══ Project detail ════════════════════════════════════════════════════ */

.work__service {
  margin-top: var(--space-7);
  font-size: var(--size-data);
  color: var(--muted-on-ink);
}

.work__service a { color: var(--ocean-300); }

.project-nav__inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--hairline);
  background: var(--rule);
  border-block: var(--hairline) solid var(--rule);
}

.project-nav__link {
  background: var(--concrete);
  padding: var(--space-7) var(--space-6);
  color: inherit;
  text-decoration: none;
  display: block;
  transition: background var(--duration) var(--ease);
}

.project-nav__link:hover { background: var(--paper); text-decoration: none; }
.project-nav__link--next { text-align: right; }

.project-nav__title {
  display: block;
  margin-top: var(--space-3);
  font-size: var(--size-subhead);
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* ══ Services ══════════════════════════════════════════════════════════ */

.services__list { margin-top: var(--space-9); }

.service-cell { min-height: 220px; }
.service-cell__title { font-size: var(--size-heading); }

.service-cell__more {
  margin-top: auto;
  padding-top: var(--space-6);
  font-weight: 700;
  color: var(--brand-text);
}

.service-detail { gap: var(--space-11); margin-top: var(--space-4); }

.service-detail__body { margin-top: var(--space-7); max-width: 58ch; }

.service-detail__included {
  border-top: 2px solid var(--ink);
  padding-top: var(--space-6);
}

.tick-list {
  list-style: none;
  margin-top: var(--space-5);
  display: grid;
  gap: var(--space-3);
}

.tick-list li {
  position: relative;
  padding-left: var(--space-6);
  line-height: 1.5;
}

/* A rule, not a checkmark glyph: the system has no icon set, and a border is
   sharper at every zoom level than a font character. */
.tick-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 12px;
  height: 2px;
  background: var(--brand);
}

/* ══ About ═════════════════════════════════════════════════════════════ */

.owner--about { margin-top: 0; }

.about-projects { margin-top: var(--space-8); }

/* ══ Contact ═══════════════════════════════════════════════════════════ */

.contact-sheet { margin-top: var(--space-9); }

.contact-note { margin-top: var(--space-7); max-width: 40ch; line-height: 1.6; }

.form-alert {
  padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-7);
  border-left: 3px solid var(--danger);
  background: color-mix(in srgb, var(--danger) 14%, transparent);
}

.form-alert__title { font-weight: 700; }

.form-alert ul {
  list-style: none;
  margin-top: var(--space-2);
  display: grid;
  gap: var(--space-1);
  font-size: 15px;
  color: var(--ink-200);
}

/* ══ Closing CTA ═══════════════════════════════════════════════════════ */

.cta__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-9);
  padding: var(--space-11) var(--space-10);
}

.cta__title { margin-top: var(--space-4); font-size: var(--size-display-m); max-width: 16ch; }

.cta__lede {
  margin-top: var(--space-5);
  max-width: 44ch;
  line-height: 1.6;
  color: var(--ink-300);
}

.cta__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* ══ Thank you ═════════════════════════════════════════════════════════ */

.thanks__inner { padding: var(--space-13) var(--space-10); }

.thanks__title { margin-top: var(--space-5); font-size: var(--size-display-m); max-width: 22ch; }

.thanks__lede {
  margin-top: var(--space-6);
  font-size: var(--size-body-l);
  max-width: 46ch;
  color: var(--ink-300);
}

.thanks__next {
  margin-top: var(--space-10);
  padding-top: var(--space-7);
  border-top: var(--hairline) solid var(--rule-on-ink);
}

.thanks__body { margin-top: var(--space-4); max-width: 52ch; line-height: 1.6; color: var(--ink-300); }

.thanks__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-9); }

/* ══ Footer nav ════════════════════════════════════════════════════════ */

.site-footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  font-size: 15px;
}

/* ══ Responsive ════════════════════════════════════════════════════════ */

@media (max-width: 1024px) {
  .project-card { grid-template-columns: 1fr; gap: var(--space-6); }
  .project-card:nth-child(even) { direction: ltr; }
  .service-detail { gap: var(--space-8); }
  .cta__inner { padding: var(--space-10) var(--space-7); }
  .thanks__inner { padding: var(--space-11) var(--space-7); }
}

@media (max-width: 768px) {
  .page-hero { padding-block: var(--space-9) var(--space-11); }
  .project-nav__inner { grid-template-columns: 1fr; }
  .project-nav__link--next { text-align: left; }
}

/* ══ FAQs ══════════════════════════════════════════════════════════════
   Native <details>. No JavaScript, keyboard accessible and screen-reader
   announced for free, and it still works if a script fails to load. */

.faq-list { margin-top: var(--space-8); border-top: 2px solid var(--ink); }

.faq { border-bottom: var(--hairline) solid var(--rule); }

.faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-6) 0;
  font-size: var(--size-subhead);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.3;
  cursor: pointer;
  list-style: none;
}

/* Safari draws its own triangle; ours is the +/− below. */
.faq__q::-webkit-details-marker { display: none; }

.faq__q:hover { color: var(--brand-text); }
.faq__q:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }

.faq__marker {
  position: relative;
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 4px;
}

.faq__marker::before,
.faq__marker::after {
  content: "";
  position: absolute;
  background: var(--brand);
  transition: transform var(--duration) var(--ease);
}

.faq__marker::before { inset: 9px 0 9px 0; height: 2px; }
.faq__marker::after { inset: 0 9px 0 9px; width: 2px; }

.faq[open] .faq__marker::after { transform: scaleY(0); }

@media (prefers-reduced-motion: reduce) {
  .faq__marker::before,
  .faq__marker::after { transition: none; }
}

.faq__a { margin: 0 0 var(--space-7); max-width: 68ch; font-size: 16px; }
.faq__a > *:first-child { margin-top: 0; }

@media (pointer: coarse) {
  .faq__q { padding-block: var(--space-5); min-height: 44px; }
}

/* ══ Testimonials ══════════════════════════════════════════════════════
   The rating and project-link rules moved to components.css. They were
   stranded here: the testimonial partial is shared with the homepage, which
   loads home.css but not this file, so the "off" stars inherited the "on"
   colour and a three-star review rendered as five. A shared component's
   styles belong in the shared stylesheet. */

/* ══ Project detail — rooms, gallery, quote ════════════════════════════
   A whole-home job carries one comparison per room. The lead pair sits in
   the split frame with the job sheet; the rest live here. */

.work__compare { margin: 0; }

.work__compare-cap {
  padding: var(--space-3) var(--space-5);
  background: var(--ink);
  color: var(--muted-on-ink);
  font-family: var(--font-mono);
  font-size: var(--size-eyebrow);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}

.work__rooms-grid {
  margin-top: var(--space-8);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6);
}

/* Grid items default to min-width:auto, so a wide child can push a track past
   its declared size. See docs/responsive.md. */
.work__rooms-grid > * { min-width: 0; }

.work__room { margin: 0; border: var(--hairline) solid var(--ink); }
.work__room .compare { width: 100%; }

.gallery__link {
  display: block;
  text-decoration: none;
  /* The frame is the hit area; the link must not add its own inline box. */
  line-height: 0;
}

.gallery__link:focus-visible {
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: 3px;
}

.work__quote {
  padding: var(--space-10) var(--space-9);
  margin: 0;
  border: var(--hairline) solid var(--ink);
}

.work__quote blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--size-h3);
  line-height: 1.3;
  text-wrap: balance;
}

.work__quote figcaption {
  margin-top: var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--size-eyebrow);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--muted-on-ink);
}

@media (max-width: 768px) {
  .work__rooms-grid { grid-template-columns: 1fr; }
  .work__quote { padding: var(--space-8) var(--space-6); }
}

/* ══ Lightbox ══════════════════════════════════════════════════════════
   A native <dialog>: Escape, the focus trap and focus return are the
   platform's job, not ours. Built by assets/js/lightbox.js only when a
   visitor actually opens a photo. */

.lightbox {
  width: min(96vw, 1400px);
  max-width: none;
  max-height: 94vh;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;

  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-4);
}

.lightbox::backdrop { background: rgb(0 0 0 / 0.88); }

.lightbox__figure {
  grid-column: 2;
  margin: 0;
  min-width: 0;
  text-align: center;
}

.lightbox__img {
  max-width: 100%;
  max-height: 80vh;
  width: auto;
  height: auto;
  object-fit: contain;
}

.lightbox__cap,
.lightbox__count {
  margin-top: var(--space-4);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--size-eyebrow);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}

.lightbox__count { grid-column: 2; margin-top: 0; opacity: 0.65; }

.lightbox__nav,
.lightbox__close {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border: var(--hairline) solid rgb(255 255 255 / 0.4);
  background: transparent;
  color: var(--paper);
  font-size: 20px;
  cursor: pointer;
}

.lightbox__nav:hover,
.lightbox__close:hover { background: rgb(255 255 255 / 0.14); }

.lightbox__nav:focus-visible,
.lightbox__close:focus-visible {
  outline: var(--focus-width) solid var(--paper);
  outline-offset: 2px;
}

.lightbox__nav--prev { grid-column: 1; }
.lightbox__nav--next { grid-column: 3; }

.lightbox__close {
  position: absolute;
  top: calc(var(--space-4) * -1 - 48px);
  right: 0;
}

/* On a phone the side arrows would eat the photo. Put the controls under it. */
@media (max-width: 768px) {
  .lightbox {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
  }

  .lightbox__figure { grid-column: 1 / -1; }
  .lightbox__count { grid-column: 1 / -1; }
  .lightbox__nav--prev { grid-column: 1; }
  .lightbox__nav--next { grid-column: 2; }
  .lightbox__nav { width: 100%; height: 44px; }
  .lightbox__close { top: calc(var(--space-3) * -1 - 44px); width: 44px; height: 44px; }
}
