/* ============= Design tokens ============= */
:root {
  --background: oklch(0.985 0.005 80);
  --foreground: oklch(0.215 0.012 60);
  --muted: oklch(0.94 0.012 75);
  --muted-foreground: oklch(0.48 0.015 60);
  --border: oklch(0.88 0.012 75);
  --destructive: oklch(0.55 0.18 27);
  --gold: oklch(0.68 0.09 75);
  --cream: oklch(0.96 0.012 80);
  --forest: oklch(0.32 0.05 152);
  --forest-deep: oklch(0.32 0.05 152); /* same shade as --forest — kept as a separate token only so hover/tint rules stay easy to find */
  --forest-light: oklch(0.94 0.02 150);
  --font-display: "Cormorant Garamond", "Times New Roman", serif;
  --font-sans: "Inter", system-ui, sans-serif;
}

@layer base {
  :root {
    --color-background: var(--background);
    --color-foreground: var(--foreground);
    --color-muted: var(--muted);
    --color-muted-foreground: var(--muted-foreground);
    --color-border: var(--border);
    --color-destructive: var(--destructive);
    --color-gold: var(--gold);
    --color-cream: var(--cream);
    --color-forest: var(--forest);
    --color-forest-deep: var(--forest-deep);
    --color-forest-light: var(--forest-light);
  }
}

* { border-color: var(--border); }
html { scroll-behavior: smooth; overflow-x: hidden; }
body {
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  font-feature-settings: "ss01", "cv11";
  -webkit-font-smoothing: antialiased;
  margin: 0;
  overflow-x: hidden;
  max-width: 100%;
}
img { max-width: 100%; }

h1, h2, h3, h4, .font-display {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.01em;
}

.eyebrow {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.rule {
  display: inline-block;
  width: 2.5rem;
  height: 1px;
  background: var(--gold);
  vertical-align: middle;
  margin-right: 0.75rem;
}

.container-luxe { max-width: 1280px; margin-inline: auto; padding-inline: 1.5rem; }
@media (min-width: 768px) { .container-luxe { padding-inline: 3rem; } }

/* ============= Hero load animations ============= */
.fade-up { animation: fadeUp 0.9s ease-out both; }
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
.fade-in { animation: fadeIn 1.2s ease-out both; }
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }

/* ============= Scroll-reveal ============= */
/* JS-driven (IntersectionObserver in js/main.js adds `.is-visible`), not
   animation-timeline: view() — that CSS feature isn't supported in enough
   browsers yet (silently falls back to "just show it", no animation),
   so this needs to work everywhere IntersectionObserver does.
   Uses `animation`, not `transition` — several revealed elements (Trust
   cards, portfolio tiles) already use `transition-all` for their own
   hover effects, and a `transition` declared here would compete with
   that shorthand instead of combining with it. */
.reveal {
  opacity: 0;
  transform: translateY(28px);
}
.reveal.is-visible {
  animation: revealIn 0.9s cubic-bezier(.2,.7,.2,1) forwards;
}
@keyframes revealIn {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Staggered reveal for grids of cards/tiles: each direct child fades in
   slightly later than the previous once the group enters the viewport. */
.reveal-stagger > * {
  opacity: 0;
  transform: translateY(24px);
}
.reveal-stagger.is-visible > * {
  animation: revealIn 0.8s cubic-bezier(.2,.7,.2,1) forwards;
}
/* Higher specificity than the shorthand above (three classes/pseudo-class
   vs two), so these delays survive rather than being reset by the
   `animation` shorthand's implicit `animation-delay: 0s`. */
.reveal-stagger.is-visible > *:nth-child(2) { animation-delay: 0.08s; }
.reveal-stagger.is-visible > *:nth-child(3) { animation-delay: 0.16s; }
.reveal-stagger.is-visible > *:nth-child(4) { animation-delay: 0.24s; }
.reveal-stagger.is-visible > *:nth-child(5) { animation-delay: 0.32s; }
.reveal-stagger.is-visible > *:nth-child(6) { animation-delay: 0.4s; }
.reveal-stagger.is-visible > *:nth-child(7) { animation-delay: 0.48s; }
.reveal-stagger.is-visible > *:nth-child(8) { animation-delay: 0.56s; }
.reveal-stagger.is-visible > *:nth-child(9) { animation-delay: 0.64s; }

/* ============= Color utility shims ============= */
.bg-cream      { background-color: var(--cream); }
.bg-cream\/50  { background-color: color-mix(in oklab, var(--cream) 50%, transparent); }
.bg-cream\/60  { background-color: color-mix(in oklab, var(--cream) 60%, transparent); }
.bg-cream\/40  { background-color: color-mix(in oklab, var(--cream) 40%, transparent); }
.text-gold     { color: var(--gold); }
.text-gold\/10 { color: color-mix(in oklab, var(--gold) 10%, transparent); }
.hover\:text-gold:hover { color: var(--gold); }
.text-destructive { color: var(--destructive); }

/* Used on the hero quick-contact widget (light glass card over the photo) */
.text-background\/70 { color: color-mix(in oklab, var(--background) 70%, transparent); }
.text-background\/80 { color: color-mix(in oklab, var(--background) 80%, transparent); }
.hover\:text-background:hover { color: var(--background); }
.border-background\/10 { border-color: color-mix(in oklab, var(--background) 10%, transparent); }
.bg-background\/95 { background-color: color-mix(in oklab, var(--background) 95%, transparent); }

/* De-emphasised secondary text (fine print, review attributions) */
.text-foreground\/70 { color: color-mix(in oklab, var(--foreground) 70%, transparent); }
.text-foreground\/80 { color: color-mix(in oklab, var(--foreground) 80%, transparent); }
.placeholder\:text-muted-foreground\/90::placeholder { color: color-mix(in oklab, var(--muted-foreground) 90%, transparent); }

/* ============= Tertiary colour utility shims ============= */
.bg-forest        { background-color: var(--forest); }
.bg-forest-light  { background-color: var(--forest-light); }
.text-forest      { color: var(--forest); }
.border-forest    { border-color: var(--forest); }
.bg-forest\/25  { background-color: color-mix(in oklab, var(--forest) 25%, transparent); }
.border-forest\/40 { border-color: color-mix(in oklab, var(--forest) 40%, transparent); }
.text-forest\/10 { color: color-mix(in oklab, var(--forest) 10%, transparent); }

/* ============= Finishes: CSS-only tabs ============= */
.finish-radio { position: absolute; opacity: 0; pointer-events: none; }

.finish-tabs {
  position: relative;
  animation: tabsInvite 4s ease-in-out infinite;
}
/* A soft double-pulse of gold, inviting the visitor to try the toggle —
   loops continuously with a rest between cycles so it stays noticeable
   without being distracting. */
@keyframes tabsInvite {
  0%, 8%, 16%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--gold) 0%, transparent); }
  4%, 12% { box-shadow: 0 0 0 6px color-mix(in oklab, var(--gold) 25%, transparent); }
}

