/* ═══════════════════════════════════════════════════════════════════
   Lamma — base layer: reset, paper ground, type, ornaments.
   The decorative layer from decor.dart, ported to the web.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Reset ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scroll-behavior: smooth;
  /* The app's eyebrow is locale-aware uppercase; the web mirrors that with
     proper Turkish İ / caseless-script handling via the browser. */
}

body {
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink);
  background-color: var(--ground);
  min-height: 100vh;
  overflow-x: hidden;
}

/* ── PaperGround (decor.dart:80-192) ──────────────────────────────────
   "Flat #FAF7F2 is a colour; the same colour with a whisper of grain is stock.
   It is the cheapest thing in this file and the one that does most for how
   expensive the app feels."

   The app generates a seeded 96×96 noise tile and GPU-tiles it. We replicate
   this with an inline SVG feTurbulence data URL at ~3.5% opacity. The seed in
   feTurbulence is fixed so the grain is identical on every load — the same
   principle as the app's Random(7). */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='96' height='96'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' seed='7' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.35  0 0 0 0 0.32  0 0 0 0 0.27  0 0 0 1 0'/></filter><rect width='96' height='96' filter='url(%23n)'/></svg>");
  background-repeat: repeat;
}

/* ── Typography ────────────────────────────────────────────────────── */

.display {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.015em;
  color: var(--ink);
}
/* Arabic display uses Amiri — the app authors Arabic deliberately. */
:lang(ar) .display,
:lang(ur) .display,
:lang(fa) .display { font-family: var(--font-display-ar); font-weight: 700; line-height: 1.3; }
/* CJK display */
:lang(zh) .display { font-family: var(--font-cjk), var(--font-display); }
:lang(ja) .display { font-family: var(--font-cjk), var(--font-display); }
/* Devanagari display */
:lang(hi) .display { font-family: var(--font-deva), var(--font-display); }

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--eyebrow-size);
  font-weight: var(--eyebrow-weight);
  letter-spacing: var(--eyebrow-tracking);
  text-transform: uppercase;
  color: var(--brand);
  /* "gives each screen a masthead without a heavy app bar" — ceremony.dart:127 */
}
:lang(ar) .eyebrow,
:lang(ur) .eyebrow,
:lang(fa) .eyebrow { text-transform: none; font-family: var(--font-body-ar); letter-spacing: 0; }

.lead {
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: var(--maxw-prose);
}

/* ── The lit-top-edge glass card (decor.dart:40-69) ───────────────────
   "The highlight is what does the work: a hairline of near-white along the top,
   fading at the sides, reads as a bevel catching light. Without it a white card
   on an ivory ground is just a lighter rectangle." */
.card {
  background: var(--card);
  border-radius: var(--r-card);
  border: 1px solid color-mix(in srgb, #fff 90%, transparent);
  position: relative;
  overflow: hidden;
  box-shadow: var(--shadow-contact), var(--shadow-soft);
  /* The lit top edge: a gradient overlay along the top, fading at the sides. */
}
.card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb, #fff 65%, transparent) 20%,
    color-mix(in srgb, #fff 65%, transparent) 80%,
    transparent 100%);
  z-index: 1;
  pointer-events: none;
}
:root[data-theme="dark"] .card::before {
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb, #fff 6%, transparent) 20%,
    color-mix(in srgb, #fff 6%, transparent) 80%,
    transparent 100%);
}

/* ── Tinted card shadow — "the tint is what makes a card feel like it belongs
   to that gathering" (ceremony.dart:134-145). Apply --accent to override. */
.card[data-accent] {
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--ink) 5%, transparent),
    0 12px 40px color-mix(in srgb, var(--accent, var(--ink)) 12%, transparent);
}

/* ── The arch (decor.dart:22-33) ──────────────────────────────────────
   "A full semicircle on top, barely-rounded feet." */
.arch-top {
  border-top-left-radius: 999px;
  border-top-right-radius: 999px;
  border-bottom-left-radius: var(--r-arch-feet);
  border-bottom-right-radius: var(--r-arch-feet);
}

/* ── The hairline double frame (ornaments.dart:96-135) ────────────────
   "Two inset rules, five units apart, the outer one brighter." */
.double-frame {
  position: relative;
}
.double-frame::after {
  content: '';
  position: absolute;
  inset: 14px;
  border: 1px solid color-mix(in srgb, currentColor 50%, transparent);
  border-radius: inherit;
  pointer-events: none;
}
.double-frame::before {
  content: '';
  position: absolute;
  inset: 19px;   /* 5 units apart (ornaments.dart:97) */
  border: 1px solid color-mix(in srgb, currentColor 24%, transparent);
  border-radius: inherit;
  pointer-events: none;
  z-index: 1;
}

