/* Guest-facing invitations. Shared base + one block per template (.tpl-<id>).
   Colours come from CSS variables set per palette: --bg --ink --accent --soft */
* { box-sizing: border-box; }
/* 3D effects must never make the page wider than the phone (which would make
   mobile browsers zoom out), so anything sticking out sideways is clipped. */
html { -webkit-text-size-adjust: 100%; overflow-x: hidden; }
body.inv { overflow-x: hidden; }
body.inv {
  margin: 0; background: var(--bg); color: var(--ink); line-height: 1.6;
  --body-font: 'Cormorant Garamond', Georgia, serif; --name-font: 'Great Vibes', 'Cormorant Garamond', cursive; --ui-font: 'Tajawal', system-ui, sans-serif;
  font-family: var(--body-font); font-size: 18px;
}
body.inv.lang-ar { --body-font: 'Amiri', 'Tajawal', serif; --name-font: 'Aref Ruqaa', 'Amiri', serif; font-size: 18px; }
body.locked { overflow: hidden; }
[hidden] { display: none !important; }
img { max-width: 100%; display: block; }

@media (min-width: 560px) {
  body.inv { background: radial-gradient(circle at 50% 0, var(--soft), var(--bg) 70%); background-attachment: fixed; }
  .card { margin: 2rem auto !important; border-radius: 28px; box-shadow: 0 30px 80px rgba(0, 0, 0, .12); min-height: auto !important; }
}

.card { position: relative; max-width: 480px; margin: 0 auto; min-height: 100vh; padding: 0 1.6rem 1.5rem; text-align: center; overflow: hidden; background: var(--bg); }
.orn { position: absolute; top: 0; left: 0; width: 100%; height: auto; aspect-ratio: 2 / 3; color: var(--accent); pointer-events: none; z-index: 0; }
.card > section, .card > figure, .card > footer { position: relative; z-index: 1; }

.cover { min-height: 600px; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 6rem .5rem 3rem; }
.guest { font-family: var(--ui-font); font-size: .95rem; background: var(--soft); border-radius: 999px; padding: .3rem 1rem; margin: 0 0 1.2rem; }
.host-line { font-size: 1.05rem; letter-spacing: .03em; margin: 0 0 .6rem; opacity: .85; }
.families { font-size: .95rem; opacity: .8; margin: 0 0 .4rem; }
.names { font-family: var(--name-font); font-weight: 400; font-size: clamp(2.8rem, 13vw, 3.6rem); line-height: 1.15; margin: .3rem 0 .8rem; color: var(--ink); display: flex; flex-direction: column; align-items: center; }
.names .amp { font-size: .55em; color: var(--accent); margin: .1em 0; }
.names.grad { font-size: clamp(2.4rem, 11vw, 3.2rem); }
.degree, .university { margin: 0; font-size: 1.15rem; }
.university { opacity: .8; }
.class-of { font-family: var(--ui-font); letter-spacing: .25em; text-transform: uppercase; color: var(--accent); font-weight: 700; margin-top: 1rem; font-size: .9rem; }
.lang-ar .class-of { letter-spacing: 0; font-size: 1rem; }
.date-short { margin: .6rem 0 0; font-size: 1.05rem; border-top: 1px solid var(--accent); border-bottom: 1px solid var(--accent); padding: .35rem 1.2rem; }

.photo { margin: 0 0 2rem; }
.photo img { width: 100%; border-radius: 200px 200px 18px 18px; aspect-ratio: 4 / 5; object-fit: cover; box-shadow: 0 0 0 6px var(--bg), 0 0 0 7px var(--accent); }

.message { padding: 0 .5rem 2rem; font-size: 1.15rem; }
.message p { margin: 0; white-space: pre-line; }

.details { display: grid; gap: 1rem; margin-bottom: 2rem; }
.detail { background: var(--soft); border-radius: 18px; padding: 1.3rem 1rem; }
.detail h2 { font-family: var(--ui-font); font-size: .8rem; letter-spacing: .25em; text-transform: uppercase; color: var(--accent); margin: 0 0 .4rem; }
.lang-ar .detail h2 { letter-spacing: 0; font-size: .95rem; }
.detail p { margin: 0 0 .2rem; }
.detail .big { font-size: 1.25rem; font-weight: 700; }
.btn { display: inline-block; margin-top: .8rem; border: 0; border-radius: 999px; padding: .65rem 1.4rem; background: var(--accent); color: var(--bg); font: 700 .95rem var(--ui-font); text-decoration: none; cursor: pointer; }
.btn.ghost { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--accent); }
.btn:disabled { opacity: .6; }

.countdown { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; margin: 0 0 2rem; font-family: var(--ui-font); }
.countdown div { border: 1px solid var(--accent); border-radius: 14px; padding: .7rem .2rem; }
.countdown b { display: block; font-size: 1.6rem; line-height: 1.1; color: var(--accent); font-variant-numeric: tabular-nums; }
.countdown span { font-size: .75rem; opacity: .8; }
.countdown.done { display: block; border: 1px dashed var(--accent); border-radius: 14px; padding: 1rem; }

.rsvp { background: var(--soft); border-radius: 22px; padding: 1.6rem 1.2rem; margin-bottom: 2rem; text-align: start; }
.rsvp h2 { text-align: center; font-family: var(--name-font); font-weight: 400; font-size: 2.2rem; margin: 0 0 .5rem; }
.rsvp .muted { text-align: center; opacity: .8; }
.rsvp form { display: grid; gap: .9rem; font-family: var(--ui-font); font-size: .95rem; }
.rsvp label { display: grid; gap: .3rem; }
.rsvp input, .rsvp select, .rsvp textarea { font: 400 1rem var(--ui-font); padding: .7rem .8rem; border-radius: 12px; border: 1px solid color-mix(in srgb, var(--ink) 25%, transparent); background: var(--bg); color: var(--ink); width: 100%; }
.rsvp .choice { display: grid; gap: .5rem; }
.rsvp .choice label { display: flex; align-items: center; gap: .6rem; background: var(--bg); border-radius: 12px; padding: .7rem .8rem; cursor: pointer; }
.rsvp input[type=radio] { width: auto; accent-color: var(--accent); }
.rsvp .btn { width: 100%; margin: 0; padding: .85rem; font-size: 1rem; }
.rsvp .hp { position: absolute; left: -9999px; width: 1px; height: 1px; }
.thanks { text-align: center; font-size: 1.2rem; font-family: var(--body-font); }
.form-msg { margin: 0; text-align: center; min-height: 1em; }