.finish-tab {
  position: relative;
  z-index: 1;
  color: color-mix(in oklab, var(--foreground) 70%, transparent);
  transition: color 0.35s ease;
}
.finish-tab:hover { color: var(--foreground); }

/* Sliding pill indicator — moves by translating between tab slots.
   The three labels share width via flex; we drive the indicator with
   CSS variables based on the checked radio. */
.finish-indicator {
  position: absolute;
  top: 0.375rem;
  left: 0.375rem;
  bottom: 0.375rem;
  width: calc((100% - 0.75rem) / 3);
  transform: translateX(0);
  background: var(--foreground);
  z-index: 0;
  transition: transform 0.5s cubic-bezier(.5,.05,.2,1);
  pointer-events: none;
}

/* Indicator position per checked tab — translate by full indicator width */
#f-natural:checked    ~ .flex .finish-tabs .finish-indicator { transform: translateX(0); }
#f-frequency:checked  ~ .flex .finish-tabs .finish-indicator { transform: translateX(100%); }
#f-wallpapers:checked ~ .flex .finish-tabs .finish-indicator { transform: translateX(200%); }

/* Mobile: stacked tabs use solid background instead of sliding pill */
@media (max-width: 767px) {
  .finish-tab {
    color: var(--foreground);
  }
  #f-natural:checked    ~ .flex .finish-tabs label[for="f-natural"],
  #f-frequency:checked  ~ .flex .finish-tabs label[for="f-frequency"],
  #f-wallpapers:checked ~ .flex .finish-tabs label[for="f-wallpapers"] {
    background: var(--foreground);
    color: var(--background);
  }
}


/* Active tab text color */
#f-natural:checked    ~ .flex .finish-tabs label[for="f-natural"],
#f-frequency:checked  ~ .flex .finish-tabs label[for="f-frequency"],
#f-wallpapers:checked ~ .flex .finish-tabs label[for="f-wallpapers"] {
  color: var(--background);
}

/* ============= Finish panels: stacked + crossfade ============= */
.finish-panels {
  position: relative;
  min-height: 1px;
}
.finish-panel {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transform: translateY(10px);
  transition: opacity 0.5s ease, transform 0.55s cubic-bezier(.2,.7,.2,1);
}
/* First panel reserves height (relative); others overlay absolutely */
.finish-panel[data-key="natural"] {
  position: relative;
}

/* Active panel reveal */
#f-natural:checked    ~ .finish-panels .finish-panel[data-key="natural"],
#f-frequency:checked  ~ .finish-panels .finish-panel[data-key="frequency"],
#f-wallpapers:checked ~ .finish-panels .finish-panel[data-key="wallpapers"] {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
  position: relative;
}
/* Hide inactive natural panel when another is active (it's the relative one) */
#f-frequency:checked  ~ .finish-panels .finish-panel[data-key="natural"],
#f-wallpapers:checked ~ .finish-panels .finish-panel[data-key="natural"] {
  position: absolute;
}

