/*!***************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/app/[locale]/(landing)/landing-v2.css ***!
  \***************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * Design tokens for the landing page redesign, from
 * design/landing-v2/README.md ("Design tokens"). Scoped under `.landing-v2`
 * so nothing leaks into the game or manage UIs, which have their own token
 * files.
 */
.landing-v2 {
  --lp-bg: #f6f2ea;
  --lp-surface: #fffdf9;
  --lp-border: #e5ded1;
  --lp-border-strong: #d8d0c0;
  --lp-border-warm: #e6ddcc;
  --lp-border-deep: #c9c2b4;
  --lp-ink: #35312a;
  --lp-ink-soft: #55503f;
  --lp-muted: #7d7565;
  --lp-muted-2: #8a8271;
  --lp-muted-3: #a39b88;
  --lp-pink: #b85c7e;
  --lp-pink-dark: #8d4d68;
  --lp-pink-tint: #f5e5eb;
  --lp-blue: #6b7fb0;
  --lp-blue-dark: #4d5d8d;
  --lp-blue-tint: #e8ecf5;
  --lp-link: #8a5a3b;
  --lp-link-hover: #6b4225;
  --lp-warm-tint: #f3ead9;
  --lp-stripe: repeating-linear-gradient(
    45deg,
    #efe8db,
    #efe8db 8px,
    #e6ddcc 8px,
    #e6ddcc 16px
  );
  --lp-cta-shadow: 0 4px 14px rgba(184, 92, 126, 0.35);

  background: var(--lp-bg);
  color: var(--lp-ink);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica,
    Arial, sans-serif;
}

.landing-v2 a {
  color: var(--lp-link);
}
.landing-v2 a:hover {
  color: var(--lp-link-hover);
}

/* Mono all-caps kicker/eyebrow. Capitalisation happens here, never in the
 * catalogue. */
.lp-kicker {
  font-family: ui-monospace, monospace;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Hero: rising emoji particles behind the score bar. */
@keyframes lp-rise {
  0% {
    transform: translateY(0) scale(0.8);
    opacity: 0;
  }
  12% {
    opacity: 0.85;
  }
  45% {
    opacity: 0.4;
  }
  70% {
    opacity: 0;
  }
  100% {
    transform: translateY(-84px) scale(1.05);
    opacity: 0;
  }
}

/* Hero: mobile scoring-chips marquee. */
@keyframes lp-marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

/* The marketing headline voice, shared with the blog: the landing's own
 * headings set this inline; the blog reaches it as a class through
 * `components/blog/fonts.ts`. !important because call sites carry per-size
 * inline font-weights from the Playfair era - the voice wins on purpose. */
.lp-headline {
  font-family: inherit;
  font-weight: 800 !important;
  letter-spacing: -0.01em;
}

/*!*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!./node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!./node_modules/next/font/google/target.css?{"path":"src/lib/designs/fonts.ts","import":"Inter","arguments":[{"subsets":["latin"],"weight":["400","700"]}],"variableName":"inter"} ***!
  \*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/ba9851c3c22cd980-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/21350d82a1f187e9-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/c5fe6dc8356a8c31-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/19cfc7226ec3afaa-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/df0a9ae256c0569c-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/8e9860b6e62d6359-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/e4af272ccee01ff0-s.p.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;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/ba9851c3c22cd980-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/21350d82a1f187e9-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/c5fe6dc8356a8c31-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/19cfc7226ec3afaa-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/df0a9ae256c0569c-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/8e9860b6e62d6359-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/e4af272ccee01ff0-s.p.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;
}@font-face {font-family: 'Inter Fallback';src: local("Arial");ascent-override: 90.44%;descent-override: 22.52%;line-gap-override: 0.00%;size-adjust: 107.12%
}.__className_516c7b {font-family: 'Inter', 'Inter Fallback';font-style: normal
}

/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!./node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!./node_modules/next/font/google/target.css?{"path":"src/lib/designs/fonts.ts","import":"Noto_Sans","arguments":[{"subsets":["latin"],"weight":["400","700"]}],"variableName":"notoSans"} ***!
  \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* cyrillic-ext */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/82ef96de0e8f4d8c-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/a6ecd16fa044d500-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* devanagari */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/bd82c78e5b7b3fe9-s.woff2) format('woff2');
  unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}
/* greek-ext */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/c32c8052c071fc42-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/6f22fce21a7c433c-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/1d8a05b60287ae6c-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/77c207b095007c34-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/1755441e3a2fa970-s.p.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;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/82ef96de0e8f4d8c-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/a6ecd16fa044d500-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* devanagari */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/bd82c78e5b7b3fe9-s.woff2) format('woff2');
  unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0, U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}
/* greek-ext */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/c32c8052c071fc42-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/6f22fce21a7c433c-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/1d8a05b60287ae6c-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/77c207b095007c34-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/1755441e3a2fa970-s.p.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;
}@font-face {font-family: 'Noto Sans Fallback';src: local("Arial");ascent-override: 100.54%;descent-override: 27.56%;line-gap-override: 0.00%;size-adjust: 106.33%
}.__className_cae096 {font-family: 'Noto Sans', 'Noto Sans Fallback';font-style: normal
}

/*!**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!./node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!./node_modules/next/font/google/target.css?{"path":"src/lib/designs/fonts.ts","import":"Noto_Serif","arguments":[{"subsets":["latin"],"weight":["400","700"]}],"variableName":"notoSerif"} ***!
  \**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* cyrillic-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/7b800e61c24d781c-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/dcd0d8c94b74be53-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/435d7d3c1b2ff02f-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/ba6607e4cc7979de-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* math */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/3ba05cde04a1b013-s.woff2) format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
/* vietnamese */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/d4548b25969cca89-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/f1c328b8a9761933-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/30d74baa196fe88a-s.p.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;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/7b800e61c24d781c-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/dcd0d8c94b74be53-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/435d7d3c1b2ff02f-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/ba6607e4cc7979de-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* math */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/3ba05cde04a1b013-s.woff2) format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
/* vietnamese */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/d4548b25969cca89-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/f1c328b8a9761933-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/30d74baa196fe88a-s.p.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;
}@font-face {font-family: 'Noto Serif Fallback';src: local("Times New Roman");ascent-override: 90.29%;descent-override: 24.75%;line-gap-override: 0.00%;size-adjust: 118.40%
}.__className_97918b {font-family: 'Noto Serif', 'Noto Serif Fallback';font-style: normal
}

/*!****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!./node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!./node_modules/next/font/google/target.css?{"path":"src/lib/designs/fonts.ts","import":"PT_Sans","arguments":[{"subsets":["latin"],"weight":["400","700"]}],"variableName":"ptSans"} ***!
  \****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* cyrillic-ext */
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/a3c2f369cb4be41c-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/da770fb7323ac426-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* latin-ext */
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/d538c3ded86c536c-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/_next/static/media/58f662ed5ba12a72-s.p.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;
}
/* cyrillic-ext */
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/056ab7b2284b723d-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/d150a0f5773426e5-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* latin-ext */
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/47346084fe5b6a4f-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/_next/static/media/c3f6eb667c0186c5-s.p.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;
}@font-face {font-family: 'PT Sans Fallback';src: local("Arial");ascent-override: 105.30%;descent-override: 28.55%;line-gap-override: 0.00%;size-adjust: 96.68%
}.__className_438d47 {font-family: 'PT Sans', 'PT Sans Fallback';font-style: normal
}

/*!*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!./node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!./node_modules/next/font/google/target.css?{"path":"src/lib/designs/fonts.ts","import":"Noto_Serif","arguments":[{"subsets":["latin"],"weight":["400","700"],"variable":"--font-qyg-serif","preload":false}],"variableName":"qygSerif"} ***!
  \*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* cyrillic-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/7b800e61c24d781c-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/dcd0d8c94b74be53-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/435d7d3c1b2ff02f-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/ba6607e4cc7979de-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* math */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/3ba05cde04a1b013-s.woff2) format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
/* vietnamese */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/d4548b25969cca89-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/f1c328b8a9761933-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/30d74baa196fe88a-s.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;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/7b800e61c24d781c-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/dcd0d8c94b74be53-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/435d7d3c1b2ff02f-s.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/ba6607e4cc7979de-s.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* math */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/3ba05cde04a1b013-s.woff2) format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
/* vietnamese */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/d4548b25969cca89-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/f1c328b8a9761933-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Noto Serif';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/_next/static/media/30d74baa196fe88a-s.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;
}@font-face {font-family: 'Noto Serif Fallback';src: local("Times New Roman");ascent-override: 90.29%;descent-override: 24.75%;line-gap-override: 0.00%;size-adjust: 118.40%
}.__className_7bd60d {font-family: 'Noto Serif', 'Noto Serif Fallback';font-style: normal
}.__variable_7bd60d {--font-qyg-serif: 'Noto Serif', 'Noto Serif Fallback'
}

