/* Components — buttons, nav, footer, chips, cards. Tokens only, never raw values. */

/* =========================================================================
   Buttons — the entire conversion path. Large, obvious, thumb-friendly.
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  min-height: 3.25rem;         /* well above the 44px floor */
  padding-inline: var(--space-lg);
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-base);
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background-color var(--dur-short) var(--ease-out),
              border-color var(--dur-short) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--color-accent);
  color: var(--color-accent-ink);
}

.btn--primary:hover {
  background: var(--color-focus);
}

.btn--outline {
  background: transparent;
  color: var(--color-ink);
  border-color: var(--color-rule);
}

.btn--outline:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.btn--block {
  width: 100%;
}

.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

@media (max-width: 26rem) {
  /* Approved CTA copy runs long ("Text us a photo of your wall", "Text a
     photo — get your mockup") and can't be shortened — give it a smaller
     size and tighter padding so the one-line affordance still fits at
     320–413px (gate 49: never two lines, never truncated). */
  .btn {
    font-size: var(--text-sm);
    padding-inline: var(--space-sm);
  }
}

/* Typographic link CTA — underline only, no box */
.link-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--color-ink);
  border-bottom: 1px solid var(--color-rule);
  padding-block-end: var(--space-3xs);
  white-space: nowrap;
  transition: border-color var(--dur-short) var(--ease-out),
              color var(--dur-short) var(--ease-out);
}

.link-cta:hover {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* Small inline call-affordance (tel:) beneath the primary sms buttons */
.tel-line {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.tel-line a {
  color: var(--color-ink-2);
  border-bottom: 1px solid var(--color-rule-2);
  white-space: nowrap;
}

.tel-line a:hover {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* =========================================================================
   Nav — edge-aligned wordmark and CTA with a quiet centre link row. From 60rem
   up the row sits inline; below that the same <ul> becomes a full-height panel
   under the bar, opened by .nav__toggle. One list, two presentations — there is
   no duplicate set of mobile links to keep in sync.
   ========================================================================= */

.nav {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  padding-block: var(--space-md);
  background: var(--color-nav-bg);
  border-bottom: 1px solid transparent;
  backdrop-filter: blur(10px);
  transition: background-color var(--dur-short) var(--ease-out),
              border-color var(--dur-short) var(--ease-out);
}

.nav__end {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

/* Mobile: the link row becomes a panel under the bar. visibility (not display)
   keeps it out of the tab order while closed but still transitionable.
   Positioned absolute, not fixed: .nav carries a backdrop-filter, which makes
   it the containing block for fixed descendants too, so `inset: var(--nav-height) 0 0 0`
   would resolve against the 4.75rem bar and collapse the panel to nothing.
   Anchoring to the bar and bleeding out to 100vw sidesteps that entirely. */
.nav__links {
  position: absolute;
  top: 100%;
  left: 50%;
  width: 100vw;
  height: calc(100dvh - var(--nav-height));
  z-index: var(--z-dropdown);
  display: flex;
  flex-direction: column;
  padding: var(--space-sm) var(--container-pad) var(--space-2xl);
  background: var(--color-paper-2);
  border-top: 1px solid var(--color-rule-2);
  overflow-y: auto;
  overscroll-behavior: contain;
  visibility: hidden;
  opacity: 0;
  transform: translateX(-50%) translateY(-0.5rem);
  transition: opacity var(--dur-short) var(--ease-out),
              transform var(--dur-short) var(--ease-out),
              visibility 0s linear var(--dur-short);
}

.nav__links.is-open {
  visibility: visible;
  opacity: 1;
  transform: translateX(-50%);
  transition-delay: 0s;
}

/* Stops the page scrolling behind the open panel or the lightbox. */
body.has-nav-open,
body.has-lightbox-open {
  overflow: hidden;
}

.nav__links a {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
  padding-block: var(--space-md);
  border-bottom: 1px solid var(--color-rule-2);
}

.nav__links li:last-child a {
  border-bottom: none;
}

/* Hamburger. Three bars, echoing the three slats in the wordmark's favicon;
   they collapse into an X while the panel is open. */
.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  margin-inline-end: -0.5rem; /* optical: pulls the bars flush with the container edge */
  color: var(--color-ink);
}

.nav__toggle-bars,
.nav__toggle-bars::before,
.nav__toggle-bars::after {
  width: 1.375rem;
  height: 2px;
  background: currentColor;
  transition: transform var(--dur-short) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}

.nav__toggle-bars {
  position: relative;
  display: block;
}

.nav__toggle-bars::before,
.nav__toggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
}

.nav__toggle-bars::before { top: -0.4375rem; }
.nav__toggle-bars::after  { top: 0.4375rem; }

.nav__toggle[aria-expanded="true"] .nav__toggle-bars {
  background: transparent;
}

.nav__toggle[aria-expanded="true"] .nav__toggle-bars::before {
  transform: translateY(0.4375rem) rotate(45deg);
}

.nav__toggle[aria-expanded="true"] .nav__toggle-bars::after {
  transform: translateY(-0.4375rem) rotate(-45deg);
}

@media (min-width: 60rem) {
  .nav__toggle {
    display: none;
  }

  /* Back to an inline row — every mobile-panel property has to be undone. */
  .nav__links {
    position: static;
    width: auto;
    height: auto;
    z-index: auto;
    flex-direction: row;
    align-items: center;
    gap: var(--space-xl);
    margin-inline: auto;
    padding: 0;
    background: none;
    border-top: none;
    overflow: visible;
    visibility: visible;
    opacity: 1;
    transform: none;
  }

  .nav__links a {
    font-size: var(--text-sm);
    letter-spacing: 0.03em;
    color: var(--color-ink-2);
    padding-block: var(--space-2xs);
    border-bottom: 1px solid transparent;
    transition: color var(--dur-short) var(--ease-out),
                border-color var(--dur-short) var(--ease-out);
  }

  .nav__links a:hover {
    color: var(--color-ink);
    border-bottom-color: var(--color-accent);
  }
}

.nav.is-scrolled {
  background: var(--color-paper-3);
  border-bottom-color: var(--color-rule-2);
}

.nav__wordmark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-lg);
  letter-spacing: var(--tracking-tight);
  color: var(--color-ink);
}