/* Image entrance: scale + blur + clip reveal */
#f-natural:checked    ~ .finish-panels .finish-panel[data-key="natural"]    .finish-img,
#f-frequency:checked  ~ .finish-panels .finish-panel[data-key="frequency"]  .finish-img,
#f-wallpapers:checked ~ .finish-panels .finish-panel[data-key="wallpapers"] .finish-img {
  animation: finishImgIn 0.65s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes finishImgIn {
  from { opacity: 0; transform: scale(1.06); filter: blur(6px); clip-path: inset(0 100% 0 0); }
  to   { opacity: 1; transform: scale(1);    filter: blur(0);   clip-path: inset(0 0 0 0); }
}

/* Text entrance: slide-up + fade, slightly delayed */
#f-natural:checked    ~ .finish-panels .finish-panel[data-key="natural"]    .finish-text,
#f-frequency:checked  ~ .finish-panels .finish-panel[data-key="frequency"]  .finish-text,
#f-wallpapers:checked ~ .finish-panels .finish-panel[data-key="wallpapers"] .finish-text {
  animation: finishTextIn 0.6s cubic-bezier(.2,.7,.2,1) 0.08s both;
}
@keyframes finishTextIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ============= Hero overlay: dark vignette, darkest at the bottom ============= */
.hero-overlay {
  background: linear-gradient(
    180deg,
    rgba(0,0,0,0.55) 0%,
    rgba(0,0,0,0.32) 45%,
    rgba(0,0,0,0.75) 100%
  );
}

/* ============= Reassurance bar: checkmark accents ============= */
.reassurance-item { position: relative; padding-left: 1.35em; }
.reassurance-item::before {
  content: "\2713";
  position: absolute;
  left: 0;
  color: var(--forest);
  font-size: 0.9em;
}

/* ============= FAQ accordion: plain <details>/<summary>, no JS ============= */
.faq-item { border-bottom: 1px solid var(--border); }
.faq-item summary {
  cursor: pointer;
  list-style: none;
  position: relative;
  padding: 1.25rem 2rem 1.25rem 0;
  font-family: var(--font-display);
  font-size: 1.1rem;
  color: var(--foreground);
}
.faq-item summary::-webkit-details-marker { display: none; }
/* Plus/minus icon: a fixed horizontal bar plus a vertical bar that rotates
   flat on open, so the two overlap into a single "minus" line. */
.faq-item summary::before,
.faq-item summary::after {
  content: "";
  position: absolute;
  right: 0.25rem;
  top: 50%;
  background: var(--gold);
  transition: transform 0.3s ease;
}
.faq-item summary::before { width: 12px; height: 2px; transform: translateY(-50%); }
.faq-item summary::after  { width: 2px; height: 12px; transform: translateY(-50%) rotate(0deg); }
.faq-item[open] summary::after { transform: translateY(-50%) rotate(90deg); }
.faq-item .faq-answer { padding: 0 2rem 1.25rem 0; }

/* ============= Mobile nav panel ============= */
/* The hamburger/close icon itself (previously .hamburger/.hamburger-bar
   here) was rebuilt 2026-07-08 using plain Tailwind utility classes
   directly in the HTML instead of custom CSS — see the "Mobile hamburger
   menu" README section for why: a custom-CSS-only icon can render
   invisibly (an empty button, no visible bars) if this stylesheet is ever
   served stale/cached, exactly the "no way to expand it" bug this was
   fixing. Two full `<span>` icon groups (`#mobile-nav-icon-open`/`-close`)
   are toggled via the same reliable Tailwind `hidden` class the panel
   itself uses, rather than one icon whose bars morph via custom
   transforms. */
/* Closed state is Tailwind's own `hidden` class (plain display:none) on the
   element itself — not a custom max-height/opacity rule — so the collapsed
   state can never depend on this stylesheet loading/cascading correctly;
   `hidden` is guaranteed to exist since the whole page already depends on
   Tailwind. JS (js/main.js) toggles `hidden` off and adds `.mobile-nav-open`
   to play the entrance animation below. Styled to match the rest of the
   site — font-display headings, gold top bar, gold hover — rather than a
   plain generic dropdown. */
#mobile-nav {
  max-height: calc(100vh - 5rem);
  overflow-y: auto;
}
#mobile-nav.mobile-nav-open {
  animation: mobileNavIn 0.25s ease forwards;
}
@keyframes mobileNavIn {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}
.mobile-nav-link {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--border);
  font-family: var(--font-display);
  font-size: 1.25rem;
  color: var(--foreground);
  transition: color 0.3s ease;
}
.mobile-nav-link:hover { color: var(--gold); }
body.mobile-nav-locked { overflow: hidden; }

/* ============= Reduced motion ============= */
@media (prefers-reduced-motion: reduce) {
  .fade-up, .fade-in, .reveal, .reveal-stagger > *,
  .finish-panel, .finish-img, .finish-text, .finish-tabs {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
    box-shadow: none !important;
  }
  .finish-indicator { transition: none !important; }
  /* #mobile-nav's closed state is the `hidden` class (display:none), not
     opacity/transform, so it's unaffected by the opacity:1/transform:none
     overrides above — only its entrance animation needs disabling here. */
  #mobile-nav.mobile-nav-open { animation: none !important; }
}