/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[2].use[1]!./node_modules/next/dist/build/webpack/loaders/next-font-loader/index.js??ruleSet[1].rules[13].oneOf[2].use[2]!./node_modules/next/font/google/target.css?{"path":"src/lib/designs/fonts.ts","import":"Nunito","arguments":[{"subsets":["latin"],"variable":"--font-qyg-rounded","preload":false}],"variableName":"qygRounded"} ***!
  \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* cyrillic-ext */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url(/_next/static/media/abfec168c8990f67-s.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url(/_next/static/media/3131c862d4942660-s.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url(/_next/static/media/6a9c36ea9dc9b36b-s.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url(/_next/static/media/e1694c6cb47c173f-s.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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url(/_next/static/media/ee40bb094c99a29a-s.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;
}@font-face {font-family: 'Nunito Fallback';src: local("Arial");ascent-override: 99.71%;descent-override: 34.82%;line-gap-override: 0.00%;size-adjust: 101.39%
}.__className_8ac22e {font-family: 'Nunito', 'Nunito Fallback';font-style: normal
}.__variable_8ac22e {--font-qyg-rounded: 'Nunito', 'Nunito Fallback'
}

/*!*************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/feature-grid.css ***!
  \*************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The bottom of the home column: the 2x2 feature grid and the two rows under
 * it (handoff README §2, items 5, 6 and 7).
 *
 * One stylesheet for three components because they are one design block - the
 * grid's cards and the two rows share the card, the pill and the icon tile
 * down to the pixel, and three files would be three copies of each drifting
 * apart. Same convention as `game-photos.css`: plain CSS next to the
 * components, every value either a `--qyg-*` lookup or a number the handoff
 * gives explicitly.
 */

.qyg-features {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 9px;
}

/*
 * An odd card out takes the full width rather than sitting beside a hole.
 * Three cards is a real state - an event with no seating plan, or a wall that
 * has closed - and a lone half-width card with empty space next to it reads
 * as something that failed to load.
 */
.qyg-feature:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

.qyg-feature {
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* Flat with a 1px border. The hero card above is the only elevated thing on
     the screen, and that is what makes it read as the hero. */
  border: 1px solid var(--qyg-border);
  border-radius: var(--qyg-r-card);
  background: var(--qyg-bg-card);
  padding: 11px;
  /* Comfortably past the 44px floor, and the number the mock's seat and
     schedule cards carry - so a card with a short caption keeps the grid
     square instead of collapsing to two lines of text. */
  min-height: 84px;
  text-align: left;
}

/*
 * Dormant, before the day (handoff §8): visible, explained, and not a
 * control. Rendered as a div rather than a disabled button, so it is not in
 * the tab order at all - there is nothing behind it to reach.
 */
.qyg-feature-dormant {
  opacity: 0.5;
}

.qyg-feature-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

.qyg-feature-tile {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: var(--qyg-r-tile);
  background: var(--color-team-tint);
  font-size: 15px;
  line-height: 1;
}

.qyg-feature-pill {
  flex: none;
  border-radius: var(--qyg-r-pill);
  background: var(--qyg-bg-pill);
  padding: 2px 7px;
  font-size: 9.5px;
  font-weight: 700;
  color: var(--qyg-ink-secondary);
  white-space: nowrap;
}

/*
 * The photo card's icon is three photographs and a "+N", because the social
 * proof is the point (handoff §2 item 5); a camera glyph over a wall of real
 * pictures would say nothing.
 *
 * The design's 44px squares are what four of them cannot be: 3x44 plus a tile
 * plus the gaps is 191px, and half a 320px column is 121px of usable width.
 * So 44px is a ceiling rather than a size - they shrink together, stay square
 * through `aspect-ratio`, and never push the card wider than its column.
 */
.qyg-feature-thumbs {
  display: flex;
  /* Takes the whole row, so its children have a width to shrink into rather
     than sizing themselves off their own 44px ceiling and overflowing. */
  flex: 1 1 auto;
  min-width: 0;
  gap: 5px;
}

.qyg-feature-thumb,
.qyg-feature-more {
  flex: 1 1 0;
  min-width: 0;
  max-width: 44px;
  aspect-ratio: 1;
  /* `--qyg-r-thumb`, not `--qyg-r-tile`: these are photographs, and the "+N"
     is shaped to match them rather than to match the icon tile above. */
  border-radius: var(--qyg-r-thumb);
}

.qyg-feature-thumb {
  object-fit: cover;
  /* Something warm rather than a white flash while the thumbnail loads. */
  background: var(--qyg-bg-pill);
}

.qyg-feature-more {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--qyg-bg-pill);
  font-size: 11px;
  font-weight: 800;
  color: var(--qyg-ink-secondary);
}

.qyg-feature-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--qyg-ink);
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
}

.qyg-feature-caption {
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--qyg-ink-tertiary);
}

/*
 * The guest's own five digits, in the box they will hold up across a table.
 * Mono and letter-spaced for the same reason the make-a-friend screen boxes
 * them: these get read out loud, and a proportional 8 next to a 1 gets read
 * out wrong.
 */
.qyg-feature-code {
  align-self: flex-start;
  border: 1px solid var(--qyg-border);
  border-radius: var(--qyg-r-tile);
  background: var(--qyg-bg-inset);
  padding: 2px 7px;
  font-family: var(--qyg-font-mono);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.14em;
  color: var(--qyg-ink);
}

/*
 * The toast row and the note row. Both replace something that used to shout:
 * the toast was a sticky floating button pinned over the game, and the note
 * was a modal. They are rows now, in the column, in reading order.
 */
.qyg-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  border: 1px solid var(--qyg-border);
  border-radius: var(--qyg-r-row);
  background: var(--qyg-bg-card);
  padding: 10px 14px;
  text-align: left;
}

/*
 * On cooldown. Dimmed rather than removed: the row is where the guest's eye
 * goes for the ritual, and a row that disappears for five minutes teaches
 * them it is not there.
 */
.qyg-row-cooldown {
  opacity: 0.55;
}

.qyg-row-emoji {
  flex: none;
  font-size: 15px;
  line-height: 1;
}

.qyg-row-text {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 1px;
}

.qyg-row-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--qyg-ink);
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
}

.qyg-row-sub {
  font-size: 11px;
  color: var(--qyg-ink-tertiary);
}

/* Tabular figures so a counting-down clock does not shuffle the row's width
   from one second to the next. */
.qyg-row-countdown {
  font-variant-numeric: tabular-nums;
}

.qyg-row-pill {
  flex: none;
  margin-left: auto;
  border-radius: var(--qyg-r-pill);
  background: var(--color-team-tint);
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 700;
  color: var(--color-team-dark);
  white-space: nowrap;
}

.qyg-row-chevron {
  flex: none;
  margin-left: auto;
  color: var(--qyg-ink-faint);
}

/*!************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/promo/promo.css ***!
  \************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The demo notice and the free-tier colophon (handoff `design_handoff_demo_
 * branding`). Every value is either a `--qyg-*` token or a number the handoff
 * gives; nothing here introduces a colour.
 */

/* ① The frosted tag, top-left of the hero. Absolute, because it sits over a
   photograph in one variant and over nothing in the other, and the hero owns
   its own padding either way. */
.qyg-demo-tag {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 1;
  padding: 4px 10px;
  border-radius: var(--qyg-r-pill);
  background: rgba(255, 253, 249, 0.9);
  font-family: var(--qyg-font-mono);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  /* The capitals live here, not in the catalogue. */
  text-transform: uppercase;
  color: var(--qyg-ink);
}

/* ② A standard feed row that happens to be a link. */
.qyg-demo-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  text-decoration: none;
}

.qyg-demo-row-text {
  display: flex;
  min-width: 0;
  flex: 1;
  flex-direction: column;
}

.qyg-demo-row .qyg-row-sub {
  font-size: 11.5px;
  color: var(--qyg-ink-secondary);
}

.qyg-demo-row-chevron {
  flex: none;
  color: var(--qyg-ink-faint);
}

/* ③ The closing card. A flat card like the rest of the feed - the pitch is in
   the words, not in the frame. */
.qyg-demo-closing {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  padding: 14px;
  border-radius: var(--qyg-r-card);
  background: var(--qyg-bg-card);
  box-shadow: var(--qyg-shadow-card);
}

.qyg-demo-closing-title {
  margin: 0;
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
  font-size: 16px;
  color: var(--qyg-ink);
}

.qyg-demo-closing-body {
  margin: 0 0 4px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--qyg-ink-secondary);
}

.qyg-demo-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border-radius: var(--qyg-r-button);
  /* Ink, not `--color-team`. The handoff is explicit: this is the app selling
     itself, and wearing the couple's colour would make it look like they were
     asking. */
  background: var(--qyg-ink);
  color: var(--qyg-bg-page);
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
  font-size: 14px;
  text-decoration: none;
}

/* §2 The colophon. Stationery credit, not a banner. */
.qyg-colophon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding-top: 14px;
}

.qyg-colophon-rule {
  width: 36px;
  height: 1px;
  background: var(--qyg-border-strong);
}

.qyg-colophon-credit {
  margin: 0;
  /* The one serif italic in the guest UI, in every theme. It is a printer's
     credit on the back of a wedding card, and it should not change when the
     couple picks a different look. */
  font-family: var(--font-qyg-serif), Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 13px;
  color: var(--qyg-ink-secondary);
}

.qyg-colophon-link {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--qyg-link);
  text-decoration: none;
}

/* §2 The admin's own line. Dashed, because it is a note to one person rather
   than part of the page everybody else is reading. */
.qyg-admin-note {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin-top: 8px;
  padding: 11px 12px;
  border: 1px dashed var(--qyg-border-strong);
  border-radius: 12px;
  text-decoration: none;
}

.qyg-admin-chip {
  flex: none;
  font-family: var(--qyg-font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--qyg-ink-faint);
}

.qyg-admin-note-text {
  font-size: 12px;
  color: var(--qyg-ink-secondary);
}

.qyg-admin-note-text span {
  font-weight: 700;
  color: var(--qyg-link);
}

/*!**********************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/hero-card.css ***!
  \**********************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The one elevated card and everything inside it (handoff README §3 and §4).
 *
 * Plain CSS beside the component, matching `game-root-v2.css` and
 * `game-sheet.css`: this card is specified as exact pixel values against
 * `--qyg-*` tokens, and a row of arbitrary-value Tailwind utilities would
 * hide both halves of that.
 *
 * Class names are `.qyg-card-*` and `.qyg-quiz-*` rather than `.qyg-hero-*`,
 * which in `game-root-v2.css` already means the hero *photo* at the top of
 * the column. Two different things called hero is the design's fault, not
 * ours, but only one of them gets the prefix.
 */

/*
 * The only element on the home screen with a shadow. Everything else is flat
 * with a 1px border, and that contrast is the whole reason this card reads as
 * the thing to look at.
 */
.qyg-hero-card {
  display: flex;
  flex-direction: column;
  gap: 9px;
  border-radius: var(--qyg-r-hero);
  padding: 16px;
  background: var(--qyg-bg-card);
  box-shadow: var(--qyg-shadow-hero);
}

.qyg-hero-card-top {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 20px;
}

.qyg-card-eyebrow {
  font-family: var(--qyg-font-mono);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.12em;
  /* Upper-cased here, never in the catalogue: capitals baked into a message
     survive translation into languages where they are wrong. */
  text-transform: uppercase;
  color: var(--qyg-ink-tertiary);
}

/*
 * "Rounds ›" and "Answers ›". 11.5-12px of text with a 44px tap target around
 * it: the padding buys the height and the negative margin gives it straight
 * back to the layout, so the row it sits in is still the height the design
 * draws.
 */
.qyg-card-link {
  margin: -12px 0 -12px auto;
  padding: 12px 0;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  color: var(--qyg-link);
}

.qyg-card-title {
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-display-weight);
  font-size: 24px;
  line-height: 1.15;
  color: var(--qyg-ink);
}

.qyg-card-line {
  font-size: 12.5px;
  color: var(--qyg-ink-secondary);
}

/* The seal, in the slot the results inset will take over once the round the
   guest just answered has been scored. */
.qyg-card-sealed {
  font-size: 11.5px;
  color: var(--qyg-ink-faint);
}

.qyg-card-divider {
  border: 0;
  border-top: 1px solid var(--qyg-divider);
}

/*
 * The screen's one primary CTA. A filled 48px button rather than the text
 * link the old card ended on - a waiting guest is the one with a free hand,
 * and this is the moment to give them something to do with it.
 */
