/* latin-ext */
@font-face {
  font-family: 'Great Vibes';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/theme-assets/_fonts/great-vibes-400-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Great Vibes';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/theme-assets/_fonts/great-vibes-400-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* arabic */
@font-face {
  font-family: 'Aref Ruqaa';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/theme-assets/_fonts/aref-ruqaa-400-arabic.woff2) format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* arabic */
@font-face {
  font-family: 'Aref Ruqaa';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/theme-assets/_fonts/aref-ruqaa-700-arabic.woff2) format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}

/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url(/theme-assets/_fonts/cormorant-garamond-500i-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url(/theme-assets/_fonts/cormorant-garamond-500i-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url(/theme-assets/_fonts/cormorant-garamond-600i-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url(/theme-assets/_fonts/cormorant-garamond-600i-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/theme-assets/_fonts/cormorant-garamond-500-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/theme-assets/_fonts/cormorant-garamond-500-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/theme-assets/_fonts/cormorant-garamond-600-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/theme-assets/_fonts/cormorant-garamond-600-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* arabic */
@font-face {
  font-family: 'Amiri';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/theme-assets/_fonts/amiri-400-arabic.woff2) format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* arabic */
@font-face {
  font-family: 'Amiri';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/theme-assets/_fonts/amiri-700-arabic.woff2) format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}

/* arabic */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/theme-assets/_fonts/tajawal-400-arabic.woff2) format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/theme-assets/_fonts/tajawal-400-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* arabic */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/theme-assets/_fonts/tajawal-500-arabic.woff2) format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/theme-assets/_fonts/tajawal-500-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* arabic */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/theme-assets/_fonts/tajawal-700-arabic.woff2) format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/theme-assets/_fonts/tajawal-700-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* arabic */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(/theme-assets/_fonts/tajawal-800-arabic.woff2) format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin */
@font-face {
  font-family: 'Tajawal';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(/theme-assets/_fonts/tajawal-800-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/*
 * Invitation engine: structure shared by every theme (from the reference prototype).
 * The <html> element carries the theme code as a class (e.g. "royal"); each theme's styles.css
 * sets the tokens below and skins the blocks under that class.
 */

:root {
  color-scheme: light;
  --bg: #F4F2EE; --bg-hi: #FFFFFF; --surface: #FFFFFF;
  --ink: #26241F; --muted: #625D53; --line: #DDD6C8; --hi: #FFFFFF;
  --accent: #6B5530; --link: #6B5530;
  --shadow: rgba(40, 30, 10, .12);
  --gold-1: var(--accent); --gold-2: var(--accent); --gold-3: var(--line); --gold-4: var(--line);
  --gold: var(--accent);
  --c1: #FF5A5F; --c2: #FFC531; --c3: #2EC4B6; --c4: #7B5CFA; --c5: #FF8FB1;
  --font-display-ar: serif;
  --font-display-lat: serif;
  --font-text-ar: serif;
  --font-text-lat: serif;
  --font-ui: system-ui, sans-serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
/* Names can be long and sit in boxes sized by their content, where only "anywhere" lets them wrap. */
.name, .names, .gate-names, .nameplate { overflow-wrap: anywhere; max-inline-size: 100%; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 8px;
  overflow-wrap: break-word; /* long names never leave their frame; "anywhere" would also let countdown cells shrink and cut their labels */
  hyphens: auto; /* follows the language of the html element */
  background-color: var(--bg);
  background-image: radial-gradient(ellipse at 50% 28%, var(--bg-hi), var(--bg) 72%);
  background-attachment: fixed;
  color: var(--ink); font-family: var(--font-ui); font-size: 16px; line-height: 1.7;
  padding-inline: 32px; padding-block: 36px 96px; overflow-x: clip;
}
body.has-bar { padding-block-end: 150px; }
body.locked { overflow: hidden; }
:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 3px; }

.svg-defs { position: absolute; width: 0; height: 0; }
.wrap { max-width: 520px; margin-inline: auto; display: flex; flex-direction: column; gap: 56px; position: relative; }
section, header { position: relative; z-index: 1; }
h2 { margin: 0; text-wrap: balance; }
.lattice { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; }
#sparkle { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2; }

/* SVG colour utilities (the CSP forbids inline style attributes) */
.f-c1 { fill: var(--c1); } .f-c2 { fill: var(--c2); } .f-c3 { fill: var(--c3); } .f-c4 { fill: var(--c4); } .f-c5 { fill: var(--c5); }
.f-ink { fill: var(--ink); }
.s-ink { stroke: var(--ink); } .s-c1 { stroke: var(--c1); } .s-c3 { stroke: var(--c3); } .s-c4 { stroke: var(--c4); }
.s-hi { stroke: var(--hi); } .s-line { stroke: var(--line); }

/* ---------- shared structure ---------- */
.topbar { display: flex; justify-content: flex-end; }
.lang { font: 500 14px var(--font-ui); border-radius: 999px; padding: 6px 16px; cursor: pointer; text-decoration: none; }
.hero { display: flex; flex-direction: column; align-items: center; gap: 24px; text-align: center; }
.hero > * { position: relative; z-index: 1; }
.name, h2, .sign, .day, .gate-names { font-family: var(--font-display-ar); }
:root[lang="fr"] .name, :root[lang="fr"] h2, :root[lang="fr"] .sign, :root[lang="fr"] .gate-names { font-family: var(--font-display-lat); }
.tagline, .close p, .msg { font-family: var(--font-text-ar); }
:root[lang="fr"] .tagline, :root[lang="fr"] .close p, :root[lang="fr"] .msg { font-family: var(--font-text-lat); }
.date { display: flex; flex-direction: column; align-items: center; gap: 28px; text-align: center; }
.datecard { display: flex; align-items: center; gap: 20px; direction: ltr; }
.dmeta { display: flex; flex-direction: column; gap: 2px; text-align: start; padding-inline-start: 18px; position: relative; }
.count { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; width: 100%; direction: ltr; }
.cell { display: flex; flex-direction: column; align-items: center; min-width: 0; padding: 14px 4px 10px; }
.cell b { font-variant-numeric: tabular-nums; line-height: 1.1; }
.cell span { font-size: 13px; }
.done { grid-column: 1 / -1; text-align: center; font-size: 20px; }
.program { display: flex; flex-direction: column; gap: 22px; }
.program h2 { text-align: center; }
.events { display: flex; flex-direction: column; }
.ev { display: grid; grid-template-columns: 76px 1fr; gap: 18px; padding-block: 18px; align-items: center; position: relative; }
.ev-d { display: flex; flex-direction: column; align-items: center; line-height: 1.1; direction: ltr; }
.ev-b { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ev-b h3 { margin: 0; font: 700 18px var(--font-ui); }
.where { color: var(--muted); font-size: 15px; }
.maps { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 6px; }
.maplink { align-self: flex-start; font-size: 14px; font-weight: 500; color: var(--link); text-decoration: underline; text-underline-offset: 4px; }
.venue { display: flex; flex-direction: column; align-items: center; gap: 0; }
.venue .maps { justify-content: center; margin-top: 0; }
.message { text-align: center; }
.message .msg { margin: 0; font-size: 20px; line-height: 1.6; white-space: pre-line; }
.dresscode { text-align: center; display: flex; flex-direction: column; gap: 4px; }
.dresscode small { font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.photo { display: flex; justify-content: center; }
.photo-frame { width: min(100%, 360px); }
.photo img { display: block; width: 100%; height: auto; }
.transport { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 16px; }
.transport-details { margin: 0; max-width: 34ch; white-space: pre-line; }
.close { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.close p { margin: 0; max-width: 30ch; color: var(--muted); font-size: 21px; }
.divider { display: flex; justify-content: center; margin-block: -24px; position: relative; z-index: 1; }
.divider svg { width: min(280px, 80%); height: 28px; }

/* ---------- intro gate ---------- */
.gate { position: fixed; inset: 0; z-index: 20; display: none; place-items: center; overflow: hidden; background: radial-gradient(ellipse at 50% 40%, var(--bg-hi), var(--bg) 75%); }
.js .gate { display: grid; }
.js.gate-skip .gate { display: none; }
/* While the intro covers the screen, the invitation is laid out only after page load, so its fonts
   do not compete with the intro's first paint; they download while the guest looks at the intro. */
.js:not(.gate-skip):not(.app-ready) #app { display: none; }
.gate-in { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 22px; text-align: center; padding: 16px; }
.gate-kicker { font-size: 13px; letter-spacing: .3em; text-transform: uppercase; color: var(--muted); }
.gate-names { font-weight: 600; font-size: 40px; line-height: 1.15; }
.gate-hint { font-size: 14px; letter-spacing: .12em; color: var(--gold-1); }
.gate-btn { border: 0; padding: 0; background: none; cursor: pointer; border-radius: 50%; }
.gate.open .gate-in { opacity: 0; transform: scale(.92); }

/* ---------- embedded demo (home page): no scrollbar, it scrolls by itself ---------- */
:root.embed, :root.still { scrollbar-width: none; }
:root.embed::-webkit-scrollbar, :root.embed body::-webkit-scrollbar, :root.still::-webkit-scrollbar { display: none; }

/* ---------- demo chrome ---------- */
.bar { position: fixed; z-index: 30; left: 50%; transform: translateX(-50%); bottom: calc(14px + env(safe-area-inset-bottom, 0px)); display: flex; align-items: center; gap: 6px; padding: 6px; border-radius: 999px; background: rgba(24, 20, 34, .9); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); box-shadow: 0 10px 30px rgba(0,0,0,.25); max-width: calc(100% - 24px); font-family: var(--font-ui); }
.bar span { font: 700 14px var(--font-ui); padding: 9px 14px; color: #E9E4F2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar a { font: 700 14px var(--font-ui); border-radius: 999px; padding: 9px 16px; background: #F1DDA0; color: #2A2010; white-space: nowrap; text-decoration: none; }
.bar :focus-visible { outline: 2px solid #F1DDA0; outline-offset: 2px; }

@media (max-width: 380px) {
  body { padding-inline: 20px; }
}

@media (prefers-reduced-motion: no-preference) {
  .gate-in { transition: opacity .5s ease, transform .6s ease; }
  .reveal .hero > :not(.balloon) { animation: rise .9s cubic-bezier(.2,.7,.2,1) both; }
  .reveal .hero > *:nth-child(2) { animation-delay: .12s; }
  .reveal .hero > *:nth-child(3) { animation-delay: .24s; }
  .reveal .hero > *:nth-child(4) { animation-delay: .36s; }
  .reveal .hero > *:nth-child(5) { animation-delay: .48s; }
  @keyframes rise { from { opacity: .001; transform: translateY(18px); } }
}

/* ---------- published page ---------- */
.calendar-link { align-self: center; }
/* "Created with" signature (SIG-01): small, no background, frame or animation; a theme may tune --brand-sig-color and
   --brand-sig-font (contrast >= 4.5:1 on its background), never remove it. 44 px high touch target. */
.signature { position: relative; z-index: 1; display: flex; justify-content: center; padding-block: 8px; }
.brand-sig { margin: 0; text-align: center; }
.brand-sig__link { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-block-size: 44px; padding-inline: 10px;
  color: var(--brand-sig-color, var(--muted)); font: 500 12px/1.3 var(--brand-sig-font, var(--font-ui)); text-decoration: none; }
.brand-sig__link:hover span, .brand-sig__link:focus-visible span { text-decoration: underline; }
.brand-sig__mark { inline-size: 16px; block-size: 16px; flex: none; }
/* RSVP thank-you (SIG-04): a separate, quieter line under the confirmation. */
.brand-sig-cta { margin: 8px 0 0; padding-block-start: 12px; border-block-start: 1px solid var(--line); color: var(--brand-sig-color, var(--muted));
  font: 400 13px/1.5 var(--brand-sig-font, var(--font-ui)); text-align: center; }
.brand-sig-cta a { display: inline-block; min-block-size: 44px; line-height: 44px; color: inherit; font-weight: 600; text-decoration: underline; }

/* ---------- guests & RSVP (PRD F-05, F-06) ---------- */
.guest-greeting { margin: 0; text-align: center; font-family: var(--font-text-ar); font-size: 22px; color: var(--accent); }
:root[lang="fr"] .guest-greeting { font-family: var(--font-text-lat); }
.rsvp { display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center; }
.rsvp-note, .rsvp-saved { margin: 0; color: var(--muted); }
.rsvp-saved { color: var(--accent); font-weight: 700; }
.rsvp-errors { margin: 0; padding: 12px 16px; list-style: none; border-radius: 12px; background: #fdecec; color: #8a1c1c; text-align: start; }
.rsvp-form { width: 100%; min-inline-size: 0; }
.rsvp-form *, .rsvp-form *::before, .rsvp-form *::after { box-sizing: border-box; }
/* min-inline-size: a fieldset otherwise refuses to be narrower than its content, and pushes the form off the screen. */
.rsvp-form > fieldset { display: flex; flex-direction: column; gap: 14px; margin: 0; padding: 20px; min-inline-size: 0; border: 1px solid var(--line); border-radius: 16px; background: var(--surface); text-align: start; }
.rsvp-form > fieldset:disabled { opacity: .75; }
/* Side by side when they fit, one under the other otherwise. */
.rsvp-choice { display: flex; flex-wrap: wrap; gap: 10px; }
.choice-pill { flex: 1 1 7.5rem; min-inline-size: 0; position: relative; display: flex; align-items: center; justify-content: center; padding: 12px 8px; border: 1.5px solid var(--line); border-radius: 999px; font-weight: 700; text-align: center; cursor: pointer; }
.choice-pill input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.choice-pill:has(input:checked) { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.choice-pill:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }
.rsvp-field { min-inline-size: 0; display: flex; flex-direction: column; gap: 6px; font-weight: 600; font-size: 15px; }
.rsvp-field small { font-weight: 400; color: var(--muted); }
.rsvp-field input, .rsvp-field textarea { width: 100%; max-inline-size: 100%; min-inline-size: 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--hi); color: var(--ink); font: 400 16px var(--font-ui); }
.rsvp-steps { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: 6px; }
.rsvp-steps legend { font-weight: 600; font-size: 15px; margin-bottom: 4px; }
.rsvp-check { display: flex; align-items: center; gap: 8px; }
.rsvp-check input { width: 18px; height: 18px; accent-color: var(--accent); }
/* Not coming: no party size nor steps to fill in. */
.rsvp-form:has(input[name="attending"][value="no"]:checked) :is(.rsvp-people, .rsvp-steps) { display: none; }
.rsvp-hp { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.rsvp-submit { max-inline-size: 100%; white-space: normal; padding: 14px 20px; border: 0; border-radius: 999px; background: var(--accent); color: var(--surface); font: 700 16px var(--font-ui); cursor: pointer; }
.rsvp-submit:disabled { cursor: not-allowed; }

/* Guests' photo album (Blocks/Album.cshtml): same form look as the RSVP, a progress line while the photos are sent. */
.album { display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center; }
.album-form input[type="file"] { padding: 10px 0; font: 400 15px var(--font-ui); color: var(--ink); }
.album-progress { width: 100%; height: 8px; accent-color: var(--accent); }
.album-status:empty { display: none; }
.album-problem { color: #8a1c1c; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Sound button of the published invitation (background music, never autoplay). */
.sound { position: fixed; inset-block-end: 16px; inset-inline-end: 16px; z-index: 40; inline-size: 44px; block-size: 44px;
  display: grid; place-items: center; border-radius: 50%; border: 1px solid currentColor; background: rgb(0 0 0 / .45); color: #fff; cursor: pointer; }
.sound svg { inline-size: 22px; block-size: 22px; }
.sound[aria-pressed="false"]::after { content: ""; position: absolute; inline-size: 26px; block-size: 2px; background: currentColor; transform: rotate(-45deg); }
.sound:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.sound[hidden] { display: none; }

/* Private preview: switch between the desktop page and the phone frame (pointless on a phone). */
.bar a.bar-view { background: transparent; color: #E9E4F2; box-shadow: inset 0 0 0 1px rgba(233, 228, 242, .35); }
.bar a.bar-view[aria-current="true"] { background: rgba(233, 228, 242, .22); color: #fff; }
@media (max-width: 599px) { .bar a.bar-view { display: none; } }
/* Showcase bar: the consent line stays whole (it names the people who agreed), on two lines if needed. */
.bar--showcase { border-radius: 22px; width: max-content; }
.bar--showcase span { white-space: normal; font-weight: 600; font-size: 13px; line-height: 1.35; padding-block: 6px; padding-inline: 12px 6px; }

/* Inside the phone frame of the private preview: scrolling works, but no desktop scrollbar on a phone screen. */
html.framed { scrollbar-width: none; }
html.framed::-webkit-scrollbar { display: none; }

/* Handwriting style of the names chosen in the editor (InvitationContent.NamesFont). Latin text only: Arabic names keep the theme's Arabic font. */
html.names-allura { --names-font: "Allura"; }
html.names-great-vibes { --names-font: "Great Vibes"; }
html.names-pinyon-script { --names-font: "Pinyon Script"; }
html.names-parisienne { --names-font: "Parisienne"; }
html.names-custom:lang(fr) :is(.name, .gate-names, .sign) {
  font-family: var(--names-font), "Cormorant Garamond", cursive !important;
  font-style: normal !important; font-weight: 400 !important; letter-spacing: normal !important; text-transform: none !important;
}

/* Calligraphy style of the Arabic names (InvitationContent.NamesFontAr). */
html.names-ar-scheherazade-new { --names-ar-font: "Scheherazade New"; --names-ar-weight: 700; }
html.names-ar-noto-nastaliq-urdu { --names-ar-font: "Noto Nastaliq Urdu"; --names-ar-weight: 600 }
html.names-ar-lemonada { --names-ar-font: "Lemonada"; --names-ar-weight: 600; }
html.names-ar-mirza { --names-ar-font: "Mirza"; --names-ar-weight: 700; }
html.names-ar-aref-ruqaa { --names-ar-font: "Aref Ruqaa"; --names-ar-weight: 700; }
html.names-ar-noto-nastaliq-urdu:lang(ar) :is(.name, .gate-names, .sign) { line-height: 2.1 !important; }
html.names-ar-custom:lang(ar) :is(.name, .gate-names, .sign) {
  font-family: var(--names-ar-font), "Amiri", serif !important;
  font-style: normal !important; font-weight: var(--names-ar-weight, 700) !important; letter-spacing: normal !important;
}

/* ---------- opening video, shared (_engine/IntroVideo.cshtml + _engine/PhotoHero.cshtml) ----------
   For a theme whose Intro and Hero blocks render these partials when theme.json has "introVideo". The theme only sets, on :root.{code}:
   --hit-w, --hit-h, --hit-y, --hit-r  the object to touch in the video's 720×1280 first frame (size, centre below the middle, radius)
   --shot                              url() of the video's last frame (img/video-end-*.webp): the picture behind the names
   --veil, --text-top                  what keeps the names readable over that picture, and where they sit
   --text-delay                        video seconds + 0.2 s: the names come in once the gate has dissolved
   --hint-bg, --hint-ink, --hint-ring  the "touch…" pill; --frame-1..3 the rings around the portrait arch on computers.
   Phones: full screen. Computers: a centred arch with the video's own 9:16 ratio, so nothing is cropped. The picture and the video
   are the same pixels at both ends, so the opening never jumps. Without playback (reduced motion, Save-Data, not loaded…) the
   picture simply dissolves. */
/* A theme that draws its intro on the gate itself (royal's and bordeaux's two panels) does not draw it over the video. */
:root .gate:has(.v-env)::before, :root .gate:has(.v-env)::after { display: none; }
.gate:has(.v-env) { container-type: size; --s: max(100cqw / 720, 100cqh / 1280); --gate-ms: 700; background: var(--bg); }
.v-env { position: absolute; inset: 0; overflow: hidden; }
.v-poster, .v-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.v-video { opacity: 0; pointer-events: none; }
:root.video-intro .gate.video-playing .v-video { opacity: 1; }
.gate:has(.v-env) .v-in { position: absolute; inset: 0; display: block; padding: 0; }
.gate .v-in .v-hit {
  position: absolute; left: 50%; top: 50%; width: calc(var(--s) * var(--hit-w, 400)); height: calc(var(--s) * var(--hit-h, 400));
  translate: -50% calc(var(--s) * var(--hit-y, 0) - 50%); border-radius: calc(var(--s) * var(--hit-r, 0)); cursor: pointer;
}
.gate .v-in .v-hit:focus-visible { outline: 3px solid var(--gold-3); outline-offset: 4px; }
.gate .v-in .v-hint {
  position: absolute; inset-inline: 0; bottom: 5%; width: fit-content; margin-inline: auto; padding: 6px 18px; border-radius: 999px;
  background: var(--hint-bg, rgba(255, 255, 255, .9)); color: var(--hint-ink, var(--accent)); font: 600 14px var(--font-ui); letter-spacing: .08em;
  box-shadow: 0 0 0 1px var(--hint-ring, transparent);
}
/* Scaled down inside a site page (phones of the home page, site.js sets --host-scale): the hint keeps 12.5 px on screen,
   on a light pill with dark ink (DES-13). */
:root.hosted .gate .gate-hint, :root.hosted .gate .v-in .v-hint {
  font-size: max(14px, calc(12.5px / var(--host-scale, 1))) !important; letter-spacing: .04em !important;
  padding: .3em 1em; border-radius: 999px; background: rgba(255, 253, 248, .94) !important; color: #3d2f12 !important;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
}
:root.hosted .gate .gate-hint { width: fit-content; margin-inline: auto; max-width: 92%; }
.gate:has(.v-env).open { opacity: 0; transition: opacity .6s ease; }
:root.video-intro .gate:has(.v-env).open { opacity: 1; transition: opacity .45s ease; }
:root.video-intro .gate:has(.v-env).open .v-in { opacity: 0; pointer-events: none; transition: opacity .25s ease; }
:root.video-intro .gate:has(.v-env).open.video-end { opacity: 0; }
/* Full screen width whatever the flex centering does (iOS Safari kept it to the column, leaving two bands): the negative margins reach the
   screen edges from the column, the body's 8 px margin + 32 px padding. */
.v-stage { position: relative; flex-shrink: 0; width: 100vw; margin-inline: calc(50% - 50vw); align-self: flex-start; height: 100svh; overflow: hidden; isolation: isolate; background: var(--bg-hi); }
.v-shot { position: absolute; inset: 0; background: center / cover no-repeat; }
:root:is(.app-ready, :not(.js)) .v-shot { background-image: var(--shot); }
.v-veil { position: absolute; inset: 0; background: var(--veil, none); }
.v-text { position: absolute; inset-inline: 0; top: var(--text-top, 12%); z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 4px; padding-inline: 20px; text-align: center; }
.v-text .bismillah { margin-bottom: 8px; }
:root:has(.v-hero) .topbar { position: absolute; top: 14px; inset-inline-end: 0; z-index: 3; }
@media (max-width: 599px) {
  :root:has(.v-hero) body { margin-top: 0; padding-top: 0; }
  /* The body clips what overflows sideways; some iOS versions clip at its padding, cutting the full-width photo into a band on
     each side. With a photo hero the body has no side margin nor padding: the column carries them, the clip falls on the screen edges. */
  :root:has(.hero--photo) body { margin-inline: 0; padding-inline: 0; }
  :root:has(.hero--photo) .wrap { padding-inline: 40px; }
}
@media (min-width: 600px) {
  :root:has(.v-env) { scrollbar-gutter: stable; }
  .gate:has(.v-env) {
    --ah: min(90vh, 860px); --aw: calc(var(--ah) * 9 / 16);
    --ax: calc((100% - var(--aw)) / 2); --ay: 44px; /* the stage's top, below */
    --s: max(var(--aw) / 720, var(--ah) / 1280);
  }
  .v-env, .gate:has(.v-env) .v-in { position: absolute; inset: auto; left: var(--ax); top: var(--ay); width: var(--aw); height: var(--ah); }
  .v-env, .v-stage {
    border-radius: calc(var(--aw, calc(min(90vh, 860px) * 9 / 16)) / 2) calc(var(--aw, calc(min(90vh, 860px) * 9 / 16)) / 2) 18px 18px;
    box-shadow: 0 0 0 1.5px var(--frame-1, var(--gold-4)), 0 0 0 7px var(--frame-2, var(--surface)), 0 0 0 8px var(--frame-3, var(--gold-1)), 0 24px 50px var(--shadow);
  }
  .v-stage { width: calc(min(90vh, 860px) * 9 / 16); height: min(90vh, 860px); }
  :root:has(.v-hero) .topbar { top: 8px; }
}
@keyframes v-text-in { 0% { opacity: 0; transform: translateY(14px); } 100% { opacity: 1; transform: none; } }
@keyframes v-veil-in { from { opacity: 0; } to { opacity: 1; } }
:root.video-intro .gate.open ~ .wrap .v-text { animation: v-text-in 1.4s ease-out var(--text-delay, 5s) both; }
:root.video-intro .gate.open ~ .wrap .v-veil { animation: v-veil-in 1.4s ease var(--text-delay, 5s) both; }
/* The photo hero does not take part in the hero's "rise" reveal: a moving full-width layer is drawn cut to the column on iOS. */
.reveal .v-hero > .v-stage { animation: none; }
@media (min-width: 600px) {
  .v-stage { margin-inline: 0; align-self: center; }
}

/* Computer / phone switch of published invitations and showcases: wide screens with a mouse only. */
.view-switch { display: none; }
@media (min-width: 900px) and (hover: hover) {
  .view-switch { position: fixed; z-index: 30; inset-block-start: 14px; inset-inline-end: 14px; display: flex; gap: 2px; padding: 3px; border-radius: 999px;
    background: rgba(24, 20, 34, .82); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); box-shadow: 0 6px 18px rgba(0,0,0,.18); font-family: var(--font-ui); }
  .view-switch a { padding: 6px 12px; border-radius: 999px; color: #E9E4F2; font: 600 12.5px var(--font-ui); text-decoration: none; }
  .view-switch a[aria-current="true"] { background: #F1DDA0; color: #2A2010; }
  .view-switch :focus-visible { outline: 2px solid #F1DDA0; outline-offset: 2px; }
}

/* Theme "palais" — Palace: a photographed embossed envelope with a wax seal, a cinematic opening through a palace
   hall to a grand staircase, a velvet arch with paper roses, gold script. Photos live in img/ (WebP, versioned
   names: theme assets are cached as immutable). */

:root.palais {
  --bg: #F6EEE8; --bg-hi: #FFFCF9; --surface: #FFFCF9;
  --ink: #3B2226; --muted: #745B58; --line: #E4D3CA; --hi: #FFFFFF;
  --accent: #8E1F2F; --link: #8E1F2F;
  --shadow: rgba(94, 15, 28, .13);
  --wine-1: #5E0F1C; --wine-2: #8E1F2F; --wine-3: #B0475A;
  --gold-1: #7E5C24; --gold-2: #B88D45; --gold-3: #F3E2B0; --gold-4: #C9A35A;
  --gold: linear-gradient(115deg, var(--gold-1) 0%, var(--gold-2) 22%, var(--gold-3) 42%, var(--gold-4) 58%, var(--gold-2) 76%, var(--gold-1) 100%);
  --font-display-ar: "Aref Ruqaa", "Amiri", serif;
  --font-display-lat: "Great Vibes", "Cormorant Garamond", cursive;
  --font-text-ar: "Amiri", "Tajawal", serif;
  --font-text-lat: "Cormorant Garamond", Georgia, serif;
  --font-ui: "Tajawal", system-ui, sans-serif;
}

/* ---------- decor ---------- */
.palais .lattice { opacity: .6; }
.palais .frame { position: fixed; inset: 10px; pointer-events: none; z-index: 0; border: 1px solid color-mix(in srgb, var(--gold-4) 55%, transparent); border-radius: 6px; }
.palais .frame::after { content: ""; position: absolute; inset: 4px; border: 1px solid color-mix(in srgb, var(--gold-4) 25%, transparent); border-radius: 3px; }
.palais .lang { border: 1px solid var(--gold-4); color: var(--gold-1); background: color-mix(in srgb, var(--surface) 82%, transparent); }
.palais .divider:has(.garland) { margin-block: -22px; }
.palais .garland { display: block; width: 230px; height: 77px; }

/* Gold foil text */
.palais h2, .palais .sign, .palais .bism {
  background: var(--gold); background-size: 220% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent; padding-inline: .1em; }
.palais h2 { font-weight: 700; font-size: 32px; line-height: 1.35; text-align: center; }
:root.palais[lang="fr"] h2 { font-weight: 400; font-size: 46px; line-height: 1.25; }

/* ---------- hero: hall → staircase ---------- */
.palais .hero { gap: 22px; }
/* On phones the stage is a full screen (wider than the column: a centred flex item overflows on both sides). */
.palais .stage { position: relative; flex-shrink: 0; width: 100vw; height: 100svh; overflow: hidden; isolation: isolate; background: #3A2418; }
.palais .shot { position: absolute; inset: 0; background: center / cover no-repeat; }
/* Loaded only once the intro has painted (.app-ready, set by invitation.js), or straight away without JavaScript. */
:root.palais:is(.app-ready, :not(.js)) .shot-hall { background-image: url("/theme-assets/palais/img/hall-1.webp"); }
:root.palais:is(.app-ready, :not(.js)) .shot-stair { background-image: url("/theme-assets/palais/img/stair-1.webp"); }
.palais .shot-hall { opacity: 0; transform-origin: 50% 60%; }
.palais .stage-veil { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(36,18,10,.5), rgba(36,18,10,.12) 40%, rgba(36,18,10,0) 58%, rgba(36,18,10,.38)); }
.palais .stage-text { position: absolute; inset-inline: 0; top: 10%; z-index: 1; display: flex; flex-direction: column; align-items: center; padding-inline: 20px; text-align: center; }
.palais .kicker { font: 500 12px var(--font-ui); letter-spacing: .26em; text-transform: uppercase; color: #F8EBD8; text-shadow: 0 1px 8px rgba(30,14,6,.6); margin-bottom: 6px; }
.palais .name { font-size: clamp(44px, 13vw, 60px); font-weight: 700; line-height: 1.2; color: #FFFDF8; text-shadow: 0 2px 16px rgba(40,18,8,.6), 0 0 2px rgba(40,18,8,.35); }
:root.palais[lang="fr"] .name { font-weight: 400; font-size: clamp(58px, 18vw, 80px); line-height: 1; }
.palais .amp { font: 400 38px var(--font-display-lat); color: #F3DDA8; line-height: 1; text-shadow: 0 2px 10px rgba(40,18,8,.55); }
:root.palais[lang="ar"] .amp { font: 700 50px var(--font-display-ar); line-height: 1.1; }
.palais .stage-date { margin-top: 12px; font: 500 13px var(--font-ui); letter-spacing: .2em; color: #F8EBD8; text-shadow: 0 1px 8px rgba(30,14,6,.6); }
:root.palais[lang="fr"] .stage-date { text-transform: uppercase; }
.palais .chev { position: absolute; bottom: calc(18px + env(safe-area-inset-bottom, 0px)); left: 50%; width: 24px; height: 14px; margin-left: -12px; z-index: 1; fill: none; stroke: #FFF6E8; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.palais .tagline { font-size: 20px; color: var(--muted); }
:root.palais[lang="fr"] .tagline { font-style: italic; font-size: 22px; }
.palais .cta, .palais .calendar-link {
  font: 500 15px var(--font-ui); color: #3A2A0C; background: var(--gold); background-size: 220% 100%; text-decoration: none; letter-spacing: .05em;
  padding: 12px 32px; border-radius: 999px; box-shadow: 0 6px 18px rgba(126,92,36,.28), inset 0 1px 0 rgba(255,255,255,.55); }

@media (max-width: 599px) {
  /* The stage starts at the very top of the screen; the language switch floats over it. */
  :root.palais body { margin-top: 0; padding-top: 0; }
  .palais .topbar { position: absolute; top: 14px; inset-inline-end: 0; z-index: 3; }
  .palais .guest-greeting { margin-top: 24px; }
}
@media (min-width: 600px) {
  .palais .stage { width: 420px; height: min(90vh, 860px); border-radius: 210px 210px 18px 18px;
    box-shadow: 0 0 0 1.5px var(--gold-4), 0 0 0 7px var(--surface), 0 0 0 8px var(--gold-4), 0 24px 50px var(--shadow); }
}

/* ---------- verse: velvet arch with paper roses ---------- */
/* The photographed arch (893 px wide source) is cut in three: top (470 px tall, lazy <img>), a repeating plain middle,
   bottom (436 px). Sizes are in cqw of the frame, so the pieces keep their proportions at any width. */
.palais .verse { display: flex; justify-content: center; }
.palais .vframe { position: relative; flex-shrink: 0; width: min(calc(100vw - 20px), 430px); container-type: inline-size; }
.palais .vtop, .palais .vbot { position: absolute; z-index: 1; inset-inline: 0; width: 100%; height: auto; pointer-events: none; }
/* Plain paper inside the arch, under the velvet pieces (their insides are transparent). */
.palais .vfill { position: absolute; z-index: 0; inset: 17cqw 12cqw 10cqw; border-radius: 38cqw 38cqw 0 0; background: #FAF4EE; }
.palais .vtop { top: 0; }
.palais .vbot { bottom: 0; }
.palais .vmid { position: absolute; z-index: 1; inset-inline: 0; top: 52.5cqw; bottom: 48.7cqw; background: url("/theme-assets/palais/img/arch-mid-2.webp") center top / 100% auto repeat-y; }
.palais .vpanel { position: relative; z-index: 2; min-height: 102cqw; padding: 34cqw 20cqw 38cqw; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; text-align: center; }
.palais .bism { font-family: var(--font-text-ar); font-size: 23px; line-height: 1.6; direction: rtl; }
.palais .verse-ar { font-family: var(--font-text-ar); font-size: 20px; line-height: 1.9; }
.palais .verse-tr { font-family: var(--font-text-lat); font-style: italic; font-size: 16.5px; color: var(--muted); line-height: 1.45; }
.palais .cite { font-size: 11px; letter-spacing: .12em; color: var(--wine-2); }
:root.palais[lang="fr"] .cite { text-transform: uppercase; }
.palais .message .msg { font-family: var(--font-text-ar); color: var(--muted); }
:root.palais[lang="fr"] .message .msg { font-family: var(--font-text-lat); font-style: italic; font-size: 22px; }

/* ---------- save the date: calendar ---------- */
.palais .date > .divider, .palais .close > .divider { margin-block: -16px -4px; }
.palais .cal { width: min(100%, 300px); border-collapse: separate; border-spacing: 2px 3px; padding: 10px 12px 14px; border: 1px solid var(--line); border-radius: 18px; background: color-mix(in srgb, var(--surface) 88%, transparent); box-shadow: 0 10px 30px var(--shadow); font-variant-numeric: tabular-nums; }
.palais .cal caption { font: italic 600 21px var(--font-text-lat); color: var(--gold-1); padding-bottom: 8px; }
:root.palais[lang="ar"] .cal caption { font: 21px var(--font-text-ar); }
.palais .cal th { font: 500 12px var(--font-ui); color: var(--muted); padding-block: 2px 6px; }
.palais .cal td { width: 14.28%; height: 34px; text-align: center; font: 400 15px var(--font-ui); color: var(--ink); }
.palais .cal .on { display: inline-grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; font-weight: 700; color: var(--wine-1); background: #FFF8EA; box-shadow: 0 0 0 1.5px var(--gold-2), 0 0 0 5px color-mix(in srgb, var(--gold-3) 55%, transparent); }
.palais .when { display: flex; flex-direction: column; align-items: center; }
.palais .when b { font: 22px var(--font-text-ar); color: var(--ink); }
:root.palais[lang="fr"] .when b { font: 600 22px var(--font-text-lat); }
.palais .when span { font-size: 15px; color: var(--muted); letter-spacing: .08em; }
.palais .venue span { font: 21px var(--font-text-ar); }
:root.palais[lang="fr"] .venue span { font: 600 21px var(--font-text-lat); }
.palais .count-title { margin-bottom: -16px; font: 20px var(--font-text-ar); color: var(--muted); }
:root.palais[lang="fr"] .count-title { font: italic 22px var(--font-text-lat); }
.palais .cell { border: 1px solid transparent; border-radius: 16px; background: linear-gradient(var(--surface), var(--surface)) padding-box, var(--gold) border-box; box-shadow: 0 6px 16px var(--shadow); }
.palais .cell b { font: 600 34px var(--font-text-lat); color: var(--gold-1); font-variant-numeric: lining-nums tabular-nums; }
.palais .cell span { color: var(--muted); }
.palais .done { color: var(--wine-2); font-family: var(--font-text-ar); }

/* ---------- program: timeline ---------- */
.palais .program { gap: 8px; }
.palais .tl-rose { display: block; width: 30px; height: 40px; margin-inline: auto; position: relative; z-index: 1; }
.palais .tl { list-style: none; margin: 0; padding: 6px 0 0; position: relative; display: flex; flex-direction: column; gap: 28px; }
.palais .tl::before { content: ""; position: absolute; top: -4px; bottom: 0; left: 50%; width: 1.5px; margin-left: -.75px; background: linear-gradient(var(--gold-2), var(--gold-4) 80%, transparent); }
.palais .tl-i { display: grid; grid-template-columns: 1fr 34px 1fr; align-items: center; }
.palais .tl-i::before { content: ""; grid-column: 2; grid-row: 1; justify-self: center; width: 9px; height: 9px; border-radius: 50%; background: var(--gold-2); box-shadow: 0 0 0 4px var(--bg); }
.palais .tl-i.main::before { width: 13px; height: 13px; background: var(--wine-2); box-shadow: 0 0 0 3px var(--bg), 0 0 0 4.5px var(--gold-4); }
.palais .tl-when, .palais .tl-what { grid-row: 1; display: flex; flex-direction: column; min-width: 0; }
.palais .tl-when { grid-column: 1; align-items: flex-end; text-align: end; }
.palais .tl-what { grid-column: 3; align-items: flex-start; text-align: start; gap: 2px; }
.palais .tl-i:nth-child(even) .tl-when { grid-column: 3; align-items: flex-start; text-align: start; }
.palais .tl-i:nth-child(even) .tl-what { grid-column: 1; align-items: flex-end; text-align: end; }
.palais .tl-i:nth-child(even) .maps { justify-content: flex-end; }
.palais .tl-when b { font: 600 30px var(--font-text-lat); line-height: 1.1; color: var(--gold-1); font-variant-numeric: lining-nums; direction: ltr; }
.palais .tl-when span { font-size: 13px; color: var(--muted); }
.palais .tl-what h3 { margin: 0; font: 20px var(--font-text-ar); line-height: 1.4; color: var(--ink); }
:root.palais[lang="fr"] .tl-what h3 { font: 600 21px var(--font-text-lat); line-height: 1.2; }
.palais .tl-i.main h3 { color: var(--wine-2); }
.palais .tl-what .where { font-size: 14px; }
.palais .maplink { text-decoration-color: var(--gold-4); }

/* ---------- other blocks ---------- */
.palais .dresscode b { font: 700 22px var(--font-ui); color: var(--wine-2); }
.palais .photo-frame { background: var(--gold); padding: 2px; border-radius: 190px 190px 16px 16px; box-shadow: 0 18px 40px var(--shadow); }
.palais .photo img { border-radius: 188px 188px 14px 14px; border: 6px solid var(--surface); }
.palais .transport-details { font-family: var(--font-text-ar); font-size: 20px; color: var(--muted); }
:root.palais[lang="fr"] .transport-details { font-family: var(--font-text-lat); font-style: italic; }

/* ---------- RSVP: a crystal chandelier over the form ---------- */
.palais .rsvp::before { content: ""; width: 84px; height: 126px; margin-bottom: -4px; background: url("/theme-assets/palais/img/chandelier-1.webp") center / contain no-repeat; }
.palais .rsvp-form > fieldset { border-color: var(--line); border-radius: 22px; background: color-mix(in srgb, var(--surface) 90%, transparent); box-shadow: 0 10px 30px var(--shadow); }
.palais .rsvp-field input, .palais .rsvp-field textarea { border-color: var(--line); border-radius: 12px; }
.palais .choice-pill { border-color: var(--gold-4); }
.palais .choice-pill:has(input:checked) { background: var(--wine-2); border-color: var(--wine-2); color: #fff; }
.palais .rsvp-submit { background: var(--gold); background-size: 220% 100%; color: #3A2A0C; box-shadow: 0 6px 18px rgba(126,92,36,.28); }
.palais .guest-greeting { color: var(--wine-2); font-style: italic; }

/* ---------- closing ---------- */
.palais .close-seal { width: 84px; height: 84px; filter: drop-shadow(0 6px 10px rgba(79,12,23,.3)); }
.palais .sign { font-size: 36px; font-weight: 700; line-height: 1.4; }
:root.palais[lang="fr"] .sign { font-weight: 400; font-size: 52px; line-height: 1.15; }
.palais .close-date { font: 500 15px var(--font-ui); letter-spacing: .08em; color: var(--muted); margin-top: -8px; }
:root.palais[lang="fr"] .close p { font-style: italic; font-size: 22px; }

/* ---------- intro: the photographed envelope ---------- */
/* --s maps the source photo (941×1672, cover-fitted) to the screen, so the monogram lands on the wax seal
   (centred at 478,824 in the photo, 222 px wide) whatever the screen ratio. */
.palais .gate { background: #EDE3D6; container-type: size; --s: max(100cqw / 941, 100cqh / 1672); }
.palais .gate.open { background: transparent; }
/* The invitation's text stays invisible behind the closed envelope: painted late (fonts compete with the photos), it
   would otherwise become the page's Largest Contentful Paint although nobody can see it yet. The stage itself stays
   visible, so the hall is laid out and its photos decoded before the tap: the opening must not wait for them. */
:root.palais.js:not(.gate-skip) .gate:not(.open) ~ .wrap { visibility: hidden; }
:root.palais.js:not(.gate-skip) .gate:not(.open) ~ .wrap .stage { visibility: visible; }
:root.palais.js:not(.gate-skip) .gate:not(.open) ~ .wrap .stage-text { visibility: hidden; }
/* Sections below the first screen are laid out when they come near the viewport. Laid out all at once (behind the
   intro or at the tap), they blocked the main thread for over half a second on phones and the opening never played. */
.palais .wrap > section:not(.hero) { content-visibility: auto; contain-intrinsic-size: auto 700px; }
.palais .env { position: absolute; inset: 0; overflow: hidden; transform-origin: 50% 47%; perspective: 1600px; }
.palais .env-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* The lining revealed by the flaps: the open-envelope photo zoomed on its satin, under a warm glow (a gradient, not a
   blur filter: a filter is recomputed on every frame of the zoom and stutters on phones). */
.palais .env-inside { position: absolute; inset: 0; background: #D9A98F center / cover no-repeat; transform: scale(2.4); transform-origin: 51% 48%; }
.palais .env-inside::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 60% 45% at 50% 50%, rgba(255,247,228,.55), rgba(240,200,170,.35) 55%, rgba(225,190,165,.7)); }
:root.palais.app-ready .env-inside { background-image: url("/theme-assets/palais/img/env-open-1.webp"); }
/* Flaps and wax: copies of the closed photo clipped to each piece, so the closed envelope looks exactly like the
   photo. Points are photo coordinates relative to its centre (470.5, 836), scaled by --s. The flaps keep the part of
   the wax lying on them, like a broken seal; the wax piece on top breaks away first. Past 90° a flap shows its back:
   the mirrored photo under a paper tint (::after). */
.palais .flap, .palais .wax { position: absolute; inset: 0; background: url("/theme-assets/palais/img/env-closed-2.webp") center / cover no-repeat; }
.palais .flap { will-change: transform; }
.palais .flap::after { content: ""; position: absolute; inset: 0; background: linear-gradient(rgba(240,231,219,.9), rgba(214,199,182,.92)); opacity: 0; }
.palais .wax { clip-path: circle(calc(var(--s) * 113) at calc(50% + var(--s) * 7.5) calc(50% - var(--s) * 12)); transform-origin: calc(50% + var(--s) * 7.5) calc(50% - var(--s) * 12); }
.palais .flap-top { transform-origin: 50% calc(50% - 836 * var(--s));
  clip-path: polygon(calc(50% - 470.5 * var(--s)) calc(50% - 836 * var(--s)), calc(50% + 470.5 * var(--s)) calc(50% - 836 * var(--s)),
    calc(50% + 470.5 * var(--s)) calc(50% - 359 * var(--s)), calc(50% + 7.5 * var(--s)) calc(50% + 24 * var(--s)),
    calc(50% - 470.5 * var(--s)) calc(50% - 431 * var(--s))); }
.palais .flap-left { transform-origin: calc(50% - 470.5 * var(--s)) 50%;
  clip-path: polygon(calc(50% - 470.5 * var(--s)) calc(50% - 431 * var(--s)), calc(50% + 7.5 * var(--s)) calc(50% + 24 * var(--s)),
    calc(50% - 470.5 * var(--s)) calc(50% + 384 * var(--s))); }
.palais .flap-right { transform-origin: calc(50% + 470.5 * var(--s)) 50%;
  clip-path: polygon(calc(50% + 470.5 * var(--s)) calc(50% - 359 * var(--s)), calc(50% + 7.5 * var(--s)) calc(50% + 24 * var(--s)),
    calc(50% + 470.5 * var(--s)) calc(50% + 393 * var(--s))); }
.palais .flap-bottom { transform-origin: 50% calc(50% + 836 * var(--s));
  clip-path: polygon(calc(50% - 470.5 * var(--s)) calc(50% + 384 * var(--s)), calc(50% + 7.5 * var(--s)) calc(50% - 66 * var(--s)),
    calc(50% + 470.5 * var(--s)) calc(50% + 393 * var(--s)), calc(50% + 470.5 * var(--s)) calc(50% + 836 * var(--s)),
    calc(50% - 470.5 * var(--s)) calc(50% + 836 * var(--s))); }
.palais .gate-in { position: absolute; inset: 0; display: block; padding: 0; }
.palais .gate.open .gate-in { opacity: 1; transform: none; }
.palais .gate-top { position: absolute; inset-inline: 0; top: 7%; padding: 22px 28px; display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: radial-gradient(closest-side, rgba(250,245,238,.92), rgba(250,245,238,.72) 60%, rgba(250,245,238,0)); }
.palais .gate-kicker { color: var(--muted); letter-spacing: .24em; font-size: 12px; }
.palais .gate-names { font-weight: 700; font-size: 34px; color: var(--wine-2); }
:root.palais[lang="fr"] .gate-names { font-weight: 400; font-size: 50px; line-height: 1.1; }
.palais .seal { position: absolute; left: 50%; top: 50%; width: calc(var(--s) * 222); height: calc(var(--s) * 222);
  translate: calc(var(--s) * 7.5 - 50%) calc(var(--s) * -11.5 - 50%); display: grid; place-items: center; border-radius: 50%; }
/* The monogram looks stamped into the wax: gold foil with a dark lower edge and a light upper edge. */
.palais .mono { font-family: var(--font-display-ar); font-weight: 700; font-size: calc(var(--s) * 64); line-height: 1; padding-inline: .1em;
  background: var(--gold); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 1px 0 rgba(40,0,8,.7)) drop-shadow(0 -1px 0 rgba(255,214,170,.3)); }
:root.palais[lang="fr"] .mono { font-family: var(--font-display-lat); font-weight: 400; font-size: calc(var(--s) * 82); }
.palais .gate-hint { position: absolute; inset-inline: 0; top: calc(50% + var(--s) * 110 + 18px); width: fit-content; margin-inline: auto; padding: 6px 18px; border-radius: 999px;
  background: rgba(250,245,238,.88); color: var(--gold-1); }

@media (prefers-reduced-motion: no-preference) {
  .palais h2, .palais .sign, .palais .bism, .palais .cta, .palais .calendar-link { animation: shine 7s ease-in-out infinite; }
  @keyframes shine { 0%,100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
  .palais .seal { animation: breathe 2.6s ease-in-out infinite; transition: opacity .3s ease; }
  @keyframes breathe { 50% { transform: scale(1.035); } }
  .palais .gate-top, .palais .gate-hint { transition: opacity .3s ease; }
  /* The opening, all done by 3.2 s (--gate-ms: invitation.js hides the gate at 3.4 s): the seal breaks and fades
     (0–0.7 s), the top flap folds back (0.4–1.6 s), then the sides (0.95–2.05 s) and the bottom (1.2–2.3 s); each
     shows its paper back from about 90°. The camera dives into the lining from 1.9 s and the envelope fades out. */
  .palais .gate { --gate-ms: 3400; }
  .palais .wax { transition: opacity .7s ease, transform .7s ease-out, filter .7s ease; }
  .palais .flap { transition: transform 1.2s cubic-bezier(.45,0,.25,1); }
  .palais .flap::after { transition: opacity .2s linear; }
  .palais .flap-top { transition-delay: .4s; } .palais .flap-top::after { transition-delay: .95s; }
  .palais .flap-left, .palais .flap-right { transition-delay: .95s; transition-duration: 1.1s; }
  .palais .flap-left::after, .palais .flap-right::after { transition-delay: 1.45s; }
  .palais .flap-bottom { transition-delay: 1.2s; transition-duration: 1.1s; } .palais .flap-bottom::after { transition-delay: 1.7s; }
  .palais .env { transition: transform 1.3s cubic-bezier(.55,0,.35,1) 1.9s, opacity .6s ease 2.6s; will-change: transform, opacity; }
  .palais .gate.open .seal { animation: none; opacity: 0; }
  .palais .gate.open .wax { opacity: 0; transform: scale(1.12); filter: brightness(1.7) saturate(.5); }
  .palais .gate.open .gate-top, .palais .gate.open .gate-hint { opacity: 0; }
  .palais .gate.open .env-img { visibility: hidden; }
  .palais .gate.open .flap::after { opacity: 1; }
  .palais .gate.open .flap-top { transform: rotateX(168deg); }
  .palais .gate.open .flap-bottom { transform: rotateX(-168deg); }
  .palais .gate.open .flap-left { transform: rotateY(-168deg); }
  .palais .gate.open .flap-right { transform: rotateY(168deg); }
  .palais .gate.open .env { transform: scale(2.2); opacity: 0; }
  /* Then the camera glides down the hall, the scene dissolves into the staircase and the names appear. */
  .palais .gate.open ~ .wrap .shot-hall { animation: hall-move 7s cubic-bezier(.3,.1,.3,1) 2.4s both; }
  .palais .gate.open ~ .wrap .shot-stair { animation: stair-in 7s ease-out 2.4s both; }
  .palais .gate.open ~ .wrap .stage-text { animation: text-in 7.4s ease-out 2.4s both; }
  @keyframes hall-move { 0% { opacity: 1; transform: scale(1.04); } 62% { opacity: 1; transform: scale(1.26); } 100% { opacity: 0; transform: scale(1.32); } }
  @keyframes stair-in { 0%, 55% { opacity: 0; transform: scale(1.12); } 100% { opacity: 1; transform: none; } }
  @keyframes text-in { 0%, 68% { opacity: 0; transform: translateY(16px); } 100% { opacity: 1; transform: none; } }
  .palais .chev { animation: nudge 2.2s ease-in-out infinite; }
  @keyframes nudge { 50% { transform: translateY(5px); } }
}

/* Opening video (theme.json "introVideo", played by invitation.js on the first tap). The closed envelope shown is the FIRST FRAME
   of the video and the monogram sits on that frame's seal (frame 720×1280: seal centre 12.5 px left and 49 px above the middle,
   194 px wide), so playback starts on identical pixels. Without playback the envelope zooms and dissolves instead. */
.palais .gate:has(.env-video) { --s: max(100cqw / 720, 100cqh / 1280); --gate-ms: 1500; }
.palais .gate:has(.env-video) .seal { width: calc(var(--s) * 194); height: calc(var(--s) * 194); translate: calc(var(--s) * -12.5 - 50%) calc(var(--s) * -49 - 50%); }
.palais .gate:has(.env-video) .mono { font-size: calc(var(--s) * 36); }
:root.palais[lang="fr"] .gate:has(.env-video) .mono { font-size: calc(var(--s) * 42); }
.palais .gate:has(.env-video) .gate-hint { top: calc(50% + var(--s) * 48 + 18px); }
.palais .env-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; pointer-events: none; }
:root.palais.video-intro .gate.video-playing .env-video { opacity: 1; }
.palais .gate:has(.env-video).open .env-img { visibility: visible; }
:root.palais.video-intro .gate.open .gate-in { opacity: 0; pointer-events: none; transition: opacity .25s ease; }
:root.palais.video-intro .gate.open .env { transform: none; opacity: 1; transition: none; }
:root.palais.video-intro .gate.video-end { opacity: 0; transition: opacity .45s ease; }
@media (prefers-reduced-motion: no-preference) {
  .palais .gate:has(.env-video) .env { transition: transform 1.1s cubic-bezier(.55,0,.35,1), opacity .6s ease .5s; }
}

/* Handoff from the video to the invitation. The video ends on the hall (4.0 s, the gate then dissolves until 4.2 s). Under it the
   hall must stay still, at the video's last frame (no zoom, no veil), and only start moving once the gate is gone: otherwise the
   picture seems to shift as the video fades. Delays = video length + 0.2 s. */
@keyframes hall-move-v { 0% { opacity: 1; transform: none; } 62% { opacity: 1; transform: scale(1.22); } 100% { opacity: 0; transform: scale(1.28); } }
@keyframes veil-in { from { opacity: 0; } to { opacity: 1; } }
:root.palais.video-intro .gate.open ~ .wrap .shot-hall { animation: hall-move-v 7s cubic-bezier(.3,.1,.3,1) 4.2s both; }
:root.palais.video-intro .gate.open ~ .wrap .shot-stair { animation: stair-in 7s ease-out 4.2s both; }
:root.palais.video-intro .gate.open ~ .wrap .stage-text { animation: text-in 7.4s ease-out 4.2s both; }
:root.palais.video-intro .gate.open ~ .wrap .stage-veil { animation: veil-in 1.6s ease 4.1s both; }

/* With the opening video, the hall of the invitation is the video's own LAST FRAME (img/video-end-1.webp, same pixels): the AI
   redraws the hall, so the site's hall photo never matches it exactly and the dissolve showed one turning into the other. */
:root.palais:has(.env-video):is(.app-ready, :not(.js)) .shot-hall { background-image: url("/theme-assets/palais/img/video-end-1.webp"); }

/* Computers: the invitation shows the hall in a 420 px arch (see .stage above), so the opening is played in that very arch,
   same position, size and shape, instead of full screen: the handoff to the invitation is then a pure dissolve. Its top is the
   stage's top (133px below the language bar, 44px without it) and the scrollbar gutter is reserved so that the scrollbar
   appearing when the page unlocks does not shift the arch. */
@media (min-width: 600px) {
  :root.palais:has(.env-video) { scrollbar-gutter: stable; }
  .palais .gate:has(.env-video) {
    --aw: 420px; --ah: min(90vh, 860px); --ay: 44px; /* the stage's top once the language bar is out of the flow (below) */
    --ax: calc((100% - var(--aw)) / 2); /* % of the gate: it already excludes the scrollbar gutter, like the page layout */
    --s: max(var(--aw) / 720, var(--ah) / 1280);
  }
  .palais .gate:has(.env-video) .env, .palais .gate:has(.env-video) .gate-in {
    position: absolute; inset: auto; left: var(--ax); top: var(--ay); width: var(--aw); height: var(--ah);
  }
  .palais .gate:has(.env-video) .env {
    border-radius: 210px 210px 18px 18px;
    box-shadow: 0 0 0 1.5px var(--gold-4), 0 0 0 7px var(--surface), 0 0 0 8px var(--gold-4), 0 24px 50px var(--shadow);
  }
}
@media (min-width: 600px) {
  /* The language bar leaves the flow (a corner chip, as on phones): the arch starts near the top of the window, so its normal
     height fits in short windows too, and the stage's top no longer depends on that bar. */
  :root.palais:has(.env-video) .topbar { position: absolute; top: 8px; inset-inline-end: 0; z-index: 3; }
}