/* ── The diamond divider (ceremony.dart:262-301) ──────────────────────
   "rule · rotated square · rule" */
.diamond-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 0 auto;
  max-width: 280px;
}
.diamond-divider::before,
.diamond-divider::after {
  content: '';
  height: 1px;
  flex: 1;
  background: var(--hairline);
}
.diamond-divider__diamond {
  width: 7px;
  height: 7px;
  background: var(--brand);
  transform: rotate(45deg);
  flex-shrink: 0;
  opacity: 0.7;
}

/* ── Buttons ───────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 600;
  padding: 14px 28px;
  border-radius: var(--r-pill);
  border: none;
  cursor: pointer;
  text-decoration: none;
  transition: transform var(--t-quick) var(--ease),
              box-shadow var(--t-quick) var(--ease),
              background var(--t-quick) var(--ease);
  white-space: nowrap;
}
.btn:active { transform: scale(0.98); }

.btn--primary {
  background: var(--brand-strong);
  color: var(--on-brand);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--brand) 35%, transparent);
}
.btn--primary:hover {
  box-shadow: 0 6px 20px color-mix(in srgb, var(--brand) 45%, transparent);
  transform: translateY(-1px);
}

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--hairline);
}
.btn--ghost:hover {
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  border-color: color-mix(in srgb, var(--ink) 16%, transparent);
}

/* ── Pills / chips ─────────────────────────────────────────────────── */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--accent, var(--brand)) 12%, transparent);
  color: color-mix(in srgb, var(--accent, var(--brand)) 90%, var(--ink));
}

/* ── Focus rings (accessibility) ───────────────────────────────────── */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ── Reveal animation (decor.dart:273-362, "Reveal") ──────────────────
   "Content that arrives, rather than content that is simply already there.
   A section fades up as it enters the viewport." */
.reveal {
  opacity: 0;
  transform: translateY(26px);   /* decor.dart:278 default rise */
  transition: opacity 620ms var(--ease-settle), transform 620ms var(--ease-settle);
  will-change: opacity, transform;
}
.reveal.is-shown {
  opacity: 1;
  transform: translateY(0);
}

/* ── Staggered entrance (motion.dart:24-87) ───────────────────────────
   fade + 12px upward slide, 45ms stagger per index. */
.stagger > * {
  opacity: 0;
  transform: translateY(var(--rise));
  transition: opacity var(--t-entrance) var(--ease), transform var(--t-entrance) var(--ease);
}
.stagger.is-shown > * { opacity: 1; transform: translateY(0); }
.stagger.is-shown > *:nth-child(1) { transition-delay: calc(0 * var(--stagger)); }
.stagger.is-shown > *:nth-child(2) { transition-delay: calc(1 * var(--stagger)); }
.stagger.is-shown > *:nth-child(3) { transition-delay: calc(2 * var(--stagger)); }
.stagger.is-shown > *:nth-child(4) { transition-delay: calc(3 * var(--stagger)); }
.stagger.is-shown > *:nth-child(5) { transition-delay: calc(4 * var(--stagger)); }
.stagger.is-shown > *:nth-child(6) { transition-delay: calc(5 * var(--stagger)); }
.stagger.is-shown > *:nth-child(7) { transition-delay: calc(6 * var(--stagger)); }
.stagger.is-shown > *:nth-child(8) { transition-delay: calc(7 * var(--stagger)); }

/* ── Skeleton shimmer (motion.dart:95-164) ────────────────────────────
   "A pulsing placeholder that reads as 'content is loading' instead of a spinner." */
.skeleton {
  background: color-mix(in srgb, var(--ink) 12%, transparent);
  animation: skeleton-pulse 1100ms ease-in-out infinite alternate;
  border-radius: 6px;
}
@keyframes skeleton-pulse {
  0% { opacity: 0.4; }
  100% { opacity: 0.8; }
}

/* ═══════════════════════════════════════════════════════════════════
   REDUCED MOTION — non-negotiable.
   "A ceremony you can't skip is a barrier, not a feature." — motion.dart:13-14
   Every animation resolves to its final state instantly.
   ═══════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    /* A delay survives a near-zero duration: without these the hero still
       arrived in five beats and the invitation's lines one by one over
       1.5s, as jumps. Reduced means the final state on the first frame. */
    animation-delay: 0ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
  .stagger > * { opacity: 1; transform: none; }
  .skeleton { animation: none; }
  .hero__nur-bloom { opacity: var(--nur-bloom-opacity); transform: none; }
  .hero__nur-mote { opacity: 0.1; transform: none; }
  /* The envelope shows already-open under reduced motion: envelope.js adds
     is-open on load, and this kill-switch makes every transition instant —
     the final state renders on the first frame (animated_invite.dart
     contract). The class the choreography selects on is .envelope; the
     element in index.html carries it. */
}