.qyg-card-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 48px;
  border-radius: var(--qyg-r-button);
  background: var(--color-team);
  color: #fff;
  font-size: 14.5px;
  font-weight: 800;
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
}

/* ---------- results inset (§4) ---------- */

/* A button, because the whole inset opens the round - so it needs the resets
   that stop a button looking like one, and a full-width block layout. */
.qyg-results {
  display: flex;
  flex-direction: column;
  gap: 7px;
  width: 100%;
  border: 0;
  border-radius: var(--qyg-r-inset);
  padding: 10px 12px;
  background: var(--qyg-bg-inset);
  font: inherit;
  color: inherit;
  text-align: left;
  appearance: none;
}

.qyg-results-top {
  display: flex;
  align-items: center;
  gap: 8px;
}

.qyg-results-yours {
  margin-left: auto;
  font-size: 12.5px;
  font-weight: 800;
  color: var(--qyg-ink);
}

/*
 * The mini tug bar. Widths are `flex-basis` here and a `scaleX` on the
 * scoreboard, which is not an inconsistency: the scoreboard's split moves as
 * points land during the evening, so it animates and must not animate a
 * layout property. This bar is drawn once for a round that has finished and
 * is replaced wholesale when the inset flips to the next one - it never
 * transitions, so there is no frame for a reflow to cost anything on.
 */
.qyg-tug {
  display: flex;
  align-items: stretch;
  overflow: hidden;
  height: 26px;
  border-radius: var(--qyg-r-tile);
}

.qyg-tug-block {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 0 10px;
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  /* The page colour between the two, exactly as the scoreboard splits its
     blocks - the gap is the card showing through, not a border. */
  border-right: 2px solid var(--qyg-bg-inset);
}

.qyg-tug-block:last-child {
  border-right: 0;
}

.qyg-tug-end {
  margin-left: auto;
}

.qyg-results-foot {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Always the guest's own team-dark, whichever team won - see `WinnerLine`. */
.qyg-results-winner {
  min-width: 0;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--color-team-dark);
}

.qyg-results-foot .qyg-card-link {
  font-size: 11.5px;
}

/* ---------- quiz (§3) ---------- */

.qyg-quiz-body {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.qyg-question {
  font-size: 19px;
  font-weight: 800;
  line-height: 1.3;
  color: var(--qyg-ink);
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
}

.qyg-answers {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.qyg-answer {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 12px;
  border: 1.5px solid var(--qyg-border);
  border-radius: var(--qyg-r-row);
  background: #fff;
  text-align: left;
}

/*
 * Locked. The 2px border replaces the 1.5px one rather than adding to it, so
 * the row does not grow by half a pixel and nudge the three below it as the
 * guest chooses.
 */
.qyg-answer[data-selected] {
  border: 2px solid var(--color-team);
  padding: 0 11.5px;
  background: var(--color-team-tint);
}

/*
 * Everything they did not pick. Dimmed, not hidden and not removed: seeing
 * the four options recede is what makes the choice feel taken, and this is as
 * far as the card is ever allowed to go - no green, no red, nothing that
 * hints at whether they were right. That rule is enforced in the data
 * (`convert.ts` strips the correctness flags from a live round) but it should
 * not be undone here by implication either.
 */
.qyg-answer[data-dim] {
  opacity: 0.45;
}

.qyg-answer-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: var(--qyg-r-pill);
  background: var(--color-team-tint);
  color: var(--color-team-dark);
  font-size: 11px;
  font-weight: 800;
}

/* The chip fills and takes the padlock, which is the one place on this card
   where something is announced rather than merely selected. */
.qyg-answer[data-selected] .qyg-answer-chip {
  background: var(--color-team);
  color: #fff;
}

.qyg-answer-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--qyg-ink);
}

.qyg-answer[data-selected] .qyg-answer-label {
  font-weight: 800;
  color: var(--color-team-dark);
}

.qyg-answer-note {
  margin-left: auto;
  flex: none;
  font-size: 12px;
  color: var(--color-team-dark);
}

.qyg-quiz-foot {
  display: flex;
  align-items: center;
  gap: 8px;
}

.qyg-progress-track {
  flex: 1;
  overflow: hidden;
  height: 6px;
  border-radius: var(--qyg-r-pill);
  background: var(--qyg-bg-pill);
}

/*
 * The fill is full width and scaled down; `.qyg-progress-fill` in
 * `game-v2.css` owns the transform and its 0.4s. Only the paint is here.
 */
.qyg-progress-fill {
  width: 100%;
  height: 100%;
  border-radius: var(--qyg-r-pill);
  background: var(--color-team);
}

.qyg-progress-count {
  font-size: 11px;
  font-weight: 700;
  color: var(--qyg-ink-tertiary);
  font-variant-numeric: tabular-nums;
}

/*!**************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/game-identity.css ***!
  \**************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The identity line (handoff README §2 item 3, Turn 17).
 *
 * A text row and not a card: no background, no border, no shadow. It is the
 * one line on the screen that says whose phone this is, and giving it a box
 * would turn it into a widget competing with the hero card below it.
 */

.qyg-identity {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  /*
   * The mock draws this row about 20px tall, because it is 11-12.5px of text
   * with 4px of padding. It is also a tap into the profile sheet, so it gets
   * the 44px the rest of the design gets - the row is airier here than in
   * Turn 17 and that is the trade the hit-target rule asks for. Pulling the
   * padding back out with a negative margin would buy the mock's spacing at
   * the price of overlapping the scoreboard's target, which is the wrong way
   * round: a mis-tap costs more than 20px of air.
   */
  min-height: 44px;
  padding: 0 6px;
  font-size: 12.5px;
  color: var(--qyg-ink-secondary);
  text-align: left;
}

/*
 * The guest's own name and score, in their own team's dark variant - the one
 * that is readable on the neutral chrome, and never `--color-team`, which is
 * sized for white text on top of it rather than for being text itself.
 */
.qyg-identity-you {
  display: flex;
  align-items: baseline;
  min-width: 0;
  white-space: nowrap;
  font-weight: 700;
  color: var(--color-team-dark);
}

/*
 * Only the name gives way, and it gives way before the row runs out of room
 * rather than after: a cap in `ch` keeps "· 65pt" on screen for a guest who
 * typed their full name into the join form. Everything else in the row is a
 * fixed handful of characters, so this is the only length the row cannot
 * predict.
 */
.qyg-identity-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 15ch;
  /* The body face, like the team row above it - see `game-scoreboard.css`. */
  font-weight: 800;
}

.qyg-identity-points {
  flex: none;
  /* Stands in for the space the flex item swallowed - see IdentityLine. */
  margin-left: 0.35em;
}

/* Not a control of its own - the whole row opens the profile sheet, and that
   is where the renaming lives. It is here as the hint that tapping does
   something, which is why it is `--qyg-ink-disabled` rather than an accent. */
.qyg-identity-edit {
  flex: none;
  font-size: 11px;
  color: var(--qyg-ink-disabled);
}

.qyg-identity-stats {
  flex: none;
  margin-left: auto;
  white-space: nowrap;
}

/*!***********************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/post-event.css ***!
  \***********************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The post-event home (handoff README §9, Turn 15c).
 *
 * Plain CSS beside the components, matching `hero-card.css` and
 * `feature-grid.css`: every value here is either a `--qyg-*` lookup or a
 * number Turn 15c gives explicitly, and a row of arbitrary-value Tailwind
 * utilities would hide both.
 *
 * One stylesheet for five blocks because they are one screen. The banner, the
 * recap, the photo strip, the email row and the friend chips are only ever
 * rendered together, and splitting them would be five copies of the same card
 * drifting apart.
 */

.qyg-post {
  display: flex;
  flex-direction: column;
  /* The column's own gap - this element is a plain wrapper inside it, so it
     has to restate the spacing rather than inherit it. */
  gap: 9px;
}

/* The two look-back rows. Tighter than the column's gap so they read as a
   pair under the recap card rather than as two more cards. */
.qyg-post-rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ---------- winner banner (§9) ---------- */

/*
 * The winning team's colour, filling the space the scoreboard and the hero
 * card used to share. It is the only saturated block on the screen and the
 * only thing on it with a shadow, which is the same trick the hero card plays
 * during the evening: one loud element, everything else flat.
 *
 * `--qyg-banner` is set inline by the component, because the winner is not
 * always the guest's own team and `--qyg-shadow-cta` is hard-wired to
 * `--color-team`. A draw sets it to the neutral ink instead.
 */
.qyg-banner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  border-radius: var(--qyg-r-card);
  padding: 16px 14px;
  background: var(--qyg-banner);
  box-shadow: 0 6px 18px color-mix(in oklch, var(--qyg-banner) 40%, transparent);
  text-align: center;
}

.qyg-banner-trophy {
  font-size: 30px;
  line-height: 1;
}

/*
 * Every line on the banner is full-strength white.
 *
 * Turn 15c fades the score to 0.9 and the thank-you to 0.85, and we do not:
 * the nine curated `main` values were each darkened until *white* clears
 * 4.5:1 on them (see `team-colors.ts`), and thinning the white is precisely
 * the thing that undoes that work. Neither line is large text - 14px bold is
 * well under the 18.66px the exemption starts at - so the hierarchy comes out
 * of size and weight instead, which costs the design nothing at this scale.
 */
.qyg-banner-title {
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-display-weight);
  font-size: 21px;
  line-height: 1.15;
  color: #fff;
}

.qyg-banner-score {
  font-size: 14px;
  font-weight: 800;
  color: #fff;
}

.qyg-banner-thanks {
  font-size: 11.5px;
  line-height: 1.35;
  color: #fff;
}

/* ---------- shared card (§9) ---------- */

/*
 * Flat, 1px border, the neutral card colour. Three of the four blocks below
 * the banner are this card; the email row is the fourth and differs only in
 * its border, which is the whole point of it.
 */
.qyg-post-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border: 1px solid var(--qyg-border);
  border-radius: var(--qyg-r-card);
  background: var(--qyg-bg-card);
  padding: 12px;
  text-align: left;
}

.qyg-post-eyebrow {
  font-family: var(--qyg-font-mono);
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.12em;
  /* Upper-cased here, never in the catalogue - capitals baked into a message
     survive translation into languages where they are wrong. */
  text-transform: uppercase;
  color: var(--qyg-ink-tertiary);
}

/* ---------- "your night" recap ---------- */

