/* ============================================================
   Site enhancements: motion tokens, scroll-reveal animations,
   and sticky-header polish.
   ============================================================ */

/* ---------- motion tokens (shared by style.css) ---------- */
:root {
  --ease: cubic-bezier(.33, 1, .68, 1);
  --dur-1: .18s;
  --dur-2: .25s;
  --dur-3: .4s;
}
@keyframes fade-in { from { opacity: 0; } }
@keyframes drop-in { from { opacity: 0; transform: translateY(-8px); } }
@keyframes rise-in { from { opacity: 0; transform: translateY(10px); } }

/* ---------- reveal + sticky header ---------- */

.reveal { opacity: 0; transform: translateY(16px); transition: opacity .55s ease, transform .55s ease; }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }

.site-header { transition: box-shadow .25s, background-color .25s; }
body.scrolled .site-header { box-shadow: 0 6px 24px rgba(0,0,0,.18); }
.header-cta { white-space: nowrap; }
.logo .lockup { white-space: nowrap; }
@media (max-width: 1200px) { .nav { gap: 18px; font-size: .74rem; } }
/* narrow desktops: tighten header metrics so logo, nav, and CTA share one row */
@media (min-width: 941px) and (max-width: 1100px) {
  .site-header .container { gap: 18px; }
  .logo-img { height: 52px; }
  .nav { gap: 12px; font-size: .72rem; letter-spacing: 1.3px; }
  .header-cta { padding: 13px 14px; font-size: .72rem; letter-spacing: 1.5px; }
}

/* ============================================================
   SAFETY NET — hero photos must always cover, never tile.
   (Theme `background:` shorthands reset background-size;
   this wins over every theme block. Do not remove.)
   ============================================================ */
html[data-theme] .hero.with-photo, .hero.with-photo {
  background-size: cover !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
}

/* mobile header overrides — must live at the end of the cascade */
@media (max-width: 940px) {
  .header-cta { padding: 13px 14px; font-size: .72rem; }
}
@media (max-width: 640px) {
  .header-cta { display: none; }
  .logo { font-size: 1.05rem; }
  .logo .mark { width: 26px; height: 26px; }
  .logo-img { height: 38px; }
}

/* ---------- entrance motion ---------- */

/* gentle page-enter fade; content is fully visible well under half a second */
@media (prefers-reduced-motion: no-preference) {
  body { animation: fade-in .3s var(--ease); }
}

/* mobile menu: the panel eases open AND closed. The display flip is held
   back (allow-discrete) so the closing fade can finish before the panel
   leaves the layout; browsers without discrete transitions simply snap. */
@media (max-width: 940px) {
  .nav { opacity: 0; transform: translateY(-8px);
    transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease), display var(--dur-2) allow-discrete; }
  body.nav-open .nav { opacity: 1; transform: none; }
  @starting-style { body.nav-open .nav { opacity: 0; transform: translateY(-8px); } }
}
/* menu links follow the panel with a short stagger */
@media (max-width: 940px) and (prefers-reduced-motion: no-preference) {
  body.nav-open .nav a { animation: drop-in var(--dur-3) var(--ease) backwards; }
  body.nav-open .nav a:nth-child(2) { animation-delay: .03s; }
  body.nav-open .nav a:nth-child(3) { animation-delay: .06s; }
  body.nav-open .nav a:nth-child(4) { animation-delay: .09s; }
  body.nav-open .nav a:nth-child(5) { animation-delay: .12s; }
  body.nav-open .nav a:nth-child(6) { animation-delay: .15s; }
  body.nav-open .nav a:nth-child(7) { animation-delay: .18s; }
  body.nav-open .nav a:nth-child(n+8) { animation-delay: .21s; }
}

/* admin modal: backdrop fades, dialog rises */
@media (prefers-reduced-motion: no-preference) {
  .modal-back.open { animation: fade-in var(--dur-2) var(--ease); }
  .modal-back.open .modal { animation: rise-in var(--dur-2) var(--ease); }
}

/* ---------- hero estimate CTA: same gold sweep as the header CTA ---------- */
.hero .btn-accent { background: linear-gradient(#d0a53c, #d0a53c) 0 50% / 0 100% no-repeat var(--accent); }
.hero .btn-accent:hover { background-size: 100% 100%; box-shadow: 0 6px 20px rgba(185,144,47,.28); }

/* ---------- comfortable touch targets on page-level components ----------
   Standalone text links keep their look; the tappable box grows upward. */
.container .brand-toc a, .container .toc a { display: inline-flex; align-items: flex-end; min-height: 44px; }
a#vendor-viz-full { display: inline-flex; align-items: flex-end; min-height: 44px; }
section .svc-card .go { display: inline-flex; align-items: flex-end; min-height: 44px; }
.projects .proj a.ext { display: inline-flex; align-items: flex-end; min-height: 44px; }

/* project tiles must be able to narrow below their 300px ideal on small phones */
section .projects { grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); }

/* built-in visualizer controls: finger-sized, with unified press feedback */
.viz-app .seg-toggle button { min-height: 44px; }
.viz-app .floors button { min-height: 44px; }
.viz-app .rooms { flex-wrap: wrap; }
@media (max-width: 900px) {
  .viz-app .colors { grid-template-columns: repeat(auto-fill, minmax(48px, 1fr)); }
}
.viz-app .seg-toggle button:active, .viz-app .floors button:active, .viz-app .colors button:active { transform: translateY(1px); }

/* ---------- reduced motion: collapse every animation to an instant state change ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  html { scroll-behavior: auto !important; }
}