.nav__wordmark span {
  color: var(--color-accent);
}

.nav__cta {
  min-height: 2.75rem;
  padding-inline: var(--space-md);
  font-size: var(--text-sm);
}

/* =========================================================================
   Footer — Ft2 Inline rule, single line. Hairline above, no columns.
   ========================================================================= */

.footer {
  border-top: 1px solid var(--color-rule-2);
  padding-block: var(--space-2xl);
  padding-block-end: max(var(--space-2xl), env(safe-area-inset-bottom));
}

.footer__line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-lg);
  color: var(--color-muted);
  font-size: var(--text-sm);
}

.footer__line strong {
  color: var(--color-ink-2);
  font-weight: 700;
}

.footer__line a {
  color: var(--color-ink-2);
  border-bottom: 1px solid var(--color-rule-2);
}

.footer__line a:hover {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* Keeps a label and its number on the same line — the line may break between
   segments, never inside one. Each separator lives inside the item that
   follows it, so a dot can never be left dangling at the end of a line. */
.footer__item {
  white-space: nowrap;
}

.footer__sep {
  color: var(--color-rule);
}

/* The finish chips lived here — a typographic list of names with no images.
   Removed along with their markup: the photographed swatches carry their own
   names now, so the chips were the same information twice. */

/* =========================================================================
   Material comparison cards
   ========================================================================= */

.material-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-rule-2);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-paper-2);
}

/* Each card carries one real install photo that evidences its own claim —
   the WPC card a bathroom, the natural-wood card a raking-light grain shot. */
.material-card__media {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-bottom: 1px solid var(--color-rule-2);
}

.material-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 55%;
}

.material-card__body {
  padding: var(--space-xl) var(--space-lg);
}

.material-card h3 {
  font-size: var(--text-xl);
  margin-block-end: var(--space-lg);
}

.material-card ul {
  display: grid;
  gap: var(--space-sm);
}

.material-card li {
  position: relative;
  padding-inline-start: var(--space-lg);
  color: var(--color-ink-2);
  line-height: var(--lh-snug);
}

.material-card li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  background: var(--color-accent);
}

/* =========================================================================
   Step sequence — F4, numbered vertical stages.
   ========================================================================= */

.steps {
  display: grid;
  gap: var(--space-xl);
}

.step {
  display: grid;
  grid-template-columns: minmax(0, 3rem) minmax(0, 1fr);
  gap: var(--space-lg);
  align-items: start;
}