.qyg-recap-top {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

/* The guest's own name and place, in their own team's dark - the same colour
   the identity line wore all evening, so the row reads as the same person. */
.qyg-recap-line {
  min-width: 0;
  margin-left: auto;
  font-size: 12.5px;
  font-weight: 800;
  text-align: right;
  color: var(--color-team-dark);
}

/*
 * Four figures across, however many there are. `auto-fit` rather than a fixed
 * four columns because an event with the photo wall or make-a-friend switched
 * off has three or two, and two stats stretched over four columns leaves half
 * the card empty.
 */
.qyg-recap-stats {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 6px;
  text-align: center;
}

.qyg-recap-stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.qyg-recap-value {
  font-size: 15px;
  font-weight: 800;
  color: var(--qyg-ink);
  font-variant-numeric: tabular-nums;
}

.qyg-recap-label {
  font-size: 9px;
  color: var(--qyg-ink-tertiary);
}

/* ---------- photo strip ---------- */

.qyg-post-photos {
  /* A card that is also a control, so it needs the 44px floor its header does
     not reach on its own. */
  min-height: 44px;
}

.qyg-post-photos-top {
  display: flex;
  align-items: center;
  gap: 7px;
}

.qyg-post-tile {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: var(--qyg-r-tile);
  background: var(--color-team-tint);
  font-size: 13px;
  line-height: 1;
}

.qyg-post-photos-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--qyg-ink);
}

.qyg-post-count {
  flex: none;
  border-radius: var(--qyg-r-pill);
  background: var(--qyg-bg-pill);
  padding: 2px 6px;
  font-size: 8.5px;
  font-weight: 700;
  color: var(--qyg-ink-secondary);
}

.qyg-post-chevron {
  flex: none;
  margin-left: auto;
  color: var(--qyg-ink-faint);
}

/*
 * Five square tiles across the card. Turn 15c draws them at 55px, which is
 * what five of them plus four gaps come to inside a 320px column - so the
 * size is a consequence of the count and the tiles share the width rather
 * than being told what it is. `aspect-ratio` keeps them square on a phone
 * wide enough to make 55px wrong.
 */
.qyg-post-strip {
  display: flex;
  gap: 5px;
}

.qyg-post-thumb,
.qyg-post-more {
  flex: 1 1 0;
  min-width: 0;
  aspect-ratio: 1;
  /* `--qyg-r-thumb`, not `--qyg-r-tile`: photographs, with the "+N" shaped to
     match them. */
  border-radius: var(--qyg-r-thumb);
}

.qyg-post-thumb {
  object-fit: cover;
  /* Something warm rather than a white flash while the thumbnail loads. */
  background: var(--qyg-bg-pill);
}

.qyg-post-more {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--qyg-bg-pill);
  font-size: 11px;
  font-weight: 800;
  color: var(--qyg-ink-secondary);
}

/* ---------- "email me my results" ---------- */

/*
 * The one outlined-accent element on the screen, and the only place the
 * guest's team colour appears as a border rather than a fill. That is the
 * whole design of it: everything else post-event is neutral or the *winning*
 * team's colour, so a 1.5px team border is enough to make one row the ask
 * without a second filled button competing with the banner.
 */
.qyg-email {
  border: 1.5px solid var(--color-team);
  padding: 10px 12px;
}

/*
 * The collapsed row. `flex-direction` is restated because this class shares
 * an element with `.qyg-post-card`, which stacks - every other block here is
 * a column and this one is the exception.
 *
 * 26px plus the card's 10px of padding is the design's 46px, which is also
 * over the 44px hit-target floor without the row having to look like a button.
 */
.qyg-email-row {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  min-height: 26px;
  text-align: left;
}

.qyg-email-emoji {
  flex: none;
  font-size: 14px;
  line-height: 1;
}

.qyg-email-label {
  min-width: 0;
  font-size: 12px;
  font-weight: 700;
  color: var(--color-team-dark);
}

.qyg-email-chevron {
  flex: none;
  margin-left: auto;
  font-weight: 800;
  color: var(--color-team);
}

.qyg-email-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qyg-email-message {
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--qyg-ink-secondary);
}

.qyg-email-fields {
  display: flex;
  gap: 6px;
}

.qyg-email-input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  border: 1.5px solid var(--qyg-border);
  border-radius: var(--qyg-r-row);
  background: var(--qyg-bg-card);
  padding: 0 12px;
  font-size: 14px;
  color: var(--qyg-ink);
}

.qyg-email-input::placeholder {
  color: var(--qyg-ink-faint);
}

.qyg-email-input:focus-visible {
  outline: none;
  border-color: var(--color-team);
}

.qyg-email-submit {
  flex: none;
  min-height: 44px;
  border-radius: var(--qyg-r-button);
  background: var(--color-team);
  padding: 0 14px;
  font-size: 13px;
  font-weight: 800;
  color: #fff;
}

.qyg-email-submit:disabled {
  background: var(--qyg-cta-disabled-bg);
  color: var(--qyg-cta-disabled-text);
}

.qyg-email-error {
  font-size: 11.5px;
  color: var(--qyg-danger);
}

.qyg-email-dismiss {
  align-self: flex-start;
  /* 11px of text with a 44px tap target around it; the negative margins hand
     the height straight back to the layout, so the form is still the height
     the design draws. Same trick as `.qyg-card-link`. */
  margin: -14px 0;
  padding: 14px 0;
  font-size: 11px;
  font-weight: 700;
  color: var(--qyg-ink-faint);
}

.qyg-email-done {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 26px;
  font-size: 12px;
  font-weight: 700;
  color: var(--color-team-dark);
}

/* ---------- "you made friends with" ---------- */

.qyg-post-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/*
 * Each name in their *own* team's colours, which post-event is half the room
 * in the opposition's - an introduction is cross-team by construction. Both
 * the tint and the dark come off the same team, so the pair is the one the
 * palette was contrast-checked as.
 */
.qyg-post-chip {
  border-radius: var(--qyg-r-pill);
  padding: 4px 10px;
  font-size: 11.5px;
  font-weight: 700;
}

/*!****************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/game-scoreboard.css ***!
  \****************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The scoreboard bar (handoff README §2 item 2, drawn at real size in
 * Turn 17). Every number here is either a `--qyg-*` lookup from `game-v2.css`
 * or a measurement off that frame.
 *
 * It is the one element in the whole design that puts both teams' colours side
 * by side, which is why the curated palette was checked for near-identical
 * pairs in Phase 0 rather than at some later point. White on `--color-team`
 * clears 4.5:1 by construction (see `team-colors.ts` and its test) - that
 * floor exists for this bar, whose 12.5px/700 names are nowhere near WCAG's
 * "large text".
 */

.qyg-scoreboard {
  position: relative;
  display: flex;
  align-items: stretch;
  overflow: hidden;
  width: 100%;
  /* Exactly the minimum hit target, and exactly what Turn 17 draws in all
     three themes: the whole bar is the tap into the leaderboard. */
  height: 44px;
  /* Rows rather than cards: Turn 17 gives the bar 8/12/99px across Classic,
     Modern and Playful, which is `--qyg-r-row` to the pixel. */
  border-radius: var(--qyg-r-row);
  box-shadow: var(--qyg-shadow-scoreboard);
  /* The one colour in here, and the reason the palette was darkened. */
  color: #fff;
  text-align: left;
}

/*
 * The two colour blocks.
 *
 * `.qyg-split-fill` (in `game-v2.css`) does the geometry: a layer as wide as
 * the whole bar, scaled down to its share, one anchored to each edge. Only
 * the background belongs here.
 */
.qyg-scoreboard-fill-own {
  background: var(--color-team);
}

.qyg-scoreboard-fill-opp {
  background: var(--color-team-opp);
}

/*
 * The 3px page-coloured gap where the blocks meet.
 *
 * It has to sit exactly on the seam, so it moves with the split - and it moves
 * by translating a layer as wide as the bar, because a percentage in
 * `translateX` is a percentage of the element's *own* width. Shifting `left`
 * instead would re-lay-out the bar on every frame of the transition, which is
 * the thing this whole design does not do.
 */
.qyg-scoreboard-divider {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform: translateX(calc(var(--qyg-split, 0.5) * 100%));
  transition: transform 0.4s ease;
}

.qyg-scoreboard-divider::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  /* Centred on the seam rather than starting at it, so neither block loses
     more of its width to the gap than the other. */
  left: -1.5px;
  width: 3px;
  background: var(--qyg-bg-page);
}

/*
 * The text over each block.
 *
 * `flex-basis` is a layout property and is deliberately not transitioned. It
 * is also unavoidable: the two scores face each other across the divider, so
 * they travel with it, and no transform moves a box's inner edge without
 * stretching what is inside it. The colours glide, the numbers step - see the
 * note in `Scoreboard.tsx`.
 *
 * `flex-shrink: 0` with `min-width: 0` is what makes the shares exact. The
 * bases sum to 100%, so nothing shrinks and nothing grows; without the
 * `min-width` a long team name would push its own block wider than its share.
 */
.qyg-scoreboard-cell {
  position: relative;
  display: flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 var(--qyg-cell-basis, 50%);
  min-width: 0;
  padding: 0 11px;
  /* A display slot: Turn 17 sets the Classic frame's team names in the serif
     while leaving the identity line beneath them in the UI sans. The weight
     stays 700 in every theme - `--qyg-display-weight` is for the slots where
     a theme's own weight is the point, and white on a saturated block is
     already as heavy as this bar wants to be. */
  /* Deliberately *not* the display face. A team's name and its score sit on a
     coloured block at 12.5px, and in Classic the serif made that row look like
     a different product from the rest of the screen - it is a label, not
     display type. Same for the identity line below it. */
  font-weight: 700;
  font-size: 12.5px;
}

/*
 * The right-hand block is the left one mirrored: score at the inner edge,
 * then the name, emoji and crown out to the rim. Reversing the direction
 * rather than the markup keeps the DOM in reading order and lets both blocks
 * share every rule above, including the score's `margin-left: auto` - which
 * in a reversed row absorbs the free space on the other side.
 */
.qyg-scoreboard-cell-end {
  flex-direction: row-reverse;
}

.qyg-scoreboard-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Never truncated, however narrow the block gets - a team can lose its name
   to an ellipsis, but a score that reads "1…" is worse than no scoreboard. */
.qyg-scoreboard-score {
  flex: none;
  margin-left: auto;
  font-size: 16px;
}

.qyg-scoreboard-crown,
.qyg-scoreboard-emoji {
  flex: none;
}

/* `game-v2.css` switches off the fills' transition for a guest who has asked
   their phone to stop moving things; the divider rides with the fills and has
   to go in the same breath, or the seam would slide across two blocks that
   have already arrived. */
@media (prefers-reduced-motion: reduce) {
  .qyg-scoreboard-divider {
    transition: none;
  }
}

/*
 * The same bar, not as a button.
 *
 * The home screen's bar opens the leaderboard; inside the leaderboard there is
 * nothing to open, so the sheet renders the bar on a plain `span`. This carries
 * the layout `.qyg-scoreboard` gets from being a button and drops the tap
 * affordance - it is one declaration rather than a second set of styles, which
 * is the point of the two sharing a component.
 */