.inv-foot { padding: 1rem 0 .5rem; font-family: var(--ui-font); font-size: .8rem; opacity: .6; }
.inv-foot a { color: inherit; }

.music-btn { position: fixed; bottom: 18px; inset-inline-end: 18px; z-index: 30; width: 48px; height: 48px; border-radius: 50%; border: 0; background: var(--accent); color: var(--bg); font-size: 1.3rem; box-shadow: 0 6px 18px rgba(0, 0, 0, .25); cursor: pointer; }
.music-btn.on { animation: spin 4s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Scroll reveal */
.reveal { opacity: 0; transform: perspective(900px) rotateX(18deg) translateY(30px); transform-origin: center top; transition: opacity .8s ease, transform .9s cubic-bezier(.2, .7, .2, 1); }
.reveal.in { opacity: 1; transform: none; }
.no-intro .reveal, [data-mode="preview"] .reveal { opacity: 1; transform: none; }

/* ---------- Opening: 3D envelope ----------
   Timeline after tap (or auto-open): seal pops (0s) → flap swings open (.3s)
   → letter slides out toward the guest (.9s) → scene zooms and fades (1.9s)
   → invitation card rises in 3D (JS adds .opened at ~2.6s). */
.intro { position: fixed; inset: 0; z-index: 50; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.2rem; background: radial-gradient(circle at 50% 40%, var(--soft), var(--bg) 70%); transition: opacity .8s ease 1.9s; padding: 1.5rem; overflow: hidden; }
.opening .intro { opacity: 0; pointer-events: none; }
.env-scene { position: relative; width: min(330px, 84vw); aspect-ratio: 3 / 2.1; perspective: 1100px; cursor: pointer; margin-top: 3rem; }
.env-tilt { position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateX(var(--rx, 10deg)) rotateY(var(--ry, 0deg)); transition: transform .35s ease-out; }
.opening .env-tilt { transform: rotateX(0deg) rotateY(0deg) translateY(12%) scale(1.25); transition: transform 1s cubic-bezier(.6, 0, .3, 1) 1.7s; }
.envelope { position: absolute; inset: 0; transform-style: preserve-3d; animation: env-float 5s ease-in-out infinite; }
.opening .envelope { animation-play-state: paused; }
.envelope > * { position: absolute; border-radius: 12px; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.env-back { inset: 0; background: color-mix(in srgb, var(--soft) 70%, var(--accent)); transform: translateZ(-2px); box-shadow: inset 0 0 40px rgba(0, 0, 0, .12); }
.env-letter { inset: 7% 7% 9%; background: var(--bg); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); box-shadow: 0 6px 20px rgba(0, 0, 0, .15); display: flex; flex-direction: column; align-items: center; justify-content: flex-start; padding-top: 9%; gap: .2rem; color: var(--ink); transform: translateZ(1px); }
.letter-mono { font-family: var(--name-font); font-size: 1.5rem; color: var(--accent); line-height: 1.2; }
.letter-names { font-family: var(--name-font); font-size: 1.05rem; line-height: 1.3; padding: 0 .8rem; text-align: center; }
.opening .env-letter { animation: letter-out 1.3s cubic-bezier(.3, .7, .2, 1) .85s forwards; }
.env-pocket { inset: 0; background: linear-gradient(160deg, color-mix(in srgb, var(--soft) 92%, white), var(--soft)); clip-path: polygon(0 0, 50% 54%, 100% 0, 100% 100%, 0 100%); transform: translateZ(3px); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent); }
.env-pocket::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(to top right, transparent 49.4%, color-mix(in srgb, var(--accent) 25%, transparent) 50%, transparent 50.6%), linear-gradient(to top left, transparent 49.4%, color-mix(in srgb, var(--accent) 25%, transparent) 50%, transparent 50.6%); }
.env-flap { inset: 0 0 auto; height: 56%; transform-origin: top center; transform-style: preserve-3d; transform: translateZ(4px) rotateX(0deg); transition: transform .9s cubic-bezier(.5, 0, .3, 1) .3s; border-radius: 12px 12px 0 0; -webkit-backface-visibility: visible; backface-visibility: visible; }
.flap-front, .flap-back { position: absolute; inset: 0; clip-path: polygon(0 0, 100% 0, 50% 100%); -webkit-backface-visibility: hidden; backface-visibility: hidden; border-radius: 12px 12px 0 0; }
.flap-front { background: linear-gradient(180deg, color-mix(in srgb, var(--soft) 78%, var(--accent)), color-mix(in srgb, var(--soft) 88%, var(--accent))); }
/* The back face is flipped about its own centre, so its triangle is drawn
   upside down here; once the flap swings open it points up, as it should. */
