:root {
  --bg: #f6f3ec;
  --bg-tint: #d8c9b8;
  --ink: #333d2e;
  --ink-soft: #6f7a68;
  --accent: #92a683;
  --frame-inset: clamp(0.9rem, 3.2vw, 2.75rem);
  --size-display: clamp(2.75rem, 14vw, 6.5rem);
  --size-base: clamp(0.72rem, 1.5vw, 0.85rem);
  /* Two voices, used deliberately: a serif for the one emotional
     moment on each page (the name, the error code, the inscription),
     a plain modern sans for everything that is just interface. */
  --font-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --font-sans: "Inter", -apple-system, "Segoe UI", Roboto, sans-serif;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  background: var(--bg);
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--bg);
  text-align: center;
  -webkit-tap-highlight-color: transparent;
}

/* Decorative invitation-card frame: pinned to the viewport (frames
   whatever is currently visible as the page scrolls), never intercepts
   clicks. Simplified to just the corner marks — no boxed border. */
.frame {
  position: fixed;
  top: calc(var(--frame-inset) + env(safe-area-inset-top));
  right: calc(var(--frame-inset) + env(safe-area-inset-right));
  bottom: calc(var(--frame-inset) + env(safe-area-inset-bottom));
  left: calc(var(--frame-inset) + env(safe-area-inset-left));
  z-index: 10;
  pointer-events: none;
}

.frame span {
  position: absolute;
  width: clamp(14px, 2.2vw, 22px);
  height: clamp(14px, 2.2vw, 22px);
  border: 1px solid var(--accent);
  opacity: 0.7;
}

.frame .tl { top: -1px; left: -1px; border-right: none; border-bottom: none; }
.frame .tr { top: -1px; right: -1px; border-left: none; border-bottom: none; }
.frame .bl { bottom: -1px; left: -1px; border-right: none; border-top: none; }
.frame .br { bottom: -1px; right: -1px; border-left: none; border-top: none; }

/* First-screen block shared by the hero (index) and the error content
   (404/50x): fills one viewport, centers its content, owns the frame
   padding and the radial background. The page can still be taller than
   this (footer below), so the block no longer relies on the document
   itself being locked to 100dvh. */
.hero,
main {
  width: 100%;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  background: radial-gradient(120% 120% at 50% 30%, var(--bg) 0%, var(--bg-tint) 140%);
  padding: calc(var(--frame-inset) + 2.25rem + env(safe-area-inset-top))
           calc(var(--frame-inset) + 1.75rem + env(safe-area-inset-right))
           calc(var(--frame-inset) + 2.25rem + env(safe-area-inset-bottom))
           calc(var(--frame-inset) + 1.75rem + env(safe-area-inset-left));
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Single unified reveal: whole hero appears as one quiet gesture, no per-letter or staggered motion */
.hero {
  opacity: 0;
  filter: blur(10px);
  transform: translateY(0.6em);
  animation: reveal 1s cubic-bezier(0.22, 1, 0.36, 1) forwards;
  animation-delay: 0.15s;
}

/* Utility voice: eyebrow label, button and footer nav — a plain,
   modern sans kept small and evenly weighted, so it reads as
   interface rather than competing with the serif headline. */
.eyebrow,
.cta,
.footer-link {
  font-family: var(--font-sans);
  font-size: var(--size-base);
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.eyebrow {
  color: var(--ink-soft);
}

/* Display voice: the headline is set light but in full caps — scale
   and tracking carry the emphasis, not weight, so it stays a
   nameplate rather than a shout. */
h1 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--size-display);
  line-height: 0.95;
  color: var(--ink);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}

@keyframes reveal {
  to {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
  }
}

/* Also used on a <button> (the 500 page's retry action), hence the
   appearance/cursor/font resets — a plain link needs none of those. */
.cta {
  display: inline-block;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  padding: 0.85em 2.4em;
  border-radius: 3px;
  background: transparent;
  color: var(--ink-soft);
  border: 1px solid var(--ink-soft);
  text-decoration: none;
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}

.cta:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}

.cta:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* Site footer: real, in-flow section below the first screen — reached
   by scrolling, present on every page. Text stays selectable (unlike
   the hero) since it will carry contact/legal details people copy. */
.site-footer {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  padding: clamp(3rem, 7vw, 4.5rem)
           calc(var(--frame-inset) + 1.25rem + env(safe-area-inset-right))
           calc(2.25rem + env(safe-area-inset-bottom))
           calc(var(--frame-inset) + 1.25rem + env(safe-area-inset-left));
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem 1.25rem;
}

.footer-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 0.25em;
  font-size: calc(var(--size-base) * 0.9);
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

/* Placeholder legal items: not wired up yet, styled as inert so they
   don't read as dead links. Swap to real <a href> once the pages exist. */
.footer-link.is-stub {
  opacity: 0.55;
  cursor: default;
}

.footer-requisites,
.footer-copy {
  font-family: var(--font-sans);
  font-size: calc(var(--size-base) * 0.9);
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  opacity: 0.8;
}

@media (prefers-reduced-motion: reduce) {
  .hero {
    animation: none;
    opacity: 1;
    filter: none;
    transform: none;
  }
}

.no-intro .hero {
  animation: none !important;
  opacity: 1 !important;
  filter: none !important;
  transform: none !important;
}