.qyg-scoreboard-static {
  cursor: default;
}

/*!************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/join-screen.css ***!
  \************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The shared-QR join screen (handoff README §1, Turn 15a for the pre-event
 * variant).
 *
 * Plain CSS beside the component, matching `game-root-v2.css` and
 * `game-sheet.css`: the design is specified in tokens and exact pixels, and a
 * row of arbitrary-value Tailwind classes would hide both.
 *
 * The one structural difference from the home column is that the hero runs
 * edge to edge here, so the padding lives on the body below it rather than on
 * the page. Everything else is the same chrome - fixed warm neutrals, team
 * colour only on the two cards and the one CTA.
 */

.qyg-join {
  display: flex;
  flex-direction: column;
  /* Same cap as the home column and the sheets, so the three are one width on
     anything bigger than a phone. */
  margin: 0 auto;
  max-width: 36rem;
  min-height: 100dvh;
  background: var(--qyg-bg-page);
  font-family: var(--qyg-font-ui);
  color: var(--qyg-ink);
}

.qyg-join-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px 14px calc(20px + env(safe-area-inset-bottom));
}

/*
 * "⏳ 3 days to go", between the hero and the team pick (handoff §1,
 * pre-event variant).
 *
 * Neutral rather than team-coloured, and deliberately so: nothing on this
 * screen wears the guest's colour before they have chosen one, and the pill
 * appears above the choice.
 */
.qyg-join-countdown {
  align-self: center;
  border-radius: var(--qyg-r-pill);
  border: 1px solid var(--qyg-border);
  background: var(--qyg-bg-pill);
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 800;
  color: var(--qyg-link);
}

.qyg-join-pick {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.qyg-join-prompt {
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  color: var(--qyg-ink-strong);
}

.qyg-join-cards {
  display: flex;
  gap: 10px;
}

/*
 * One team: the card and the caption under it. Each column carries its *own*
 * team's variables as an inline style, which is why `--color-team` inside one
 * is never the value it has on the root - the two sit side by side and each
 * has to be its own colour before either is chosen.
 */
.qyg-join-choice {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.qyg-join-team {
  width: 100%;
  /* 68px, and comfortably past the 44px floor. */
  height: 68px;
  border-radius: var(--qyg-r-card);
  border: 1.5px solid var(--qyg-border);
  background: var(--qyg-bg-card);
  /* The team's readable-on-neutral variant. Never `--color-team`, which is
     sized for white text sitting on top of it rather than for being text. */
  color: var(--color-team-dark);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 0 6px;
  text-align: center;
}

.qyg-join-team-selected {
  border-color: var(--color-team);
  background: var(--color-team);
  /* White on `--color-team` is the pair the curated palette is tested at
     4.5:1 for; a team colour on a team colour is not. */
  color: #fff;
  box-shadow: var(--qyg-shadow-cta);
}

.qyg-join-team-emoji {
  font-size: 22px;
  line-height: 1;
}

.qyg-join-team-name {
  font-size: 14px;
  font-weight: 800;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/*
 * "41 playing", under the card rather than inside it: a long team name and a
 * caption would otherwise fight for the same 68px, and the caption stays
 * neutral when the card above it fills with colour.
 */
.qyg-join-count {
  text-align: center;
  font-size: 10.5px;
  color: var(--qyg-ink-faint);
}

.qyg-join-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.qyg-join-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.qyg-join-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--qyg-ink-strong);
}

/* "· optional" beside the email label. Not part of the label's string: it is
   a marker on the field, and gluing it on would make one message out of two
   facts (see the catalogue's note on assembling sentences). */
.qyg-join-optional {
  font-weight: 400;
  color: var(--qyg-ink-faint);
}

.qyg-join-input {
  height: 50px;
  width: 100%;
  border-radius: var(--qyg-r-inset);
  border: 1.5px solid var(--qyg-border);
  background: var(--qyg-bg-card);
  padding: 0 14px;
  /* 16px is not a design choice: anything smaller makes iOS Safari zoom the
     page in when the field takes focus, and it never zooms back out. */
  font-size: 16px;
  color: var(--qyg-ink);
  outline: none;
}

.qyg-join-input::placeholder {
  color: var(--qyg-ink-faint);
}

.qyg-join-input:focus {
  border-color: var(--color-team);
}

.qyg-join-help {
  font-size: 10.5px;
  color: var(--qyg-ink-faint);
}

/*
 * The one primary CTA. 52px, the guest's chosen colour, and the only place on
 * this screen that carries a shadow.
 */
.qyg-join-cta {
  height: 52px;
  border-radius: var(--qyg-r-button);
  background: var(--color-team);
  color: #fff;
  box-shadow: var(--qyg-shadow-cta);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 800;
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
}

/* Disabled is a state of the same button rather than a different one: the
   label is what changes as the form fills in, and the guest should be able to
   read where they are up to without the button moving. */
.qyg-join-cta:disabled {
  background: var(--qyg-cta-disabled-bg);
  color: var(--qyg-cta-disabled-text);
  box-shadow: none;
}

.qyg-join-error {
  font-size: 12.5px;
  color: var(--qyg-danger);
}

.qyg-join-recovery {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qyg-join-recovery-row {
  display: flex;
  gap: 8px;
}

.qyg-join-recovery-row .qyg-join-input {
  flex: 1;
  min-width: 0;
  height: 44px;
}

.qyg-join-recovery-button {
  flex: none;
  min-height: 44px;
  border-radius: var(--qyg-r-button);
  border: 1.5px solid var(--color-team);
  background: var(--qyg-bg-card);
  padding: 0 14px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--color-team-dark);
}

.qyg-join-reassurance {
  text-align: center;
  font-size: 10.5px;
  color: var(--qyg-ink-faint);
}

/*
 * The two things a guest can do before they have joined anything. They are
 * links rather than cards because they are not the job of this page - a guest
 * who came here to find their table should be able to, and then be looking at
 * the form again.
 */
.qyg-join-footer {
  display: flex;
  justify-content: center;
  /* Side by side on a 390px phone and stacked on a 320px one. Whichever it
     is, a label never breaks across two lines - see `white-space` below. */
  flex-wrap: wrap;
  gap: 0 20px;
  border-top: 1px solid var(--qyg-border);
  padding-top: 4px;
}

.qyg-join-footer-link {
  display: flex;
  align-items: center;
  white-space: nowrap;
  /* The design draws these as a 12.5px line; the hit-target rule is what
     makes them 44px tall. Same trade as the identity line. */
  min-height: 44px;
  padding: 0 4px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--qyg-link);
}

/* The spinner inside the CTA and the recovery button. Rotation is a transform,
   so this is on the compositor like everything else here. */
.qyg-join-spinner {
  width: 14px;
  height: 14px;
  flex: none;
  border-radius: var(--qyg-r-pill);
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: qyg-join-spin 0.7s linear infinite;
}

@keyframes qyg-join-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .qyg-join-spinner {
    animation-duration: 2.4s;
  }
}

/* The second line under "sent", for a guest whose inbox will stay empty. */

/* The screen a recovery link leaves behind. It replaces the form, so it can
   have the vertical room the form was using - centred, and roughly where the
   team cards were, so the eye does not have to go looking. */
.qyg-join-sent {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
  padding: 28px 8px 36px;
}

.qyg-join-sent-icon {
  font-size: 44px;
  line-height: 1;
}

.qyg-join-sent-title {
  margin: 6px 0 0;
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
  font-size: 24px;
  color: var(--qyg-ink);
}

.qyg-join-sent-body {
  margin: 0;
  max-width: 20rem;
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--qyg-ink-secondary);
  /* An address is the one thing here that must not be re-flowed into
     something that looks like a different address. */
  overflow-wrap: anywhere;
}

.qyg-join-sent-retry {
  margin: 10px 0 0;
  max-width: 20rem;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--qyg-ink-faint);
}

.qyg-join-sent-retry a {
  color: var(--qyg-ink-secondary);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

/*!*************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/welcome-gate.css ***!
  \*************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The welcome gate borrows the join screen's field, input and CTA wholesale
 * (`join-screen.css`), so all this file owns is the card they sit in - the
 * same elevated card the hero card uses, because in this state it *is* the
 * one card the evening is asking something in.
 */
.qyg-welcome {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  padding: 16px;
  border-radius: var(--qyg-r-card);
  background: var(--qyg-bg-card);
  box-shadow: var(--qyg-shadow-card);
}

/* The secondary way out, under the CTA. A link rather than a button, because
   it undoes something rather than doing it. */
.qyg-welcome-switch {
  align-self: center;
  min-height: 44px;
  padding: 0 8px;
  border: 0;
  background: none;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--qyg-link);
}

/*!*****************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/chips/game-chips.css ***!
  \*****************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The event chip and the glass rain (handoff README §Chips).
 *
 * Both are overlays rather than blocks in the column, so unlike the rest of
 * the v2 stylesheets nothing here participates in the page's layout at all -
 * which is also why both can animate freely: a transform on a fixed element
 * over the page costs the page nothing.
 *
 * Same convention as its neighbours: plain CSS beside the components, every
 * value either a `--qyg-*` lookup or a number the handoff gives explicitly.
 * The two keyframes live in `game-v2.css` with the rest of the motion, and
 * are reached through the `.qyg-anim-*` utilities so the reduced-motion rules
 * there apply here without being restated.
 */

/*
 * Top of the screen, 16px in, over everything.
 *
 * `fixed` rather than the mock's `absolute`: the mock's positioning context is
 * a 790px phone frame that cannot scroll, and this column can. An
 * announcement pinned to the top of the *document* would be posted above a
 * guest who has scrolled to the note row and never seen.
 *
 * Above the sheets (1100) on purpose. A round going live while somebody is
 * reading the leaderboard is exactly when the announcement matters most, and
 * the sheet only covers the bottom 86% anyway.
 */
.qyg-chip-layer {
  position: fixed;
  top: calc(16px + env(safe-area-inset-top));
  left: 0;
  right: 0;
  z-index: 1300;
  display: flex;
  justify-content: center;
  padding: 0 16px;
  /* Nothing here is a control, and a pill floating over the answer rows must
     not be able to eat a tap meant for one. */
  pointer-events: none;
}

.qyg-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  /* The column's own cap, less its inset, so on a laptop the chip is the
     width of the screen it belongs to rather than the width of the window. */
  max-width: calc(36rem - 32px);
  border-radius: var(--qyg-r-pill);
  background: var(--qyg-bg-card);
  padding: 9px 15px;
  box-shadow: var(--qyg-shadow-chip);
  color: var(--qyg-ink);
  font-family: var(--qyg-font-ui);
}