.flap-back { background: color-mix(in srgb, var(--soft) 60%, var(--accent)); transform: rotateX(180deg); clip-path: polygon(0 100%, 100% 100%, 50% 0); }
/* Once open, the flap folds back BEHIND the letter (z -1px), like a real envelope. */
.opening .env-flap { transform: translateZ(-1px) rotateX(178deg); }
.seal { top: 56%; left: 50%; width: 66px; height: 66px; margin: -33px 0 0 -33px; border-radius: 50% !important; background: radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--accent) 70%, white), var(--accent) 55%, color-mix(in srgb, var(--accent) 75%, black)); color: var(--bg); display: grid; place-items: center; font-family: var(--name-font); font-size: 1.25rem; box-shadow: 0 6px 14px rgba(0, 0, 0, .3), inset 0 0 0 4px color-mix(in srgb, var(--bg) 22%, transparent); transform: translateZ(6px); transition: transform .45s cubic-bezier(.5, -0.5, .5, 1.5), opacity .35s ease .1s; }
.opening .seal { transform: translateZ(30px) scale(1.5) rotate(25deg); opacity: 0; }
.env-shadow { position: absolute; left: 12%; right: 12%; bottom: -16%; height: 14%; border-radius: 50%; background: radial-gradient(closest-side, rgba(0, 0, 0, .28), transparent); animation: shadow-float 5s ease-in-out infinite; }
.intro-names { position: relative; font-family: var(--name-font); font-size: 1.7rem; margin: 1.2rem 0 0; text-align: center; animation: intro-in 1s ease .2s both; transition: opacity .4s; }
.opening .intro-names, .opening .open-btn { opacity: 0; }
.open-btn { position: relative; overflow: hidden; border: 0; border-radius: 999px; padding: .75rem 1.7rem .85rem; background: var(--ink); color: var(--bg); font: 700 1rem var(--ui-font); cursor: pointer; animation: intro-in 1s ease .4s both, pulse 2.4s ease-in-out 1.4s infinite; transition: opacity .3s; }
.auto-bar { position: absolute; inset: auto 0 0; height: 3px; background: var(--accent); transform: scaleX(0); transform-origin: left center; animation: auto-fill var(--auto-ms, 12000ms) linear forwards; }
[dir="rtl"] .auto-bar { transform-origin: right center; }
.intro.paused .auto-bar { animation-play-state: paused; }
@keyframes env-float { 0%, 100% { transform: translateY(0) rotateZ(-.6deg); } 50% { transform: translateY(-10px) rotateZ(.6deg); } }
@keyframes shadow-float { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(.85); opacity: .7; } }
@keyframes letter-out { 0% { transform: translateZ(1px) translateY(0); } 55% { transform: translateZ(1px) translateY(-58%); } 100% { transform: translateZ(70px) translateY(-46%) scale(1.04); } }
@keyframes intro-in { from { opacity: 0; transform: translateY(14px); } }
@keyframes auto-fill { to { transform: scaleX(1); } }
@keyframes pulse { 50% { transform: scale(1.05); } }

/* Card rises in 3D after the envelope opens */
.card { transition: opacity 1s ease, transform 1.2s cubic-bezier(.2, .8, .2, 1); }
/* Tilted with its bottom leaning AWAY (negative rotateX, pivot at the top): a
   tall card tilted toward the viewer would look wider than the phone and make
   mobile browsers zoom the whole page out. */
.locked .card { opacity: 0; transform-origin: 50% 0; transform: perspective(1200px) rotateX(-14deg) translateY(60px) scale(.94); }
.opened:not(.no-intro) .orn { animation: orn-in 1.8s ease both; }
.opened:not(.no-intro) .cover > * { animation: rise .9s cubic-bezier(.2, .7, .2, 1) both; }
.opened:not(.no-intro) .cover > :nth-child(2) { animation-delay: .15s; }
.opened:not(.no-intro) .cover > :nth-child(3) { animation-delay: .3s; }
.opened:not(.no-intro) .cover > :nth-child(4) { animation-delay: .45s; }
.opened:not(.no-intro) .cover > :nth-child(5) { animation-delay: .6s; }
.opened:not(.no-intro) .cover > :nth-child(6) { animation-delay: .75s; }
.opened:not(.no-intro) .names .amp { animation: amp-glow 3.5s ease-in-out 1.5s infinite; }
@keyframes rise { from { opacity: 0; transform: perspective(600px) rotateX(35deg) translateY(24px); } }
@keyframes orn-in { from { transform: scale(1.06); filter: blur(6px); } }
@keyframes amp-glow { 50% { text-shadow: 0 0 14px color-mix(in srgb, var(--accent) 70%, transparent); } }

/* Celebration burst (petals for weddings/engagements, confetti for graduations) */
.burst { position: fixed; inset: 0; pointer-events: none; z-index: 40; overflow: hidden; }
.burst i { position: absolute; top: -6vh; left: var(--x); width: var(--w, 10px); height: var(--h, 14px); background: var(--c); border-radius: 60% 0 60% 0; opacity: .9; animation: fall var(--d) cubic-bezier(.25, .4, .4, 1) var(--delay) forwards; }
.cat-graduation .burst i { border-radius: 2px; }
@keyframes fall { 0% { transform: translate3d(0, 0, 0) rotateX(0) rotateZ(0); opacity: 0; } 10% { opacity: .95; } 100% { transform: translate3d(var(--drift), 112vh, 0) rotateX(var(--spin)) rotateZ(var(--rot)); opacity: .85; } }

/* ---------- Floating background (moves with finger / phone tilt) ---------- */
.ambient { position: fixed; inset: 0; pointer-events: none; z-index: 20; overflow: hidden; opacity: 0; transition: opacity 2.5s ease; }
.opened .ambient { opacity: 1; }
.amb-layer { position: absolute; inset: -50px; transform: translate3d(calc(var(--px, 0px) * var(--k)), calc(var(--py, 0px) * var(--k)), 0); transition: transform .9s ease-out; }
.ambient i { position: absolute; left: var(--x); top: -6vh; width: var(--s); height: calc(var(--s) * 1.3); background: var(--c); border-radius: 60% 0 60% 0; opacity: var(--o); animation: amb-fall var(--d) linear var(--delay) infinite; will-change: transform; }
.ambient[data-kind="confetti"] i { border-radius: 2px; height: calc(var(--s) * 1.6); }
.ambient[data-kind="rise"] i { top: auto; bottom: -6vh; height: var(--s); border-radius: 50%; box-shadow: 0 0 10px 3px var(--c); animation-name: amb-rise; }
.ambient[data-kind="stars"] i { top: var(--y); height: var(--s); border-radius: 0; clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); animation: twinkle var(--d) ease-in-out var(--delay) infinite; }
@keyframes amb-fall { 0% { transform: translate3d(0, 0, 0) rotate(0); } 25% { transform: translate3d(var(--sway), 28vh, 0) rotate(90deg); } 50% { transform: translate3d(0, 56vh, 0) rotate(180deg); } 75% { transform: translate3d(calc(var(--sway) * -1), 84vh, 0) rotate(270deg); } 100% { transform: translate3d(0, 115vh, 0) rotate(360deg); } }
@keyframes amb-rise { 0% { transform: translate3d(0, 0, 0); opacity: 0; } 15% { opacity: var(--o); } 50% { transform: translate3d(var(--sway), -55vh, 0); } 85% { opacity: var(--o); } 100% { transform: translate3d(0, -115vh, 0); opacity: 0; } }
@keyframes twinkle { 0%, 100% { opacity: .1; transform: scale(.5) rotate(0); } 50% { opacity: var(--o); transform: scale(1) rotate(35deg); } }