.step__num {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-xl);
  color: var(--color-accent);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.step h3 {
  font-size: var(--text-md);
  margin-block-end: var(--space-2xs);
}

.step p {
  color: var(--color-ink-2);
}

/* =========================================================================
   Gallery figure
   ========================================================================= */

.gallery__figure {
  position: relative;
  overflow: hidden;
  background: var(--color-paper-2);
}

/* The button is the tile. It carries no styling of its own beyond filling the
   figure — the photo stays the whole affordance. */
.gallery__btn {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  cursor: zoom-in;
}

.gallery__figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-long) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .gallery__figure:hover img {
    transform: scale(1.035);
  }
}

/* =========================================================================
   Lightbox — opened from a gallery tile. The open/close motion is a FLIP in
   js/main.js: the full image is laid out at its final size, then inverted
   back onto the tile's rect and animated to identity, so the photo appears to
   grow out of the tile it was clicked from rather than cross-fading in.
   ========================================================================= */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  padding: var(--space-xl) var(--space-md);
  background: var(--color-scrim-strong);
  backdrop-filter: blur(14px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-short) var(--ease-out),
              visibility 0s linear var(--dur-short);
}

.lightbox.is-open {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.lightbox__figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  max-width: 100%;
  max-height: 100%;
  margin: 0;
}

.lightbox__img {
  display: block;
  max-width: min(92vw, 76rem);
  max-height: 78vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--radius-md);
  transform-origin: top left;   /* the FLIP inverse is computed against this */
}

.lightbox__caption {
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-ink-2);
  text-align: center;
}

.lightbox__count {
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

.lightbox__btn {
  position: absolute;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--color-paper-3);
  color: var(--color-ink);
  transition: background-color var(--dur-short) var(--ease-out),
              transform var(--dur-short) var(--ease-spring);
}

.lightbox__btn:hover {
  background: var(--color-accent);
  color: var(--color-accent-ink);
  transform: scale(1.08);
}

.lightbox__btn svg {
  width: 1.375rem;
  height: 1.375rem;
}

.lightbox__close { top: var(--space-md); right: var(--space-md); }
.lightbox__prev  { left: var(--space-md);  top: 50%; margin-top: -1.5rem; }
.lightbox__next  { right: var(--space-md); top: 50%; margin-top: -1.5rem; }

@media (max-width: 40rem) {
  /* Side arrows would sit on top of the photo on a phone; drop them under it
     where the thumb already is. Swipe is not a substitute — the range of
     motion overlaps the browser's own back gesture. */
  .lightbox__prev { left: calc(50% - 4rem); top: auto; bottom: var(--space-md); margin-top: 0; }
  .lightbox__next { right: calc(50% - 4rem); top: auto; bottom: var(--space-md); margin-top: 0; }
  .lightbox__img  { max-height: 62vh; }
}

.gallery__caption {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  padding: var(--space-md) var(--space-md) var(--space-sm);
  background: linear-gradient(180deg, transparent 0%, var(--color-overlay-scrim) 70%);
  color: var(--color-ink);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: var(--lh-snug);
}

@media (max-width: 40rem) {
  /* Two tiles across a phone leaves ~180px per caption — step down so the
     longer install names stay to two lines instead of four. */
  .gallery__caption {
    padding: var(--space-sm) var(--space-xs) var(--space-xs);
    font-size: var(--text-xs);
  }
}

/* =========================================================================
   Trust items — three plain statements under the fold. Every line is a claim
   already made in the process section; nothing here is a metric or a rating.
   ========================================================================= */

.trust__item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-sm);
  letter-spacing: 0.02em;
  color: var(--color-ink-2);
  line-height: var(--lh-snug);
}

.trust__icon {
  flex: none;
  width: 1.375rem;
  height: 1.375rem;
  color: var(--color-accent);
}

/* =========================================================================
   Benefit cards — icon over one verbatim sentence.
   ========================================================================= */

.benefit {
  display: grid;
  gap: var(--space-md);
  align-content: start;
  padding: var(--space-lg);
  border: 1px solid var(--color-rule-2);
  border-radius: var(--radius-md);
  background: var(--color-paper);
}

.benefit__icon {
  width: 1.75rem;
  height: 1.75rem;
  color: var(--color-accent);
}

.benefit p {
  color: var(--color-ink-2);
  line-height: var(--lh-snug);
}