/*
 * The game-wide announcement. Ink ground, and the lightest declared token for
 * the text - the mock's own #f7f4ee sits between `--qyg-bg-page` and
 * `--qyg-bg-card` and is not a token, so this takes the nearer of the two
 * rather than inventing a value.
 *
 * No player name ever lands on this ground. That is a property of
 * `eventChip`: every content type that carries a `ChipName` is built as
 * `light`. Team colours were darkened until white clears 4.5:1 on them and
 * there is no tested variant for a team colour *on* ink, so a dark chip with
 * a name in it would be the one surface in the design nobody has checked.
 */
.qyg-chip-dark {
  background: var(--qyg-ink);
  color: var(--qyg-bg-page);
}

.qyg-chip-emoji {
  flex: none;
  font-size: 15px;
  line-height: 1;
}

.qyg-chip-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12.5px;
}

/* The actor's name, in their own team-dark - which is set as an inline style
   per name, because the two names in an introduction belong to two teams. */
.qyg-chip-actor {
  font-weight: 700;
}

/*
 * "+10PT". Uppercased here rather than in the catalogue, like the eyebrows:
 * shouting baked into a string survives translation into languages where it
 * is wrong.
 *
 * `--qyg-ink-strong` rather than the mock's `--qyg-ink-secondary`: at 10px
 * bold the secondary ink is 3.5:1 on the pill ground, and this is the same
 * floor the palette was darkened for.
 */
.qyg-chip-pill {
  flex: none;
  margin-left: auto;
  border-radius: var(--qyg-r-pill);
  background: var(--qyg-bg-pill);
  padding: 2px 7px;
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--qyg-ink-strong);
}

.qyg-chip-dark .qyg-chip-pill {
  background: var(--qyg-ink-strong);
  color: var(--qyg-bg-page);
}

/*
 * Four glasses down the whole screen. Fixed and full-bleed rather than inside
 * the column, because the fall is measured in viewport height (110vh in the
 * keyframe) and a column shorter than the window would clip it halfway.
 *
 * Under the chip and over everything else: the rain is the toast's answer and
 * the chip is what the toast said.
 */
.qyg-rain {
  position: fixed;
  inset: 0;
  z-index: 1290;
  overflow: hidden;
  pointer-events: none;
}

.qyg-rain-drop {
  position: absolute;
  top: 0;
  line-height: 1;
}

/*!************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/photos/photo-viewer.css ***!
  \************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The full-screen photo viewer: the one dark screen in the product, so the
 * photographs glow instead of competing with a page of cream around them.
 *
 * Lifted out of `game-photos.css` unchanged when `PhotoViewerShell` was shared
 * with the album page at `/album/{token}`, so the chrome travels with the
 * component rather than staying behind in the guest game's stylesheet. Every
 * value is either a `--qyg-*` lookup from `game-v2.css` or a number the design
 * handoff gives explicitly (README §6): the 38x48 overlay arrows, the 36rem
 * column, the 0.2s cross-fade.
 *
 * The last three blocks - the like button, the "your own photo" pill and the
 * delete - are the guest game's rather than the shell's. They stay here
 * because they are viewer chrome in viewer colours, and splitting one dark
 * screen's styling across two files to save a few hundred bytes on a page that
 * does not use them is not a trade worth making.
 */

.qyg-viewer {
  position: fixed;
  inset: 0;
  z-index: 1201;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--qyg-viewer-bg);
  /*
   * Two text colours that only exist on this screen. Every other `--qyg-ink-*`
   * is defined for the cream page and would disappear on `#221a1e`; these two
   * are the handoff's, and they are local rather than in `game-v2.css`
   * because nothing outside this screen has a dark surface to put text on.
   */
  --qyg-viewer-ink: #e5ded1;
  --qyg-viewer-ink-faint: #a39b88;
}

.qyg-viewer-column {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0 auto;
  width: 100%;
  max-width: 36rem;
  min-height: 100%;
  padding: 12px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
}

.qyg-viewer-header {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

.qyg-viewer-back {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  margin-left: -8px;
  padding: 0 8px;
  color: var(--qyg-bg-page);
  font-size: 15px;
  font-weight: 800;
}

.qyg-viewer-counter {
  margin-left: auto;
  font-family: var(--qyg-font-mono);
  font-size: 12px;
  color: var(--qyg-viewer-ink-faint);
}

.qyg-viewer-frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--qyg-r-photo);
  background: #000;
}

/*
 * Square, like the grid cell it was tapped from, so swiping through a wall of
 * portrait and landscape shots does not make the buttons underneath jump.
 *
 * `contain`, not `cover`, and that is the one place this diverges from the
 * mock: the grid already crops every photo to a square, and if the viewer
 * crops it too then part of somebody's photograph exists nowhere in the app.
 * A portrait shot letterboxes against the frame's black instead, which on this
 * backdrop reads as a frame rather than as a mistake.
 */
.qyg-viewer-image {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  /*
   * Positioned so that it paints over the thumbnail below. Both sit at the
   * same stacking level, so it is document order that decides, and this one
   * comes second.
   */
  position: relative;
  /*
   * Revealed by `.is-loaded` rather than by an animation on mount. The viewer
   * remounts for every photograph, so an unconditional fade would run while
   * the picture was still arriving and finish before it got here - which is
   * the flicker, not a cure for it. Tying the fade to the load event means it
   * is always a cross-fade from the thumbnail to the real thing.
   */
  opacity: 0;
  transition: opacity 0.2s ease;
}

.qyg-viewer-image.is-loaded {
  opacity: 1;
}

/*
 * The thumbnail the grid has already loaded, standing in until the full-size
 * photograph arrives.
 *
 * It lines up exactly because the frame is precisely the square the image
 * above occupies - the image is the only thing in it that takes up room - so
 * `inset: 0` plus the same `contain` letterboxes both identically, and the big
 * one lands on the small one rather than beside it.
 */
.qyg-viewer-thumb {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/*
 * The overlay arrows. The handoff draws them 38x48; the button around them is
 * 44 wide so the target clears the minimum, with the painted box centred
 * inside it. Nothing about the picture changes - only how much of it counts as
 * "next".
 */
.qyg-viewer-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 56px;
}

.qyg-viewer-nav-prev {
  left: 5px;
}

.qyg-viewer-nav-next {
  right: 5px;
}

.qyg-viewer-nav span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 48px;
  border-radius: 12px;
  background: rgba(20, 14, 17, 0.45);
  color: #fff;
  font-size: 20px;
  font-weight: 800;
  line-height: 1;
}

.qyg-viewer-by {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 4px;
  font-size: 13px;
  color: var(--qyg-viewer-ink);
}

.qyg-viewer-name {
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.qyg-viewer-time {
  margin-left: auto;
  flex: none;
  font-family: var(--qyg-font-mono);
  font-size: 11px;
  color: var(--qyg-viewer-ink-faint);
}

.qyg-viewer-actions {
  display: flex;
  gap: 8px;
}

.qyg-viewer-like {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 48px;
  border-radius: var(--qyg-r-button);
  background: var(--color-team);
  color: #fff;
  font-size: 14px;
  font-weight: 800;
}

/*
 * Liked is a dark neutral, not a lighter tint of the team colour: the button
 * has to say "done" from the corner of an eye, and on this backdrop a change
 * of shade would not. It also takes the one saturated thing on the screen back
 * out once the guest has finished with it.
 */
.qyg-viewer-like.is-liked {
  background: var(--qyg-ink-strong);
}

/*
 * Your own photo. You cannot like it - the server refuses, and has since
 * likes existed - so the button becomes the count it would have changed
 * rather than a control that does nothing when tapped.
 */
.qyg-viewer-own {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 48px;
  border-radius: var(--qyg-r-button);
  border: 1.5px solid var(--qyg-ink-strong);
  color: var(--qyg-viewer-ink-faint);
  font-size: 13px;
  font-weight: 700;
}

/*
 * The mock sets this caption in `--qyg-ink-tertiary`, which is a colour chosen
 * to be quiet on cream and lands at about 4.3:1 on `#221a1e`. One step lighter
 * clears the floor and is still plainly a footnote.
 */
.qyg-viewer-note {
  padding: 0 12px;
  color: var(--qyg-viewer-ink-faint);
  font-size: 10.5px;
  line-height: 1.5;
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  /* No cross-fade; the photograph simply replaces the thumbnail the moment it
     is there. The thumbnail underneath is not motion, so it stays - it is what
     keeps the frame from going black, which is the whole point. */
  .qyg-viewer-image {
    transition: none;
  }
}

/*
 * "Remove", on your own photo only. Deliberately quiet - it is a way out of a
 * mistake, not something to invite - so it is a text button in the muted ink
 * rather than anything in `--qyg-danger`, and it only turns red on the second
 * tap, when it is about to do something.
 */
.qyg-viewer-delete {
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  font-size: 12px;
  font-weight: 700;
  color: var(--qyg-ink-tertiary);
}

.qyg-viewer-delete:disabled {
  opacity: 0.6;
}

.qyg-viewer-delete.is-confirming {
  color: var(--qyg-danger);
}

/* ------------------------------------------------- the album's own footer */

/*
 * "Save this photo", on the album page only. A link rather than a button,
 * because that is what it is: the 1600px copy the frame is already showing,
 * opened on its own so a phone can long-press it. Quiet, in the same muted ink
 * as the note below it - the loud way to get the photographs is the download
 * at the top of the page, which has the full-size files in it.
 */
.qyg-viewer-save {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 44px;
  border-radius: var(--qyg-r-button);
  border: 1.5px solid var(--qyg-ink-strong);
  color: var(--qyg-viewer-ink);
  font-size: 13px;
  font-weight: 700;
}

/*!*******************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/photos/game-photos.css ***!
  \*******************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * Chrome for the v2 photo wall (handoff README §6).
 *
 * Every value here is either a `--qyg-*` lookup from `game-v2.css` or a number
 * the handoff gives explicitly - the 4px grid gap, the like-count text shadow.
 * Nothing invents a colour.
 *
 * The viewer that opens on top of this used to live at the bottom of this
 * file. It moved to `components/photos/photo-viewer.css` unchanged, next to
 * `PhotoViewerShell`, when the album page started using the same frame - so
 * the rules are loaded by the component that needs them rather than by
 * whichever screen happens to mount it.
 *
 * This and the viewer are the only two guest screens that are not a scroll
 * column inside the game: they cover it. That is deliberate (README §6, plan
 * §4.1) - taking and looking at photos is a different mode of the evening,
 * and it should feel like a place you went to rather than a panel that slid
 * up.
 */

/*
 * Above everything, including the sheet layer at 1100/1101. A full screen and
 * a bottom sheet never coexist - a sheet is an informational surface on the
 * home screen, and reaching the wall is a navigation away from it - but if a
 * stale sheet ever were still mounted underneath, covering it is the right
 * failure rather than being covered by it.
 */
.qyg-photos {
  position: fixed;
  inset: 0;
  z-index: 1200;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--qyg-bg-page);
}