/* ---------- Tap sparkles ---------- */
.spark { position: fixed; left: var(--x); top: var(--y); z-index: 45; pointer-events: none; color: var(--c, var(--accent)); font: 400 var(--fs) / 1 system-ui, sans-serif; text-shadow: 0 0 8px color-mix(in srgb, var(--accent) 60%, transparent); animation: spark .9s cubic-bezier(.2, .7, .3, 1) forwards; }
.spark-ring { position: fixed; left: var(--x); top: var(--y); z-index: 45; width: 70px; height: 70px; margin: -35px 0 0 -35px; border-radius: 50%; border: 2px solid var(--accent); pointer-events: none; animation: ring .6s ease-out forwards; }
@keyframes spark { 0% { transform: translate(-50%, -50%) scale(.3); opacity: 1; } 100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1) rotate(var(--r)); opacity: 0; } }
@keyframes ring { from { transform: scale(.2); opacity: .9; } to { transform: scale(1.3); opacity: 0; } }

/* ---------- Tap-to-flip 3D cards (when / where) ---------- */
.details { perspective: 1100px; }
.flip-card { display: grid; transform-style: preserve-3d; transition: transform .8s cubic-bezier(.3, .7, .2, 1); cursor: pointer; padding: 1.3rem 1rem 1rem; }
.flip-card.flipped { transform: rotateY(180deg); }
.flip-card .face { grid-area: 1 / 1; display: flex; flex-direction: column; align-items: center; justify-content: center; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.flip-card .back { transform: rotateY(180deg); }
.d-icon { color: var(--accent); display: block; margin-bottom: .3rem; }
.d-icon svg { display: block; }
.flip-btn { margin-top: .7rem; border: 0; background: none; color: var(--accent); font: 600 .85rem var(--ui-font); cursor: pointer; padding: .3rem .7rem; border-radius: 999px; }
.flip-btn:focus-visible { outline: 2px solid var(--accent); }
.opened .flip-card:not(.flipped):not(.touched) { animation: nudge 6s ease-in-out 3s infinite; }
.opened .flip-card:nth-child(2):not(.flipped):not(.touched) { animation-delay: 4.2s; }
@keyframes nudge { 0%, 14%, 100% { transform: rotateY(0); } 5% { transform: rotateY(16deg); } 10% { transform: rotateY(-6deg); } }

/* ---------- Scratch to reveal the date ---------- */
.scratch-wrap { position: relative; display: inline-block; margin: .6rem 0 0; -webkit-user-select: none; user-select: none; }
.scratch-wrap .date-short { margin: 0; }
.scratch-canvas { position: absolute; top: -6px; left: -10px; width: calc(100% + 20px); height: calc(100% + 12px); border-radius: 10px; touch-action: none; cursor: grab; box-shadow: 0 4px 14px rgba(0, 0, 0, .2); transition: opacity .7s ease, transform .7s ease; }
.opened .scratch-canvas:not(.done):not(.touched) { animation: scratch-wiggle 3.5s ease-in-out 2.5s infinite; }
.scratch-canvas.done { opacity: 0; transform: scale(1.12); pointer-events: none; }
.scratch-canvas:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
@keyframes scratch-wiggle { 0%, 20%, 100% { transform: rotate(0); } 5% { transform: rotate(-2deg) scale(1.03); } 10% { transform: rotate(2deg) scale(1.03); } 15% { transform: rotate(0) scale(1); } }

/* ---------- Animated artwork (Phase 2) ----------
   Elements carry .a-* classes and their pivot as an inline transform-origin.
   On invitations they start once the envelope has opened; in gallery
   illustrations they always run. */
.orn [class*="a-"], .g-art [class*="a-"] { transform-box: view-box; }
.opened:not(.no-intro) .orn .a-draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw 2.6s ease .3s forwards; }
.opened:not(.no-intro) .orn .a-sway, .g-art .a-sway { animation: sway 4.6s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-sway-slow { animation: sway-slow 7s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-glow, .g-art .a-glow { animation: glow 2.6s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-pulse, .g-art .a-pulse { animation: pulse-svg 3s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-twinkle, .g-art .a-twinkle { animation: twinkle-svg 2.4s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-moon { animation: moon 5s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-bloom { animation: bloom 1.4s cubic-bezier(.3, 1.4, .5, 1) both; }
.opened:not(.no-intro) .orn .a-rose { animation: rose-in 1.6s cubic-bezier(.3, 1.3, .5, 1) both; }
.opened:not(.no-intro) .orn .a-grow { animation: grow 1.8s cubic-bezier(.3, 1.2, .5, 1) .4s both; }
.opened:not(.no-intro) .orn .a-bob { animation: bob 3.2s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-tassel, .g-art .a-tassel { animation: tassel 2.2s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-flutter { animation: flutter 3.4s ease-in-out infinite; }
.opened:not(.no-intro) .orn .a-toss, .g-art .a-toss { animation: toss 6s ease-in-out 1s infinite; }
.g-art .a-beat { animation: beat 1.8s ease-in-out infinite; }
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes sway { 0%, 100% { transform: rotate(-5deg); } 50% { transform: rotate(5deg); } }
@keyframes sway-slow { 0%, 100% { transform: rotate(-1.6deg); } 50% { transform: rotate(1.6deg); } }
@keyframes glow { 0%, 100% { opacity: .35; } 50% { opacity: .95; } }
@keyframes pulse-svg { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.22); } }
@keyframes twinkle-svg { 0%, 100% { transform: scale(.65); opacity: .55; } 50% { transform: scale(1.15); opacity: 1; } }
@keyframes moon { 0%, 100% { filter: drop-shadow(0 0 3px currentColor); } 50% { filter: drop-shadow(0 0 16px currentColor); } }
@keyframes bloom { from { transform: scale(0) rotate(-120deg); opacity: 0; } }
@keyframes rose-in { from { transform: scale(.15) rotate(-160deg); opacity: 0; } }
@keyframes grow { from { transform: scale(.55); opacity: 0; } }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
@keyframes tassel { 0%, 100% { transform: rotate(-9deg); } 50% { transform: rotate(9deg); } }
@keyframes flutter { 0%, 100% { transform: translateY(0) rotate(0); } 33% { transform: translateY(-6px) rotate(22deg); } 66% { transform: translateY(4px) rotate(-16deg); } }
@keyframes toss { 0%, 62%, 100% { transform: translateY(0) rotate(0); } 72% { transform: translateY(-34px) rotate(-14deg); } 82% { transform: translateY(-8px) rotate(10deg); } 90% { transform: translateY(0) rotate(-3deg); } }
@keyframes beat { 0%, 100% { transform: scale(1); } 15% { transform: scale(1.08); } 30% { transform: scale(.98); } 45% { transform: scale(1.05); } }

/* ---------- 3D photo gallery (Phase 3) ---------- */
.gallery { margin: 0 -1.6rem 2.2rem; padding: 0 0 .5rem; overflow: hidden; }
.gallery h2 { font-family: var(--name-font); font-weight: 400; font-size: 2.2rem; margin: 0 0 .6rem; color: var(--accent); }
.g-stage { position: relative; height: 340px; perspective: 1000px; transform-style: preserve-3d; touch-action: pan-y; -webkit-user-select: none; user-select: none; outline: none; }
.g-stage:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.g-slide { position: absolute; top: 10px; left: 50%; width: 220px; height: 300px; margin: 0 0 0 -110px; border-radius: 18px; overflow: hidden; background: var(--soft); box-shadow: 0 18px 40px rgba(0, 0, 0, .25), 0 0 0 4px var(--bg), 0 0 0 5px color-mix(in srgb, var(--accent) 60%, transparent); transition: transform .7s cubic-bezier(.25, .8, .25, 1), opacity .7s ease; cursor: pointer; }
.g-slide.active { cursor: default; }
.g-slide img, .g-slide svg { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
.g-slide::after { content: ""; position: absolute; inset: 0; background: linear-gradient(115deg, rgba(255, 255, 255, .28), transparent 40%); pointer-events: none; }
.g-art { color: var(--accent); }
.g-nav { display: flex; align-items: center; justify-content: center; gap: .8rem; margin-top: .4rem; }
.g-btn { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--accent); background: transparent; color: var(--ink); font-size: 1.5rem; line-height: 1; cursor: pointer; display: grid; place-items: center; }
[dir="rtl"] .g-btn span { display: inline-block; transform: scaleX(-1); }
.g-dots { display: flex; gap: .4rem; }
.g-dots i { width: 7px; height: 7px; border-radius: 50%; background: color-mix(in srgb, var(--ink) 25%, transparent); transition: background .3s, transform .3s; }
.g-dots i.on { background: var(--accent); transform: scale(1.3); }
.gallery.single .g-nav { display: none; }
.no-intro .g-slide { transition: none; }

/* ---------- "Our story": polaroids of them when young ---------- */
.story h2, .schedule h2 { font-family: var(--name-font); font-weight: 400; font-size: 2.2rem; margin: 0 0 .8rem; color: var(--accent); }
.story-pics { display: flex; justify-content: center; align-items: flex-start; gap: 1rem; margin: .8rem 0 1.6rem; perspective: 900px; }
.polaroid { --r: -4deg; --d: 0s; position: relative; margin: 0; width: 46%; max-width: 190px; padding: 10px 10px 38px; background: #fffdf8; box-shadow: 0 14px 30px rgba(0, 0, 0, .22); transform: rotate(var(--r)); transition: transform 1s cubic-bezier(.2, .8, .2, 1) var(--d), opacity .8s ease var(--d); cursor: default; }
.polaroid.p2 { --r: 5deg; --d: .25s; margin-top: 1.6rem; }
.story-pics[data-count="1"] .polaroid { width: 62%; --r: -3deg; }
.polaroid::before { content: ""; position: absolute; top: -11px; left: 50%; width: 64px; height: 22px; margin-left: -32px; background: color-mix(in srgb, var(--accent) 35%, rgba(255, 255, 255, .7)); transform: rotate(-4deg); opacity: .9; }
.polaroid:hover { transform: rotate(0deg) scale(1.05); z-index: 2; }
.pol-img { aspect-ratio: 4 / 5; overflow: hidden; background: var(--soft); color: var(--accent); }
.pol-img img, .pol-img svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.pol-img img { filter: sepia(.18) saturate(.95); }
.polaroid figcaption { position: absolute; inset-inline: 0; bottom: 6px; font-family: var(--name-font); font-size: 1.25rem; color: #3a2e2a; text-align: center; }
.story-text { margin: 0 0 2.2rem; padding: 0 .5rem; font-size: 1.12rem; white-space: pre-line; }
.opened:not(.no-intro) .story:not(.in) .polaroid { opacity: 0; transform: perspective(700px) rotateY(75deg) translateY(30px); }
.pol-img [class*="a-"] { transform-box: view-box; }
.pol-img .a-sway { animation: sway 4.6s ease-in-out infinite; }
.pol-img .a-twinkle { animation: twinkle-svg 2.4s ease-in-out infinite; }

/* ---------- Programme of the night (timeline) ---------- */
.schedule { margin: 0 0 2.2rem; }
.tl { list-style: none; margin: 0; padding: 0; padding-inline-start: 1.8rem; position: relative; text-align: start; }
.tl::before { content: ""; position: absolute; inset-block: .9rem; inset-inline-start: .5rem; width: 2px; border-radius: 2px; background: linear-gradient(var(--accent), color-mix(in srgb, var(--accent) 25%, transparent)); transform-origin: top; transition: transform 1.6s ease .2s; }
.tl-item { position: relative; display: grid; grid-template-columns: 5.4rem 1fr; gap: .8rem; align-items: baseline; padding: .7rem 0; transition: opacity .7s ease, transform .7s cubic-bezier(.2, .8, .2, 1); }
.tl-dot { position: absolute; top: 1.05rem; inset-inline-start: calc(-1.8rem + .5rem + 1px - 7px); width: 14px; height: 14px; border-radius: 50%; background: var(--bg); border: 3px solid var(--accent); }
.tl-time { font-family: var(--ui-font); font-weight: 700; color: var(--accent); white-space: nowrap; }
.tl-body b { display: block; font-size: 1.15rem; }
.tl-body span { display: block; opacity: .8; font-size: .98rem; }
.opened:not(.no-intro) .schedule:not(.in) .tl::before { transform: scaleY(0); }
.opened:not(.no-intro) .schedule:not(.in) .tl-item { opacity: 0; transform: translateY(16px); }
.schedule.in .tl-item:nth-child(2) { transition-delay: .25s; }
.schedule.in .tl-item:nth-child(3) { transition-delay: .5s; }
.schedule.in .tl-item:nth-child(4) { transition-delay: .75s; }
.schedule.in .tl-item:nth-child(5) { transition-delay: 1s; }
.schedule.in .tl-item:nth-child(n+6) { transition-delay: 1.2s; }
.opened:not(.no-intro) .schedule.in .tl-dot { animation: dot-pop 2.8s ease-in-out 1.4s infinite; }
@keyframes dot-pop { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); } 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 0%, transparent); } }

/* ==========================================================
   Opening ritual 2: CAP TOSS (template "ramya")
   A 3D graduation cap floats; swipe up / tap and it spins into
   the sky while six more caps launch up behind it.
   ========================================================== */
.intro-hint { margin: 0; font: 600 .95rem var(--ui-font); opacity: .75; text-align: center; animation: intro-in 1s ease .6s both; transition: opacity .3s; }
.opening .intro-hint { opacity: 0; }
.cap-scene { position: relative; width: min(300px, 78vw); aspect-ratio: 1; perspective: 900px; cursor: grab; margin-top: 2rem; touch-action: none; }
.cap-scene .env-tilt { position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateX(var(--rx, 10deg)) rotateY(var(--ry, 0deg)); transition: transform .35s ease-out; }
/* The cap is drawn as ONE flat piece (board painted over the skullcap) and the
   whole piece tilts/flies in 3D. Separate 3D layers sliced through each other. */
.cap3d { position: absolute; inset: 14% 10% 22%; animation: cap-float 4.6s ease-in-out infinite; }
.cap-board { position: absolute; left: 50%; top: 38%; width: 70%; aspect-ratio: 1; margin-left: -35%; transform: translateY(-50%) scaleY(.46) rotate(45deg); background: linear-gradient(135deg, color-mix(in srgb, var(--bg) 55%, #000) 0%, color-mix(in srgb, var(--bg) 35%, #000) 100%); border-radius: 6px; box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 70%, transparent), 0 18px 30px rgba(0, 0, 0, .45); display: grid; place-items: center; }
.cap-board::after { content: ""; position: absolute; left: 50%; top: 50%; width: 12%; height: 12%; margin: -6% 0 0 -6%; border-radius: 50%; background: var(--accent); box-shadow: 0 2px 4px rgba(0, 0, 0, .4); }
.cap-year { display: none; }
.cap-skull { position: absolute; left: 50%; top: 44%; width: 56%; height: 30%; margin-left: -28%; border-radius: 10% 10% 50% 50% / 10% 10% 60% 60%; background: linear-gradient(180deg, color-mix(in srgb, var(--bg) 40%, #000), color-mix(in srgb, var(--bg) 25%, #000)); box-shadow: inset 0 -10px 20px rgba(0, 0, 0, .35), 0 12px 24px rgba(0, 0, 0, .35); }
.cap-tassel { position: absolute; left: 50%; top: 38%; width: 46%; height: 2px; transform-origin: 0 50%; transform: rotate(18deg); background: var(--accent); }
.cap-tassel i { position: absolute; right: -4px; top: 0; width: 3px; height: 70px; background: var(--accent); transform-origin: top; animation: tassel-swing 2.2s ease-in-out infinite; }
.cap-tassel i::after { content: ""; position: absolute; left: -6px; bottom: -16px; width: 15px; height: 20px; border-radius: 3px 3px 7px 7px; background: repeating-linear-gradient(90deg, var(--accent) 0 2px, color-mix(in srgb, var(--accent) 70%, #000) 2px 3px); }
.mini-cap { position: absolute; left: 50%; bottom: -10%; width: 54px; height: 20px; margin-left: -27px; opacity: 0; background: var(--ink); border-radius: 3px; box-shadow: 0 0 0 2px var(--accent), 0 6px 14px rgba(0, 0, 0, .35); transform: rotateX(60deg); }
.mini-cap::after { content: ""; position: absolute; right: 2px; top: 50%; width: 2px; height: 16px; background: var(--accent); }
.opening .intro-captoss .cap3d { animation: cap-toss 1.5s cubic-bezier(.25, .7, .3, 1) forwards; }
.opening .intro-captoss .env-shadow { opacity: 0; transition: opacity .4s; }
.opening .intro-captoss .mini-cap { animation: mini-fly 2.4s cubic-bezier(.35, .55, .45, 1) forwards; }
.mini-cap.m1 { --tx: -140px; --rz: -260deg; animation-delay: .1s !important; }
.mini-cap.m2 { --tx: 130px; --rz: 300deg; animation-delay: .2s !important; }
.mini-cap.m3 { --tx: -60px; --rz: 200deg; animation-delay: .3s !important; }
.mini-cap.m4 { --tx: 80px; --rz: -220deg; animation-delay: .15s !important; }
.mini-cap.m5 { --tx: -190px; --rz: 340deg; animation-delay: .35s !important; }
.mini-cap.m6 { --tx: 190px; --rz: -300deg; animation-delay: .25s !important; }
@keyframes cap-float { 0%, 100% { transform: translateY(0) rotateZ(-3deg); } 50% { transform: translateY(-12px) rotateZ(3deg); } }
@keyframes cap-toss { 0% { transform: translateY(0) rotateZ(0); } 25% { transform: translateY(14px) scale(.96); } 100% { transform: translateY(-140vh) rotateZ(-540deg) rotateX(180deg) scale(1.15); } }
@keyframes mini-fly { 0% { opacity: 0; transform: translate(0, 0) rotateX(60deg) rotateZ(0); } 15% { opacity: 1; } 100% { opacity: .9; transform: translate(var(--tx), -120vh) rotateX(60deg) rotateZ(var(--rz)); } }
@keyframes tassel-swing { 0%, 100% { transform: rotate(-8deg); } 50% { transform: rotate(8deg); } }

/* Cap Toss — invitation look */
.tpl-ramya .card { background: radial-gradient(ellipse at 50% 0, var(--soft), var(--bg) 62%); }
.tpl-ramya .cover { padding-top: 11rem; }
.tpl-ramya .names { color: var(--accent); font-weight: 700; font-size: clamp(2.4rem, 11vw, 3.1rem); text-shadow: 0 4px 22px color-mix(in srgb, var(--accent) 35%, transparent); }
.tpl-ramya .class-of { display: inline-block; background: var(--accent); color: var(--bg); padding: .25rem 1rem; border-radius: 999px; }
.tpl-ramya .detail { background: color-mix(in srgb, var(--soft) 85%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); }
.tpl-ramya .btn { color: var(--bg); }
.tpl-ramya .btn.ghost { color: var(--ink); }
.tpl-ramya .rsvp input, .tpl-ramya .rsvp select, .tpl-ramya .rsvp textarea, .tpl-ramya .rsvp .choice label { background: color-mix(in srgb, var(--bg) 70%, black); }

/* ==========================================================
   Opening ritual 3: NIGHT SKY (template "samaa")
   Guests tap 5 stars; lines join them into a graduation-cap
   constellation; then fireworks reveal the invitation.
   ========================================================== */
.intro-sky { background: radial-gradient(ellipse at 50% 100%, var(--soft), var(--bg) 65%), var(--bg); }
.intro-sky::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .8; background-image:
  radial-gradient(1.2px 1.2px at 12% 18%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 28% 72%, #fff 50%, transparent 51%),
  radial-gradient(1.4px 1.4px at 44% 12%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 63% 84%, #fff 50%, transparent 51%),
  radial-gradient(1.2px 1.2px at 78% 22%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 90% 58%, #fff 50%, transparent 51%),
  radial-gradient(1px 1px at 8% 88%, #fff 50%, transparent 51%), radial-gradient(1.3px 1.3px at 55% 46%, #fff 50%, transparent 51%),
  radial-gradient(1px 1px at 34% 36%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 70% 64%, #fff 50%, transparent 51%);
  animation: sky-twinkle 4s ease-in-out infinite alternate; }
@keyframes sky-twinkle { to { opacity: .45; } }
.sky-scene { position: relative; width: min(340px, 86vw); aspect-ratio: 1.1; margin-top: 1rem; }
.sky-lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.sky-lines line { stroke: var(--accent); stroke-width: .5; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset .7s ease; filter: drop-shadow(0 0 1.5px var(--accent)); }
.sky-lines line.on { stroke-dashoffset: 0; }
.sky-star { position: absolute; width: 52px; height: 52px; margin: -26px 0 0 -26px; display: grid; place-items: center; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.sky-star i { width: 12px; height: 12px; border-radius: 50%; background: color-mix(in srgb, var(--ink) 75%, transparent); box-shadow: 0 0 10px 2px color-mix(in srgb, var(--ink) 40%, transparent); animation: star-call 1.8s ease-in-out infinite; transition: transform .4s cubic-bezier(.3, 1.6, .5, 1), background .3s, box-shadow .3s; }
.sky-star:nth-child(3) i { animation-delay: .3s; } .sky-star:nth-child(4) i { animation-delay: .6s; } .sky-star:nth-child(5) i { animation-delay: .9s; } .sky-star:nth-child(6) i { animation-delay: 1.2s; }
.sky-star.lit i { animation: none; transform: scale(1.7); background: var(--accent); box-shadow: 0 0 18px 6px color-mix(in srgb, var(--accent) 70%, transparent); clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); border-radius: 0; }
.sky-scene.complete .sky-lines line { stroke-width: .9; filter: drop-shadow(0 0 3px var(--accent)); }
.sky-scene.complete .sky-star.lit i { transform: scale(2.1); }
@keyframes star-call { 0%, 100% { transform: scale(1); opacity: .7; } 50% { transform: scale(1.5); opacity: 1; } }
.firework { position: absolute; left: var(--fx); top: var(--fy); width: 7px; height: 7px; margin: -3.5px; border-radius: 50%; opacity: 0; color: var(--accent); filter: drop-shadow(0 0 4px currentColor) drop-shadow(0 0 8px currentColor); }
.firework.f1 { --fx: 22%; --fy: 20%; } .firework.f2 { --fx: 78%; --fy: 14%; color: var(--ink); } .firework.f3 { --fx: 50%; --fy: 6%; } .firework.f4 { --fx: 12%; --fy: 64%; color: var(--ink); } .firework.f5 { --fx: 88%; --fy: 60%; }
.opening .intro-sky .firework { animation: firework 1.4s ease-out forwards; }
.opening .intro-sky .firework.f2 { animation-delay: .25s; } .opening .intro-sky .firework.f3 { animation-delay: .5s; } .opening .intro-sky .firework.f4 { animation-delay: .7s; } .opening .intro-sky .firework.f5 { animation-delay: .9s; }
@keyframes firework {
  0% { opacity: 1; box-shadow: 0 0 currentColor; transform: scale(.4); }
  60% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.15); box-shadow: 0 -90px currentColor, 64px -64px currentColor, 90px 0 currentColor, 64px 64px currentColor, 0 90px currentColor, -64px 64px currentColor, -90px 0 currentColor, -64px -64px currentColor, 34px -84px currentColor, 84px 34px currentColor, -34px 84px currentColor, -84px -34px currentColor, 0 -45px currentColor, 45px 0 currentColor, 0 45px currentColor, -45px 0 currentColor; }
}
.opening .intro-sky .sky-scene { transition: transform 1.2s ease .3s, opacity 1s ease .6s; transform: scale(1.3) translateY(-10%); opacity: 0; }

/* Night Sky — invitation look */
.tpl-samaa .card { background: radial-gradient(ellipse at 50% 110%, var(--soft), var(--bg) 60%); }
.tpl-samaa .cover { padding-top: 12rem; }
.tpl-samaa .names { color: var(--ink); font-weight: 700; text-shadow: 0 0 18px color-mix(in srgb, var(--accent) 55%, transparent), 0 0 2px var(--accent); }
.tpl-samaa .class-of, .tpl-samaa .degree { color: var(--accent); }
.tpl-samaa .detail { background: color-mix(in srgb, var(--soft) 80%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); backdrop-filter: blur(2px); }
.tpl-samaa .btn { color: var(--bg); }
.tpl-samaa .btn.ghost { color: var(--ink); }
.tpl-samaa .rsvp input, .tpl-samaa .rsvp select, .tpl-samaa .rsvp textarea, .tpl-samaa .rsvp .choice label { background: color-mix(in srgb, var(--bg) 70%, black); }
.orn .a-shoot { opacity: 0; } /* invisible until it streaks */
.opened:not(.no-intro) .orn .a-shoot { animation: shoot 7s ease-in 2s infinite; }
@keyframes shoot { 0%, 80% { transform: translate(0, 0); opacity: 0; } 82% { opacity: 1; } 92% { transform: translate(90px, -34px); opacity: 0; } 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } .burst, .ambient, .spark, .spark-ring { display: none; } }

/* ---------- Template: Noor (arch) ---------- */
.tpl-noor .cover { padding-top: 7.5rem; }
.tpl-noor .orn { height: 560px; aspect-ratio: auto; }

/* ---------- Template: Yasmeen (jasmine) ---------- */
.tpl-yasmeen .orn { opacity: .95; }
.tpl-yasmeen .names { color: var(--accent); }
.tpl-yasmeen .names .amp { color: var(--ink); }
.tpl-yasmeen .photo img { border-radius: 18px; }

/* ---------- Template: Layali (night) ---------- */
body.inv.tpl-layali { --name-font: 'Cormorant Garamond', serif; }
body.inv.tpl-layali.lang-ar { --name-font: 'Aref Ruqaa', serif; }
.tpl-layali .names { color: var(--accent); font-weight: 600; font-style: italic; }
.tpl-layali.lang-ar .names { font-style: normal; font-weight: 700; }
.tpl-layali .card { background: radial-gradient(ellipse at 50% 0, var(--soft), var(--bg) 60%); }
.tpl-layali .cover { padding-top: 9rem; }
.tpl-layali .detail { background: color-mix(in srgb, var(--soft) 85%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); }
.tpl-layali .btn { color: var(--bg); }
.tpl-layali .btn.ghost { color: var(--ink); }
.tpl-layali .rsvp input, .tpl-layali .rsvp select, .tpl-layali .rsvp textarea, .tpl-layali .rsvp .choice label { background: color-mix(in srgb, var(--bg) 70%, black); }

/* ---------- Template: Ward (roses) ---------- */
.tpl-ward .names { color: var(--accent); }
.tpl-ward .host-line { font-style: italic; }
.tpl-ward .detail { background: transparent; border: 1px solid var(--accent); }

/* ---------- Template: Ghar / Laurel (graduation) ---------- */
body.inv.tpl-ghar { --name-font: 'Cormorant Garamond', serif; }
body.inv.tpl-ghar.lang-ar { --name-font: 'Amiri', serif; }
.tpl-ghar .cover { min-height: 640px; padding-top: 6.5rem; }
.tpl-ghar .cover > * { max-width: 60%; }
.tpl-ghar .names { font-weight: 700; font-size: clamp(2.1rem, 9vw, 2.7rem); max-width: 15ch; }
.tpl-ghar .host-line { max-width: 18ch; }
.tpl-ghar .date-short { border: 0; }

/* ---------- Template: Dofaa / Class Of (graduation) ---------- */
body.inv.tpl-dofaa { --name-font: 'Poppins', 'Tajawal', sans-serif; --body-font: 'Poppins', 'Tajawal', sans-serif; font-size: 16px; }
body.inv.tpl-dofaa.lang-ar { --name-font: 'Tajawal', sans-serif; --body-font: 'Tajawal', sans-serif; }
.tpl-dofaa .cover { align-items: flex-start; text-align: start; padding-top: 12rem; }
.tpl-dofaa .names { font-weight: 800; text-transform: uppercase; line-height: 1; letter-spacing: -.01em; align-items: flex-start; font-size: clamp(2.6rem, 13vw, 3.4rem); }
.tpl-dofaa .class-of { order: -1; font-size: 1rem; background: var(--accent); color: var(--bg); padding: .2rem .8rem; border-radius: 6px; margin: 0 0 1rem; }
.tpl-dofaa .degree { font-weight: 600; }
.tpl-dofaa .date-short { border: 0; padding: 0; color: var(--accent); font-weight: 700; }
.tpl-dofaa .detail { background: var(--soft); border-inline-start: 4px solid var(--accent); border-radius: 8px; text-align: start; }
.tpl-dofaa .countdown div { border-radius: 8px; }
.tpl-dofaa .rsvp { border-radius: 10px; }
.tpl-dofaa .rsvp h2 { font-weight: 800; font-size: 1.8rem; text-transform: uppercase; }
.tpl-dofaa .photo img { border-radius: 10px; box-shadow: 10px 10px 0 var(--accent); }
.tpl-dofaa .rsvp input, .tpl-dofaa .rsvp select, .tpl-dofaa .rsvp textarea, .tpl-dofaa .rsvp .choice label { background: var(--bg); }