/* The same column the game lives in: capped, centred, 12px of side padding. */
.qyg-photos-column {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin: 0 auto;
  width: 100%;
  max-width: 36rem;
  min-height: 100%;
  padding: 12px;
  /* The home indicator sits over the last row of thumbnails otherwise. */
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
}

.qyg-photos-header {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

/*
 * "‹ Back" is a 44px target with its padding pulled back out of the layout, so
 * the label still lines up with the grid's left edge while the thumb gets the
 * whole corner.
 */
.qyg-photos-back {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  margin-left: -8px;
  padding: 0 8px;
  font-size: 15px;
  font-weight: 800;
  color: var(--qyg-ink);
}

.qyg-photos-title {
  margin-left: auto;
  font-family: var(--qyg-font-display);
  font-size: 15px;
  font-weight: var(--qyg-weight-display);
  color: var(--qyg-ink);
}

.qyg-photos-title-alone {
  margin-right: auto;
}

.qyg-photos-count {
  margin-left: auto;
  border-radius: var(--qyg-r-pill);
  padding: 3px 8px;
  background: var(--qyg-bg-pill);
  color: var(--qyg-ink-secondary);
  font-size: 10px;
  font-weight: 700;
  /* Capitals live here, never in the catalogue - see `messages/en.ts`. */
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* The one primary CTA on the screen, and the only team-coloured surface on it. */
.qyg-photos-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 48px;
  border-radius: var(--qyg-r-button);
  background: var(--color-team);
  box-shadow: var(--qyg-shadow-cta);
  color: #fff;
  font-size: 14.5px;
  font-weight: 800;
}

/*
 * The only time this button is disabled is while it is uploading, so it keeps
 * its colour and its white label rather than taking the `--qyg-cta-disabled-*`
 * pair. Those are for a CTA the guest has not earned yet - a join form with no
 * name in it - and they are deliberately quiet, which is the wrong thing to be
 * when the text says "adding photo 2 of 5" and the guest is waiting to read it.
 */
.qyg-photos-cta:disabled {
  box-shadow: none;
  cursor: default;
}

/*
 * The upload spinner. A border-and-rotate rather than an image, and it turns
 * the only way anything is allowed to move here: `transform` on the
 * compositor, while the main thread is busy decoding a twelve-megapixel photo.
 */
.qyg-photos-spinner {
  width: 15px;
  height: 15px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: qyg-photo-spin 0.7s linear infinite;
}

@keyframes qyg-photo-spin {
  to {
    transform: rotate(360deg);
  }
}

/*
 * Deliberately not stood down under `prefers-reduced-motion`: it is the only
 * thing on the screen saying the upload has not stalled, and a still one says
 * the opposite. The viewer's cross-fade is stood down, in its own stylesheet.
 */

.qyg-photos-error {
  border-radius: var(--qyg-r-inset);
  padding: 9px 11px;
  background: var(--qyg-bg-card);
  border: 1px solid var(--qyg-border);
  color: var(--qyg-danger);
  font-size: 12.5px;
  line-height: 1.4;
}

.qyg-photos-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}

.qyg-photos-cell {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--qyg-r-thumb);
  /* Something warm rather than a white flash while the thumbnail loads. */
  background: var(--qyg-bg-pill);
}

.qyg-photos-cell img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * The like count sits on the photograph itself, so it carries its own contrast
 * rather than trusting whatever happens to be in that corner of the picture.
 *
 * The cell clips to `--qyg-r-thumb`, so this inset has to clear the corner arc
 * at the largest value any theme gives that token. Playful's 16px is that
 * value: the nearest corner of this box lands about 1px inside the arc and
 * the first glyph several px further in again, so nothing is cut. A larger
 * thumbnail radius would start eating the number, so move this inset in with
 * it if one is ever chosen.
 */
.qyg-photos-likes {
  position: absolute;
  left: 6px;
  bottom: 5px;
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

.qyg-photos-hint,
.qyg-photos-empty {
  padding: 2px 12px;
  color: var(--qyg-ink-faint);
  font-size: 10.5px;
  line-height: 1.5;
  text-align: center;
}

.qyg-photos-empty {
  padding-top: 18px;
  font-size: 12.5px;
  color: var(--qyg-ink-secondary);
}

.qyg-photos-debug {
  font-family: var(--qyg-font-mono);
  font-size: 10px;
  color: var(--qyg-ink-faint);
  word-break: break-all;
}

/*!***********************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/game-sheet.css ***!
  \***********************************************************************************************************************************************************************************************************************************************************************************/
/*
 * Chrome for the v2 bottom sheets (handoff README §5).
 *
 * Everything here is either a `--qyg-*` lookup from `game-v2.css` or a
 * deliberate override of a rule vaul injects into the document head when it
 * is imported. That injected <style> lands after Next's own stylesheet link,
 * so a plain class never beats it on a tie: the selectors below that look
 * absurdly specific are matched against vaul's own and won by one attribute.
 */

.qyg-sheet-scrim {
  position: fixed;
  inset: 0;
  /* Above the sticky demo banner and the v1 team backdrop, both z-1000. */
  z-index: 1100;
  background: var(--qyg-scrim-sheet);
}

.qyg-sheet {
  position: fixed;
  right: 0;
  /* Above the keyboard rather than behind it - see `visual-viewport.ts`. Zero
     whenever there is no keyboard, which is every desktop and most of the
     evening. */
  bottom: var(--qyg-keyboard-inset, 0px);
  left: 0;
  z-index: 1101;
  display: flex;
  flex-direction: column;
  /* The game column is capped at max-w-xl; an uncapped sheet would be a
     letterbox on a laptop while the content above it stays narrow. */
  margin: 0 auto;
  max-width: 36rem;
  /* vh first, purely as a fallback for browsers without dvh. On iOS Safari vh
     is measured against the viewport with the URL bar *collapsed*, so a sheet
     sized in vh is around 60px too tall exactly when the bar is showing -
     which is when a guest opens their first one. */
  /*
   * Clamped against the *visible* height, not just the layout one. `dvh` knows
   * about the browser's chrome and not about the iOS keyboard, and a sheet is
   * anchored to the bottom - so a sheet too tall for the space left loses its
   * top, which is where its heading and any input are. `--qyg-visual-h` is
   * published by `visual-viewport.ts`; the `dvh` inside the `min()` is what
   * applies before the first frame and on browsers without the API.
   */
  max-height: 86vh;
  max-height: min(86dvh, var(--qyg-visual-h, 86dvh));
  background: var(--qyg-bg-card);
  /* Follows the event's theme: 16, 22 or 26 depending on the bundle. */
  border-top-left-radius: var(--qyg-r-sheet);
  border-top-right-radius: var(--qyg-r-sheet);
  box-shadow: var(--qyg-shadow-sheet);
  outline: none;
}

/*
 * Entry only, and by name rather than through the ready-made
 * `.qyg-anim-sheet-up` utility, which loses to vaul's own
 * `animation-name: slideFromBottom` on specificity.
 *
 * vaul's exit is left exactly as it is, at its own 0.5s, because the JS keeps
 * the sheet mounted for a hardcoded 500ms after a close: a shorter exit
 * animation finishes early, the transform snaps back to zero because nothing
 * holds the end state, and the sheet flashes back into view on its way out.
 */
.qyg-sheet[data-vaul-drawer][data-vaul-snap-points="false"][data-vaul-drawer-direction="bottom"][data-state="open"] {
  animation-name: qyg-sheet-up;
  animation-duration: 0.22s;
  animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
}

.qyg-sheet-grip {
  display: flex;
  justify-content: center;
  /* 44px of grabbable sheet above the content, per the handoff's hit-target
     rule. vaul's own hit area is that size but centred on the bar, so on its
     own it would reach into the first row of content. */
  padding: 10px 0 6px;
}

.qyg-sheet-handle[data-vaul-handle] {
  width: 38px;
  height: 4px;
  border-radius: 999px;
  opacity: 1;
  background: var(--qyg-border-strong);
}

.qyg-sheet-header {
  padding: 0 16px 10px;
}

.qyg-sheet-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--qyg-ink);
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
}

.qyg-sheet-scroller {
  /* min-height:0 is what actually lets this shrink inside the flex column;
     without it the scroller takes its content height and the sheet grows past
     its max-height instead of scrolling. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Stops a flick at either end of the list from rubber-banding the game
     screen behind the sheet. */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0 16px 16px;
  /* The home indicator eats the bottom of the last row otherwise. */
  padding-bottom: calc(16px + env(safe-area-inset-bottom));
}

/*
 * The seat sheet, which is a list to be scrolled rather than a statement to be
 * read.
 *
 * The `min-height` is the point of this class, not the `max-height`. A sheet is
 * sized by its content, so as a guest typed their name the panel collapsed
 * around the shrinking list - four matches, then one, then a strip 200px tall
 * with an input in it. A floor keeps it the same shape from the moment it
 * opens, so filtering happens inside a panel instead of dragging the panel
 * about.
 *
 * The ceiling goes up a little as well, because with a whole guest list in it
 * this is the one sheet that wants the room. 86vh leaves a strip of the game
 * visible behind every sheet, which is what tells a guest they are on top of
 * something - keep that, just less of it.
 */
.qyg-sheet-tall {
  min-height: 60vh;
  /*
   * The floor gives way to the keyboard. `min()` here is doing the opposite of
   * what it looks like: it lowers the *minimum*, so when the visible height
   * collapses the sheet is allowed to be shorter than 60dvh instead of being
   * pushed off the top of the screen by its own floor.
   */
  min-height: min(60dvh, var(--qyg-visual-h, 60dvh));
  max-height: 94vh;
  max-height: min(94dvh, var(--qyg-visual-h, 94dvh));
}

/*!*************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/components/game/v2/game-root-v2.css ***!
  \*************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * The v2 home column and its header (handoff README §2, items 1 and the
 * column itself). Everything here is either a `--qyg-*` lookup from
 * `game-v2.css` or a measurement straight off Turn 17.
 *
 * Written as plain CSS beside the component rather than as Tailwind classes,
 * matching `game-sheet.css`: the design is specified in tokens and exact
 * pixel values, and a row of arbitrary-value utilities would hide both.
 */

.qyg-root {
  /* The one place the display weight per theme lives.
     `game-v2.css` carries the display *font* for each bundle but not its
     weight, because a weight is not a token the rest of the design uses - the
     three bundles are Noto Serif 700, the UI sans at 800, Nunito 900, and
     only display slots ever ask. Declared before the theme classes below so
     source order lets a theme win on equal specificity. */
  --qyg-display-weight: 800;

  display: flex;
  flex-direction: column;
  /* 12px sides, 8-9px between blocks. Tighter than it looks on paper: the
     column is nearly full-bleed on a 320px phone and the cards carry their
     own padding. */
  gap: 9px;
  padding: 12px;
  /* Same cap as the sheets, so a sheet and the screen it slides over are the
     same width on a laptop. */
  margin: 0 auto;
  max-width: 36rem;
  min-height: 100dvh;
  background: var(--qyg-bg-page);
  font-family: var(--qyg-font-ui);
  color: var(--qyg-ink);
  /* iOS pads the home indicator into the page rather than out of it. */
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
}

.qyg-theme-classic {
  --qyg-display-weight: 700;
}

.qyg-theme-modern {
  --qyg-display-weight: 800;
}

.qyg-theme-playful {
  --qyg-display-weight: 900;
}

/*
 * The hero photo. One image, a scrim, and the event's name sitting in the
 * gradient's darkest band - which is what makes the white text safe on a
 * photo nobody vetted. No per-photo tuning, no fallback colour behind it.
 */
.qyg-hero {
  position: relative;
  height: 150px;
  border-radius: var(--qyg-r-photo);
  overflow: hidden;
}

/* Post-event the photo shrinks and the caption becomes the wedding date: the
   screen stops being a game and starts being a keepsake (handoff §9). */
.qyg-hero-keepsake {
  height: 120px;
}

/*
 * The join screen's hero (handoff §1). Taller, square and edge to edge, with
 * the caption centred rather than tucked into the corner.
 *
 * It is bigger here because it is doing a different job. On the home screen
 * the photo is a header above the evening's controls; on the join screen it
 * is the whole of the argument for filling the form in - a guest who has just
 * scanned a sign on a table has no idea what this page is until they
 * recognise the couple on it.
 */
.qyg-hero-join {
  height: 210px;
  border-radius: 0;
}

.qyg-hero-join .qyg-hero-caption {
  bottom: 16px;
  text-align: center;
}

.qyg-hero-join .qyg-hero-name {
  font-size: 26px;
}

.qyg-hero-join .qyg-hero-eyebrow {
  font-size: 10.5px;
  letter-spacing: 0.22em;
}

.qyg-hero-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.qyg-hero-scrim {
  position: absolute;
  inset: 0;
  background: var(--qyg-scrim-photo);
}

.qyg-hero-caption {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 10px;
  color: #fff;
  /* Belt and braces with the scrim, for the white-sky photo that lands one
     day and cannot be tuned for. */
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.qyg-hero-name {
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-display-weight);
  font-size: 19px;
  line-height: 1.15;
  /* Two lines and then the ellipsis: the photo is a fixed height, so a long
     title has to stop rather than push the scrim off the bottom of it. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.qyg-hero-eyebrow {
  font-size: 9.5px;
  letter-spacing: 0.18em;
  /* Upper-cased here rather than in the catalogue: capitals in a message
     survive translation into languages where they are wrong. */
  text-transform: uppercase;
  opacity: 0.92;
}

.qyg-hero-date {
  font-size: 10.5px;
  opacity: 0.92;
}

/*
 * The no-photo masthead (handoff §2 item 1, Turn 16a/16c).
 *
 * A transparent block, not a card and never a placeholder image: no image
 * means no fake image. Event name over a date between two short rules, and
 * nothing else - no monogram, no eyebrow. It replaces a singular hero image,
 * so it is singular too, and the same block serves join, home and post-event.
 */
.qyg-masthead {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 18px 16px 14px;
  min-height: 70px;
  text-align: center;
}

.qyg-masthead-name {
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-display-weight);
  /*
   * Wrap to two lines first, shrink only if that is not enough - which is the
   * design's rule and is not something CSS can decide on its own, since it
   * cannot see how many lines a size would produce. The component sets this
   * from the title's length; the floor of 20px is the design's.
   */
  font-size: var(--qyg-masthead-size, 26px);
  line-height: 1.12;
  color: var(--qyg-ink);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: break-word;
}

.qyg-masthead-dateline {
  display: flex;
  align-items: center;
  gap: 8px;
}

.qyg-masthead-date {
  font-size: 10.5px;
  color: var(--qyg-ink-faint);
}

.qyg-masthead-rule {
  width: 28px;
  height: 1.5px;
  background: var(--qyg-border-strong);
  flex: none;
}

/*
 * The one exception to "a theme only swaps the display font and the radii".
 *
 * The handoff is explicit that the masthead's rule treatment is part of each
 * bundle - Classic hairlines with an italic date, Modern plain, Playful a
 * team-coloured dot at each end - and this is the only element in the whole
 * design where that is true. Keeping the exception here, next to the element
 * it applies to, rather than widening the theme classes in `game-v2.css`.
 */
.qyg-theme-classic .qyg-masthead-rule {
  height: 1px;
}

.qyg-theme-classic .qyg-masthead-date {
  font-style: italic;
}

.qyg-theme-playful .qyg-masthead-rule {
  width: 4px;
  height: 4px;
  border-radius: var(--qyg-r-pill);
}

/* One dot per team, in the order the scoreboard draws them: the guest's own
   side first. The masthead is the only place on the screen that shows both
   colours without showing a score. */
.qyg-theme-playful .qyg-masthead-rule-start {
  background: var(--color-team);
}

.qyg-theme-playful .qyg-masthead-rule-end {
  background: var(--color-team-opp);
}

.qyg-theme-playful .qyg-masthead-date {
  font-family: var(--qyg-font-display);
  font-weight: var(--qyg-weight-display);
}

/*
 * Slot placeholders.
 *
 * Deliberately ugly. Each of the six is a real component with a real props
 * interface (`slots.ts`) and a stand-in body, so that the column can be seen
 * and navigated while four other people build the real ones. Anything that
 * looked finished here would be copied.
 */
.qyg-slot {
  border: 1px dashed var(--qyg-border-strong);
  border-radius: var(--qyg-r-card);
  background: var(--qyg-bg-card);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-height: 44px;
  justify-content: center;
  /* Four of the six placeholders are buttons, which centre their text by
     default - without this the column looks like two different designs. */
  text-align: left;
}

.qyg-slot-name {
  font-family: var(--qyg-font-mono);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--qyg-ink-tertiary);
}

.qyg-slot-line {
  font-size: 12.5px;
  color: var(--qyg-ink-secondary);
}

.qyg-slot-strong {
  color: var(--color-team-dark);
  font-weight: 700;
}

/*
 * The host for the two full screens (§6, §7).
 *
 * It exists because the screens disagree about what they are: the photo wall
 * is `position: fixed` and covers whatever is under it, while make-a-friend is
 * a `min-h-dvh` section that expects to *be* the page - which is true in its
 * own preview harness and false here, where the home column is above it in the
 * same flow. Rather than rewrite either to match the other, the host is the
 * thing that covers, and both are simply inside it.
 *
 * 1200 puts a screen above the sheets (1100) and below the chips (1300),
 * which is the wall's own z-index and the order the design asks for: a
 * celebration still lands on top of wherever the guest is.
 */
.qyg-screen-host {
  position: fixed;
  inset: 0;
  z-index: 1200;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--qyg-bg-page);
}

/*!**********************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!./src/app/[locale]/signup/step-questions-stack.css ***!
  \**********************************************************************************************************************************************************************************************************************************************************************************************/
/*
 * Step 3's question stack (design/landing-v2/Signup Funnel - Wizard v2.dc.html,
 * the `showStack` column). The cards keep the design's inline styling like the
 * rest of the wizard; what lives here is everything inline styles cannot say:
 * keyframes, hover and press states, and the tilt.
 *
 * Every card is wrapped in a `.sq-slot`, and that split is load-bearing rather
 * than tidiness. A card has up to three animations in its life - arriving,
 * pulsing while the model writes, leaving - and CSS `animation` is one
 * property: put them on the same element and the class that happens to be
 * last in this file silently wins, so a card would restart its arrival slide
 * every time it started or stopped pulsing, which is exactly the layout jump
 * this step must not have. The slot owns arriving and leaving, the card owns
 * the pulse and the tilt, and they compose because they are different
 * elements.
 */

/* New cards arrive at the top of the pile, so they come *from* above. */
@keyframes sq-slot-enter {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Removal: the card goes back the way it came. */
@keyframes sq-slot-leave {
  from {
    opacity: 1;
    transform: none;
  }
  to {
    opacity: 0;
    transform: translateY(-6px) scale(0.96);
  }
}

.sq-slot {
  animation: sq-slot-enter 250ms ease-out;
}

/* The starter pack has always been in the pile; it should not slide in. */
.sq-slot-static {
  animation: none;
}

.sq-slot-leaving {
  animation: sq-slot-leave 220ms ease-in forwards;
  pointer-events: none;
}

.sq-card {
  transform: rotate(var(--sq-tilt, 0deg));
}

@keyframes sq-writing-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

.sq-card-writing {
  animation: sq-writing-pulse 1.1s ease-in-out infinite;
}

/* The quiet action row under a written question. */
.sq-actions {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 8px;
}

.sq-action {
  padding: 0;
  background: none;
  border: none;
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--lp-muted-2);
  cursor: pointer;
  transition:
    color 0.15s,
    opacity 0.15s;
}

.sq-action:hover {
  color: var(--lp-ink);
}

.sq-action:active {
  opacity: 0.55;
}

.sq-action:disabled {
  opacity: 0.4;
  cursor: default;
}

.sq-action:disabled:hover {
  color: var(--lp-muted-2);
}

.sq-action-sep {
  font-size: 11px;
  line-height: 1.2;
  color: var(--lp-border-strong);
  user-select: none;
}

/* Tweak's in-place edit form. Narrow column, so everything is small. */
.sq-edit {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}

.sq-edit-label {
  display: block;
  margin-bottom: 2px;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--lp-muted-2);
}

.sq-edit-input {
  width: 100%;
  box-sizing: border-box;
  padding: 6px 8px;
  font: inherit;
  font-size: 11.5px;
  color: var(--lp-ink);
  background: var(--lp-bg);
  border: 1px solid var(--lp-border-strong);
  border-radius: 8px;
}

.sq-edit-input:focus {
  outline: 2px solid var(--lp-pink);
  outline-offset: -1px;
}

@media (prefers-reduced-motion: reduce) {
  .sq-slot,
  .sq-slot-leaving {
    animation: none;
  }
  .sq-slot-leaving {
    opacity: 0;
  }
  .sq-card-writing {
    animation-duration: 3s;
  }
}

