/* Шрифты и иконки — свои файлы, не Google. Собирается: npm run fonts. */

/*
 * Шрифты и иконки, раздаются нашим сервером, а не Google.
 * Файл собран скриптом scripts/fetch-fonts.js — руками не править,
 * перезапустить: npm run fonts. Лицензии — desktop/fonts/LICENSES.md.
 */

/* cyrillic-ext */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-cyrillic-ext.woff2?v=1a0609a15c) 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: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-cyrillic.woff2?v=c47e6493c4) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-vietnamese.woff2?v=c50ce0ffd2) 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: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-latin-ext.woff2?v=c33f88bf77) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-latin.woff2?v=b6711decba) 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: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-cyrillic-ext.woff2?v=1a0609a15c) 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: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-cyrillic.woff2?v=c47e6493c4) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-vietnamese.woff2?v=c50ce0ffd2) 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: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-latin-ext.woff2?v=c33f88bf77) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/montserrat-latin.woff2?v=b6711decba) 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: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/onest-cyrillic-ext.woff2?v=310002a221) 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: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/onest-cyrillic.woff2?v=9b14495282) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* math */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/onest-math.woff2?v=767cb74d60) 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-209F, 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;
}
/* symbols */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/onest-symbols.woff2?v=1f418388ee) format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AE, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F8D0-1F8D8, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FAC6, U+1FAC8, U+1FACC-1FADD, U+1FADF-1FAEB, U+1FAEF-1FAFA, U+1FB00-1FBFF;
}
/* vietnamese */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/onest-vietnamese.woff2?v=576e2f6b7d) 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: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/onest-latin-ext.woff2?v=2e84fbcaba) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/onest-latin.woff2?v=324d4be3f2) 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: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/onest-cyrillic-ext.woff2?v=310002a221) 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: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/onest-cyrillic.woff2?v=9b14495282) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* math */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/onest-math.woff2?v=767cb74d60) 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-209F, 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;
}
/* symbols */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/onest-symbols.woff2?v=1f418388ee) format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AE, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F8D0-1F8D8, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FAC6, U+1FAC8, U+1FACC-1FADD, U+1FADF-1FAEB, U+1FAEF-1FAFA, U+1FB00-1FBFF;
}
/* vietnamese */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/onest-vietnamese.woff2?v=576e2f6b7d) 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: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/onest-latin-ext.woff2?v=2e84fbcaba) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/onest-latin.woff2?v=324d4be3f2) 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: 'Unbounded';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-cyrillic-ext.woff2?v=47e3a40d07) 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: 'Unbounded';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-cyrillic.woff2?v=3e88c0f888) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-vietnamese.woff2?v=d1b9d9d63f) 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: 'Unbounded';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-latin-ext.woff2?v=fa9fd91cd1) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-latin.woff2?v=aef5c24657) 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: 'Unbounded';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-cyrillic-ext.woff2?v=47e3a40d07) 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: 'Unbounded';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-cyrillic.woff2?v=3e88c0f888) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-vietnamese.woff2?v=d1b9d9d63f) 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: 'Unbounded';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-latin-ext.woff2?v=fa9fd91cd1) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/desktop/fonts/unbounded-latin.woff2?v=aef5c24657) 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: 'Material Symbols Rounded';
  font-style: normal;
  font-weight: 400 600;
  font-display: block;
  src: url(/desktop/fonts/material-symbols-rounded.woff2?v=9522f40189) format('woff2');
}

.material-symbols-rounded {
  font-family: 'Material Symbols Rounded';
  font-weight: normal;
  font-style: normal;
  font-size: 24px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  -webkit-font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
}



/* tokens.css идёт первым из стилей: остальные файлы опираются на его переменные. */

/**
 * Дизайн-токены Iwent.
 *
 * Значения не придуманы заново — все до единого собраны из существующих стилей
 * проекта. Это единственное место, где хранятся «сырые» цвета, кегли и радиусы:
 * в остальных файлах их нужно брать через var().
 *
 * Каталог компонентов: /styleguide
 */
:root {
  /* --- Бренд и текст --- */
  --color-brand: #0167FF;
  --color-ink: #031021;          /* основной текст и тёмные подложки */
  --color-ink-alt: #06041F;      /* логотип, иконки в кнопках */
  --color-ink-secondary: rgba(3, 16, 33, 0.64); /* второстепенный текст — один вид во всей ДС: --color-ink на 64% (как теги карточки события).
                                                  Готовый цвет, не opacity: иконки и точки внутри строки не бледнеют. На цветной/тёмной подложке — --color-on-dark-80 */
  --color-muted: #91959B;        /* НЕ для текста. Только нетекстовое и состояния: значок поиска в поле, плейсхолдер поля,
                                    рамка при наведении/фокусе (поле, флажок), выключенное (кнопка, пункт меню, источник),
                                    прошедшее (дни календаря, даты серии), точка нейтрального статуса, запасной цвет аватарки */
  --color-danger: #FF002B;       /* выходные в календаре */

  /* --- Поверхности --- */
  --color-surface: #FFFFFF;      /* карточки */
  --color-bg: #F3F4F8;           /* фон страницы, подложка иконок */
  --color-skeleton: #E7E8ED;     /* скелетоны и разделители */
  --color-skeleton-pulse: #DCDEE4; /* вторая точка пульсации заглушки: темнее, а не цвет фона — иначе заглушка на фоне страницы пропадает */

  /* --- Цвета категорий события --- */
  --color-type-tech: #AD20E1;
  --color-type-music: #EF1B1B;
  --color-type-art: #D7BC8D;
  --color-type-sport: #0167FF;
  --color-type-cinema: #F39A15;
  --color-type-games: #1BC226;
  --color-type-theatre: #E0218A;    /* малиновый — отличим от красной «Музыки» */
  --color-type-knowledge: #00A3A3;  /* бирюзовый */
  --color-type-city: #E3B200;       /* тёмно-жёлтый: на светлом белая иконка не читалась бы */
  --color-type-other: #91959B;   /* запасной для неизвестной категории — серый: фиолетовый занят «Технологиями» */

  /* --- Границы и состояния --- */
  --color-border: rgba(145, 149, 155, 0.24);
  --color-border-soft: rgba(145, 149, 155, 0.12);
  --color-hover: rgba(145, 149, 155, 0.08);
  --color-stack-1: #D7DADF;      /* стопка под карточкой подборки (CollectionCard), макет Figma 661:74: ближний слой */
  --color-stack-2: #E0E2E7;      /* средний слой */
  --color-stack-3: #E9EBEF;      /* дальний слой — светлее всех, уходит в фон страницы */
  --stack-depth-activity: 13px;   /* глубина стопки групповой карточки — на столько она ниже соседних */
  --color-ink-disabled: rgba(3, 16, 33, 0.24);  /* иконка выключенной кнопки: --color-ink на 24%. Через opacity нельзя — у загруженной иконки opacity: 1 !important (base.css) */
  --color-ink-32: rgba(3, 16, 33, 0.32);         /* возраст в названии на белой панели поста (пара к --color-on-dark-32) */
  --color-ink-past: rgba(3, 16, 33, 0.36);      /* «Прошло» (выключенная кнопка события): на 50% ярче --color-ink-disabled */

  /* --- Затемнения поверх изображений --- */
  --color-overlay-8: rgba(3, 16, 33, 0.08);
  --color-overlay-16: rgba(3, 16, 33, 0.16);   /* тень приподнятого стикера — вдвое светлее --color-overlay-32 */
  --color-overlay-24: rgba(3, 16, 33, 0.24);
  --color-overlay-32: rgba(3, 16, 33, 0.32);
  --color-overlay-64: rgba(3, 16, 33, 0.64);
  --color-on-dark-80: rgba(255, 255, 255, 0.8);    /* второстепенный текст на цветной/тёмной подложке (пара к --color-ink-secondary) */
  --color-on-dark-64: rgba(255, 255, 255, 0.6);
  --color-on-dark-32: rgba(255, 255, 255, 0.32);
  --color-on-dark-48: rgba(255, 255, 255, 0.48);   /* «Прошло» на цветном: на 50% ярче --color-on-dark-32 */
  --color-on-dark-24: rgba(255, 255, 255, 0.24);   /* разделитель на цветном (герой события, залитые карточки ленты) */
  --color-on-dark-12: rgba(255, 255, 255, 0.12);   /* кнопки на тёмном фоне галереи */
  --color-on-dark-20: rgba(255, 255, 255, 0.2);     /* подложка круглого аватара в герое события */
  --color-photo-bg: var(--color-skeleton);           /* подложка под фото и аватары: цвет заглушки, пока снимок грузится или его нет (бывший --color-black) */
  --color-hero-bg: #111;                             /* фон левой колонки события с фото */
  --color-scrim: rgba(3, 16, 33, 0.92);             /* фон полноэкранной галереи */
  --color-vk: #0077FF;                               /* знак VK ID на кнопке входа (ProviderMark) */
  --color-yandex: #FC3F1D;                           /* знак Яндекс ID на кнопке входа (ProviderMark) */
  --color-telegram: #26A5E4;                         /* знак Telegram в «Поделиться» (ProviderMark) */
  --color-whatsapp: #25D366;                         /* знак WhatsApp в «Поделиться» (ProviderMark) */
  /* Знаки сервисов в «Где посмотреть / послушать / купить / прочитать» (ProviderMark, ServiceCard) */
  --color-kinopoisk: #FF5500;
  --color-okko: #6B3EE8;
  --color-ivi: #EA003D;
  --color-wink: #FF4F12;
  --color-start: #FF6B2C;
  --color-premier: #FFC107;   /* жёлтый — буква тёмная (--color-ink) */
  --color-kion: #8C2AF5;
  --color-yandexmusic: #FFCC00; /* жёлтый — буква тёмная */
  --color-zvuk: #6B56FF;
  --color-mtsmusic: #E30611;
  --color-steam: #1B2838;
  --color-gog: #86328A;
  --color-litres: #F95A1F;
  --color-yandexbooks: #FF6633;
  --color-backdrop: var(--color-overlay-64);         /* затемнение под модалкой и полноэкранной галереей — одно */
  --shadow-panel: 0 var(--space-4) calc(var(--space-4) * 4) calc(var(--space-4) * -1) var(--color-overlay-32); /* всплывающие панели: Dropdown, выбор месяца, Modal — видна над контентом */

  /* --- Шрифты --- */
  --font-display: 'Unbounded', sans-serif;  /* заголовки */
  --font-body: 'Onest', sans-serif;         /* основной текст */
  --font-alt: 'Montserrat', sans-serif;     /* цифры дат */

  --weight-regular: 400;
  --weight-bold: 700;

  /* --- Кегль --- */
  --text-2xs: 10px;        /* плашки даты и места на картинке поста (DatePlace compact): снимок ×2,5 — 25 px */
  --text-xs: 12px;
  --text-sm: 14px;
  --text-base: 16px;
  --text-lg: 18px;
  --text-xl: 20px;
  --text-2xl: 24px;
  --text-4xl: 40px;
  --text-display: 96px;          /* число крупно: уровень в ленте активности */
  --text-display-mobile: 64px;

  /* --- Отступы --- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;    /* минимум между смысловыми блоками экрана */
  --space-12: 48px;
  --space-16: 64px;   /* между блоками страницы понятия и «Все похожие» */
  --avatar-cut: 3px;  /* прозрачный вырез стопки аватарок (CalendarAvatarStack): Figma 661:74, пользователь */
  --control-height: 44px; /* кнопка-фильтр и чип понятия: строка 20 + поля 12 × 2 */
  --row-avatar-lg: 128px;  /* аватарка строки списка EventCard avatar: 'large' — вдвое крупнее обычной (64) */
  --post-slide-width: 432px;  /* картинка поста в Telegram (PostSlide): 3:4 в CSS-пикселях, снимок ×2,5 = 1080×1440 — */
  --post-slide-height: 576px; /* на экране телефона она такого же размера, поэтому кегли и поля — обычные токены */
  --post-slide-digest-width: 540px;  /* слайд дайджеста — две строки списка с описанием: шире, чем картинка события, снимок ×2 = 1080 по ширине */
  --post-slide-digest-height: 681px; /* высота слайда и обложки дайджеста: поля 16 + шапка 44 + 16 + две самые высокие строки по 270 (название 3 строки, мета, описание 4 строки, плашки в одну линию — «Четыре сонаты Бетховена…») + 16 между ними + поле 16 + 16 между строками и подписью источников фото + её строка 16 (кегль 12 × 1,33); снимок ×2 = 1080×1362 */

  /* --- Радиусы --- */
  --radius-xs: 6px;        /* знак сервиса входа 20×20 (ProviderMark) */
  --radius-sm: 12px;   /* ячейка календаря на телефоне — замер по макету */
  --radius-md: 16px;       /* кнопки, иконочные кнопки */
  --radius-lg: 24px;       /* панели внутри карточек */
  --radius-xl: 32px;       /* карточки */
  --radius-pill: 100px;    /* даты, площадки */

  /* --- Иконки (Material Symbols Rounded) ---
     Варианты:
       обычная      — 20px, толщина 600;
       состояние    — 40px, толщина 400 (пусто / ошибка / не найдено);
       иллюстрация  — 96px (на двойной плитке 144px), толщина 400: только
                      достижение (AchievementBadge), двухтонная.
     Оптический размер обязан совпадать с пиксельным, иначе штрих рисуется
     для чужого кегля: в 20 пикселях с opsz 48 иконка выглядит тонкой
     (у иллюстрации — наибольший, 48). Начертание контурное; заливка (FILL 1)
     — только светлая подложка иллюстрации под её контуром. */
  --icon-base: 20px;
  --icon-state: 40px;
  --icon-hero: 96px;
  --icon-hero-lg: 144px;
  --sticker-height: 96px;         /* стикер (Sticker): высота, ширина по форме */
  --sticker-height-mobile: 64px;
  --sticker-height-lg: 144px;     /* стикер один в карточке ленты активности — крупно по центру */
  --sticker-height-xl: 240px;     /* стикер в окне стикера (StickerModal) — рассмотреть */
  --sticker-height-xl-mobile: 192px;
  --sticker-perspective: 600px;   /* глубина наклона стикера за мышью (Iwent.stickerTilt) */
  --sticker-tilt-card: 12;        /* наибольший наклон стикера за мышью в карточке, градусы (Iwent.stickerTilt читает) */
  --sticker-tilt-modal: 15;       /* то же в окне стикера (StickerModal) */
  --sticker-lift-scale: 1.08;     /* стикер в карточке при наведении «приподнимается» — крупнее на 8% */
  --sticker-lift-outline: 3px;    /* белый контур по форме приподнятого стикера — тень падает от него, край чистый */
  --sticker-lift-shadow: 0 var(--space-2) var(--space-3) var(--color-overlay-16); /* тень под приподнятым стикером (drop-shadow — по форме) */
  --sticker-glare: 0.45;          /* блик на стикере при наклоне в карточке: сила при наибольшем угле */
  --sticker-glare-xl: 0.6;        /* то же в окне стикера (StickerModal) — заметнее */
  --sticker-glare-size: 1;        /* пятно блика: диаметр в долях стикера */
  --sticker-glare-color: rgba(255, 255, 255, 0.9); /* свет блика (mix-blend-mode: screen) */
  --icon-weight-base: 600;
  --icon-weight-state: 400;
  --icon-opsz-base: 20;
  --icon-opsz-state: 40;
  --icon-opsz-hero: 48;

  /* --- Прочее --- */
  --music-cover-compact: calc(var(--space-4) * 5 - var(--space-3)); /* обложка песни в обычной и широкой карточке записи ленты: диск с кольцом 80 (обложка + 12) — как аватарка события в широкой */
  --music-cover-large: calc(var(--space-4) * 8 - var(--space-3));   /* в вертикальной: диск 128 — как аватарка героя (EventHero card) */
  --blur-panel: blur(32px);
  --blur-photo-preview: blur(12px); /* размытое превью фото (ui.Photo): копия ~16 px растянута — пиксели не видны */
  --photo-preview-scale: 1.15;      /* превью чуть крупнее рамки: размытый край не светлеет у границы */

  /* --- Движение (docs/design-system.md, «Движение») ---
     Числа в transition / animation запрещены, как сырые цвета; transition: all — тоже
     (захватывает раскладку). Анимировать только transform, opacity и цвет. */
  --duration-instant: 80ms;  /* отклик нажатия (:active) */
  --duration-fast: 120ms;    /* маленькие панели, смена иконки, наведение в каталоге */
  --duration-base: 200ms;    /* по умолчанию: цвет, фон, рамка, Toast, стрелки */
  --duration-slow: 320ms;    /* окна, галочка успеха, тряска ошибки, проявление фото на странице */
  --duration-spin: 800ms;    /* оборот спиннера ожидания (Button state busy) */
  --duration-pulse: 1.6s;    /* цикл пульсации заглушки загрузки (Skeleton, фото в загрузке) */
  --duration-progress: 1.2s; /* пробег полосы неопределённого ProgressBar */
  --duration-fade: 240ms;    /* проявление загруженного фото поверх заглушки */
  --reveal-step: 30ms;       /* лесенка появления карточек (не больше 4 ступеней) */
  --reveal-shift: 8px;       /* сдвиг карточки при появлении */
  --ease-out: cubic-bezier(0.2, 0, 0, 1);           /* появление, ответ на действие, смена цвета */
  --ease-in: cubic-bezier(0.4, 0, 1, 1);            /* уход */
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);      /* перемещение, поворот стрелки, пульсация */
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* «щелчок» галочки успеха */
  /* Смена цвета, фона и рамки при наведении и выборе — у кнопок, вкладок, дат, меню. */
  --transition-colors: background-color var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out), color var(--duration-base) var(--ease-out);

  /* --- Раскладка --- */
  --page-max-width: 1440px;  /* ширина страницы; шире — поля по бокам */
  --grid-gap: var(--space-6); /* промежуток сетки в три колонки: карточки ленты (.events) и колонки страницы события */
  --header-height: 72px;     /* шапка сайта; под ней — уведомления (Toast) */
  --modal-width: 680px;      /* модальное окно (Modal): настройки источника; поля 36 */
  --modal-width-sm: 520px;   /* узкое окно (Modal size small): «Добавить в календарь»; поля 36 */
  --city-picker-width: 520px; /* панель выбора города (CityPicker) на компьютере: три колонки, «Нижний Новгород» в строку; длиннее — шире */
  --toast-max-width: 400px;  /* уведомление (Toast): шире — текст переносится */
  --banner-width: 880px;     /* баннер поверх страницы внизу (CookieBanner): текст в две строки и две кнопки справа */
  --text-measure: 720px;     /* строка длинного текста (описание события): ~85 знаков, шире читать тяжело */
  --stepper-page-width: 1080px; /* шаги на всю страницу (Stepper variant 'page', «Добро пожаловать»): три карточки событий в ряд */
  --sidebar-rail-width: 128px;   /* боковое меню сайта: колонка «иконка над подписью» (Sidebar) — по самой длинной подписи в строку («Мои события» 101 + поля 8 + 16) */
  --story-gutter: 104px;         /* наименьшее поле по бокам карточки «Листать» на компьютере (--story-side): справа в нём столбик кнопок (16 + до 88) */
  --story-width: 430px;          /* лента «Листать» (EventStories) на компьютере: колонка шириной крупного телефона по центру; на телефоне — во весь экран */
}

/*
 * Мобильная версия — до 767px включительно; от 768px — десктоп.
 * Макеты в Figma нарисованы под 375 и 1440, планшетного макета нет, поэтому
 * промежуточной раскладки тоже нет. В медиазапросах переменные не работают,
 * так что брейкпоинт записывается числом: @media (max-width: 767px).
 * Поля страницы на телефоне — --space-mobile.
 */
:root {
  --space-mobile: 20px;
  --header-height-mobile: 64px;  /* шапка сайта на телефоне */
  --bottom-nav-height: 64px;     /* нижняя панель меню на телефоне (Sidebar rail), без safe-area */
}

/*
 * Меньше движения. Человек попросил об этом в настройках системы — длительности
 * обнуляются одним правилом: цвет меняется сразу, ничего не едет, не крутится и не
 * трясётся. Бесконечные анимации (пульсация, спиннер) дополнительно выключены у
 * своих компонентов (animation: none) — на их месте статичный вид.
 * html.motion-reduce — тот же сброс по переключателю «Меньше движения» в каталоге ДС,
 * чтобы проверить вид без настроек ОС.
 */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-instant: 0ms;
    --duration-fast: 0ms;
    --duration-base: 0ms;
    --duration-slow: 0ms;
    --duration-fade: 0ms;
    --reveal-step: 0ms;
    --reveal-shift: 0px;
  }
}
:root.motion-reduce {
  --duration-instant: 0ms;
  --duration-fast: 0ms;
  --duration-base: 0ms;
  --duration-slow: 0ms;
  --duration-fade: 0ms;
  --reveal-step: 0ms;
  --reveal-shift: 0px;
}



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

/* Типограф (docs/design-system.md «Типограф»): абзацы и заголовки переносятся без
   одинокого слова в последней строке. Неразрывные пробелы ставит ui.typo при отрисовке.
   :where — без веса, правила компонентов главнее. .event-title — названия в карточках. */
:where(p, li, dd, blockquote, h1, h2, h3, h4, .event-title) { text-wrap: pretty; }

body {
  background: var(--color-bg);
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  min-width: 1024px;
  max-width: var(--page-max-width);
  margin: 0 auto;
  overflow-x: hidden;
}

.material-symbols-rounded {
  font-family: 'Material Symbols Rounded' !important;
  font-size: 20px !important;
  line-height: 1 !important;
  display: inline-flex !important;
  width: 20px !important;
  height: 20px !important;
  align-items: center !important;
  justify-content: center !important;
  speak: never;
  font-style: normal;
  font-variant: normal;
  text-transform: none;
  color: inherit;
  opacity: 0;
  visibility: hidden;
  font-variation-settings: 'wght' 600;
}

.material-symbols-rounded.loaded {
  opacity: 1 !important;
  visibility: visible !important;
}

.body {
  display: flex;
  margin: 0 auto;
}

/* Без overflow: hidden — он резал тень всплывающих панелей (--shadow-panel).
   min-width: 0 — то, что давал hidden: колонка не шире своего места во flex. */
.content {
  flex: 1;
  min-width: 0;
}

.content-full {
  flex: 1;
  min-width: 0;
  max-width: 100%;
}

.btn {
  /* Раскладка как у .filter-btn: иначе иконка прилипает к тексту,
     а <a class="btn"> получает подчёркивание от браузера. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  text-decoration: none;
  padding: 12px 16px;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink);
  cursor: pointer;
  transition: var(--transition-colors), transform var(--duration-instant) var(--ease-out);
}

/* :not(:disabled) — чтобы выключенная кнопка вообще не отзывалась на наведение.
   Раньше здесь сбрасывались фон и рамка, но не цвет текста, и выключенная
   кнопка синела под курсором.
   .btn.is-hover — тот же вид для каталога, где навести курсор нельзя. */
.btn:hover:not(:disabled):not([aria-disabled="true"]),
.btn.is-hover {
  background: var(--color-hover);
  color: var(--color-brand);
  border-color: transparent;
}

/* Выключенная кнопка — серый текст и иконка (--color-ink-disabled), бледная рамка:
   прежде у <button disabled> текст оставался чёрным, и она выглядела активной.
   Выключенная ссылка-кнопка (Button с href и disabled: aria-disabled) — тот же
   вид, и по ней не перейти: например, способ входа, который ещё не настроен. */
.btn:disabled,
.btn[aria-disabled="true"] {
  border-color: var(--color-border-soft);
  color: var(--color-ink-disabled);
  cursor: default;
}

.btn[aria-disabled="true"] {
  pointer-events: none;
}

/* Отклик нажатия — сразу, не дожидаясь сервера: кнопка чуть «вдавливается» за
   --duration-instant (transform — не раскладка, соседи не двигаются). */
.btn:active:not(:disabled):not([aria-disabled="true"]) {
  transform: scale(0.97);
}

.btn-full {
  width: 100%;
}

/* ---------- Мобильная версия (≤ 767px) ----------
   Десктоп держит ширину не меньше 1024px; на телефоне это превращалось в
   уменьшенный десктоп с горизонтальной прокруткой. Здесь страница занимает
   ширину экрана. Подробности и правила — docs/design-system.md, «Мобильная версия». */
@media (max-width: 767px) {
  body {
    min-width: 0;
  }

  .body {
    display: block;
  }
}



.header {
  background: var(--color-bg);
  height: var(--header-height);
  border-bottom: 1px solid var(--color-border);
}

.header-inner {
  position: relative; /* строка поиска на телефоне закрывает шапку целиком */
  margin: 0 auto;
  height: 100%;
  padding: 0 24px;
  display: flex;
  align-items: center;
}

.logo {
  display: flex;
  align-items: center;
  text-decoration: none;
}

.header-divider {
  width: 1px;
  height: 24px;
  background: var(--color-border);
  margin-left: 16px;
}

.city {
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  color: var(--color-ink);
  margin-left: 16px;
}

/* Выбор города (ui.HeaderCity → CityPicker, когда включённых городов больше одного) —
   на месте подписи города: та же раскладка после разделителя, вид — свой у CityPicker. */
.header-inner > .city-picker {
  margin-left: var(--space-4);
}

.spacer {
  flex: 1;
}

/* Правая часть шапки (ui.Header actions): администратор и «Выйти» в админке. */
.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.header-account {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink-secondary);
}

/* Правый край шапки по сетке ленты (ui.HeaderEnd, Iwent.initSearch): от второй
   колонки карточек главной до правого края. Сетка .events — три колонки через
   --grid-gap во всю ширину содержимого, у шапки та же ширина содержимого
   (поля 24), поэтому две колонки с промежутком — (2 × 100% − gap) / 3 от неё:
   левый край совпадает с колонкой на любой ширине. Внутри — поиск и после
   него, в версии с пользователями, вход или аватарка (поле сжимается). */
.header-end {
  flex: 0 0 calc((200% - var(--grid-gap)) / 3);
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.header-end > .search-field {
  flex: 1 1 auto;
  min-width: 0;
}

/* Мобильная шапка: ниже и с полями страницы, расстояния внутри те же. */
@media (max-width: 767px) {
  .header {
    height: var(--header-height-mobile);
  }

  .header-inner {
    padding: 0 var(--space-mobile);
  }

  /* На телефоне сетки в три колонки нет: справа только кнопки — лупа и вход. */
  .header-end {
    flex: 0 0 auto;
    gap: var(--space-2);
  }

  .header-end > .search-field {
    flex: 0 0 auto;
  }

  /* На самых узких экранах (320) логотип, город и кнопки справа не умещаются
     в ряд: логотип сжимается (картинка пропорционально), остальное
     держит размер, шапка не шире экрана. */
  .logo {
    min-width: 0;
    /* область нажатия 44: поля со встречным отрицательным отступом, раскладка на месте */
    padding-block: var(--space-3);
    margin-block: calc(-1 * var(--space-3));
  }

  .logo svg {
    max-width: 100%;
    height: auto;
  }

  .header-divider {
    flex-shrink: 0;
  }

  .city {
    flex-shrink: 0;
    margin-right: var(--space-2);
    white-space: nowrap;
  }

  /* Выбор города сжимается вместе с логотипом: длинное название («Санкт-Петербург») —
     с многоточием в кнопке, шапка не шире экрана. */
  .header-inner > .city-picker {
    flex: 0 1 auto;
    margin-right: var(--space-2);
  }
}



.sidebar {
  width: 288px;
  flex-shrink: 0;
  padding: 24px;
}

/* Отступ между пунктами — как между кнопками фильтров. */
.menu {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border-radius: 16px;
  padding: 12px 16px;
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  color: var(--color-ink);
  cursor: pointer;
  transition: var(--transition-colors);
  text-decoration: none;
}

.menu-icon {
  font-family: 'Material Symbols Rounded' !important;
  /* Размер и оси берутся из общего правила в components.css:
     свой opsz 24 давал иконке чужую толщину. */
  width: 20px;
  height: 20px;
  min-width: 20px;
  min-height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: inherit;
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-out), color var(--duration-base) var(--ease-out);
}

body.loaded .menu-icon {
  opacity: 1;
}

/* Наведение — на любом невыбранном пункте. */
/* Пункт-действие (MenuItem без href) — кнопка, но выглядит как пункт-ссылка. */
button.menu-item {
  width: 100%;
  border: 0;
  text-align: left;
}
button.menu-item:disabled {
  color: var(--color-muted);
  cursor: default;
}

/* :where — чтобы наведение не перебивало выбранный пункт (.menu-item.active). */
.menu-item:hover:where(:not(:disabled)) {
  background: var(--color-hover);
  color: var(--color-brand);
}

/* Опасное действие (MenuItem danger): красный в покое; наведение и фокус — та же подложка, цвет остаётся красным. */
.menu-item--danger,
.menu-item--danger:hover:where(:not(:disabled)),
.event-hero:not([data-tone="light"]) .event-hero-menu .menu-item--danger,
.event-hero:not([data-tone="light"]) .event-hero-menu .menu-item--danger:hover:where(:not(.active)) {
  color: var(--color-danger);
}
.menu-item--danger:focus-visible {
  background: var(--color-hover);
  outline: 2px solid var(--color-danger);
  outline-offset: -2px;
}

/*
 * Выбранный пункт — белый с синим, и только он один в своей колонке. Выделение
 * задаёт сам пункт (класс active у ui.Sidebar), а не класс
 * страницы: раньше страница красила белым все пункты разом. Какой пункт выбран
 * на странице, решает Iwent.initMenu (event-utils.js). Пунктов админки в
 * публичном меню нет.
 */
.menu-item.active {
  background: var(--color-surface);
  color: var(--color-brand);
}

/* ---------- Меню сайта: колонка «иконка над подписью» (Sidebar, layout 'rail') ----------
   Одна колонка у левого края, пункты одним списком (второй колонки раздела нет
   с 19.10.2026); пункт — MenuItem stacked: иконка над подписью, наведение и
   выбор — как у пункта строкой. Ширина — по самой длинной подписи
   (--sidebar-rail-width). */
.sidebar--rail {
  width: var(--sidebar-rail-width);
  padding: var(--space-6) var(--space-2);
}

.menu-item--stacked {
  flex-direction: column;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-1);
  font-size: var(--text-xs);
  line-height: var(--space-4);
  text-align: center;
}

/* ---------- Разделы человека в герое профиля (PersonHero menu) ----------
   Те же пункты строками на цветной подложке героя: белый текст, выбранный —
   белый с синим, наведение — светлая подложка. До кнопки героя сверху 16,
   линия под разделами — своя (.event-divider, 24). */
.event-hero-menu {
  margin-top: var(--space-4);
}

/* Разделитель между пунктами (Divider): 16 сверху и снизу. */
.event-hero-menu .event-divider {
  margin: var(--space-2) 0;
}

.event-hero:not([data-tone="light"]) .event-hero-menu .menu-item {
  color: var(--color-surface);
}

.event-hero:not([data-tone="light"]) .event-hero-menu .menu-item:hover:where(:not(.active)) {
  background: var(--color-on-dark-12);
  color: var(--color-surface);
}

.event-hero:not([data-tone="light"]) .event-hero-menu .menu-item.active {
  background: var(--color-surface);
  color: var(--color-brand);
}

/*
 * Телефон. Меню строками (админка) скрыто: в админке разделы показывает
 * TabBar в .admin-mobile-nav. Меню сайта — нижняя панель во всю ширину над
 * safe-area, пункты поровну; выбранный — синий без подложки. Пунктов только
 * для десктопа (MenuItem phone: 'off' — «Темы», «Создать событие») в панели
 * нет; одному оставшемуся пункту (гость: только «События») панель не нужна —
 * её нет. Разделы тёмного героя — строкой, листаются; светлого (профиль) —
 * столбиком, как на десктопе.
 * Пока панель есть, странице добавлено поле снизу, а уведомления (Toast)
 * поднимаются над панелью (--bottom-nav-offset).
 */
/* Короткая подпись пункта для нижней панели телефона (phoneLabel): на десктопе — полная. */
.menu-label--phone { display: none; }

@media (max-width: 767px) {
  .sidebar--rail .menu-label--desktop { display: none; }
  .sidebar--rail .menu-label--phone { display: inline; }
  .sidebar,
  .sidebar--rail .menu-item--off {
    display: none;
  }

  .sidebar--rail:has(.menu-item:not(.menu-item--off) ~ .menu-item:not(.menu-item--off)) {
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 900; /* под шторками (1000) и уведомлениями (1100) */
    width: auto;
    padding: 0 var(--space-mobile) env(safe-area-inset-bottom, 0px);
    background: var(--color-surface);
    border-top: 1px solid var(--color-border-soft);
  }

  .sidebar--rail .menu {
    flex-direction: row;
    align-items: center;
    height: var(--bottom-nav-height);
  }

  .sidebar--rail .menu-item {
    flex: 1;
    padding: var(--space-2) var(--space-1);
  }

  .sidebar--rail .menu-item.active,
  .sidebar--rail .menu-item:hover {
    background: transparent;
  }

  body:has(.sidebar--rail .menu-item:not(.menu-item--off) ~ .menu-item:not(.menu-item--off)) {
    --bottom-nav-offset: calc(var(--bottom-nav-height) + 1px);
    padding-bottom: calc(var(--bottom-nav-offset) + env(safe-area-inset-bottom, 0px));
  }

  .event-hero:not([data-tone="light"]) .event-hero-menu {
    flex-direction: row;
    overflow-x: auto;
    margin-inline: calc(-1 * var(--space-mobile));
    padding-inline: var(--space-mobile);
    scrollbar-width: none;
  }

  .event-hero:not([data-tone="light"]) .event-hero-menu::-webkit-scrollbar {
    display: none;
  }

  .event-hero:not([data-tone="light"]) .event-hero-menu .menu-item {
    flex-shrink: 0;
  }
}

/* Место меню на странице (<div id="sidebar">, Iwent.initMenu): обёртка без
   своего блока — колонка меню встаёт прямо в ряд .body. */
.site-menu {
  display: contents;
}



.content-inner {
  padding: 24px;
  min-width: 0;
}

.tabs {
  display: flex;
  gap: 8px;
}

.tab {
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  padding: 12px 16px;
  border-radius: 16px;
  background: transparent;
  border: 2px solid transparent;
  color: var(--color-ink);
  cursor: pointer;
  transition: var(--transition-colors);
}

.tab:hover:not(.active) {
  background: var(--color-hover);
  color: var(--color-brand);
}

.tab.active {
  border-color: var(--color-brand);
  color: var(--color-ink);
}

@media (max-width: 767px) {
  .content-inner {
    padding: var(--space-mobile);
  }

  /* Вкладки «Будущие / Прошедшие» делят ширину поровну; высота 44px, как
     в макете: рамка активной вкладки входит в высоту, а не добавляется к ней. */
  .tabs .tab {
    flex: 1;
    padding: 10px 16px;
  }

  /* Вкладок больше трёх (профиль: События, Прошедшие, Лента…) — поровну не
     влезают: ряд прокручивается вбок от края до края экрана, вкладки по
     своей ширине и в одну строку. */
  .tabs:has(> .tab:nth-child(4)) {
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 calc(var(--space-mobile) * -1);
    padding: 0 var(--space-mobile);
  }
  .tabs:has(> .tab:nth-child(4))::-webkit-scrollbar { display: none; }
  .tabs:has(> .tab:nth-child(4)) .tab {
    flex: 0 0 auto;
    white-space: nowrap;
  }
}



.date-block {
  margin-top: 16px;
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

.month-group {
  display: flex;
  flex-direction: column;
}

.month-title {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 400;
  line-height: 16px;
  color: var(--color-ink-secondary);
  text-transform: uppercase;
  margin-bottom: 4px;
}

.dates {
  display: flex;
  gap: 8px;
  overflow: hidden;
}

.date {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 12px 16px;
  cursor: pointer;
  transition: var(--transition-colors);
  border-radius: 16px;
}

.date:hover {
  background: var(--color-hover);
}

.date.active {
  background: #fff;
}

.date.active .day-name,
.date.active .day-num {
  color: var(--color-brand);
}

.date:hover .day-name,
.date:hover .day-num {
  color: var(--color-brand);
}

.day-name {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 400;
  line-height: 16px;
  color: var(--color-ink-secondary);
  text-transform: uppercase;
}

.day-name.weekend {
  color: var(--color-danger);
}

.day-num {
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  color: var(--color-ink);
  display: flex;
  align-items: center;
  gap: 4px;
}

.today-dot {
  width: 4px;
  height: 4px;
  background: var(--color-brand);
  border-radius: 50%;
}

.calendar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px 16px;
  border: 1px solid var(--color-border);
  border-radius: 16px;
  flex-shrink: 0;
  background: transparent;
  box-sizing: border-box;
  cursor: pointer;
  transition: var(--transition-colors);
}

.calendar-btn:hover {
  background: var(--color-hover);
  border-color: transparent;
}

.calendar-btn:hover .material-symbols-rounded {
  color: var(--color-brand);
}

.calendar-btn .material-symbols-rounded {
  color: var(--color-ink);
  width: 20px;
  height: 20px;
}

/* Группа кнопки календаря тянется на высоту ленты, а кнопка — на высоту даты,
   как когда она стояла в одном ряду с датами. */
.calendar-group {
  align-self: stretch;
  /* Кнопка календаря — у правого края ленты: правая граница совпадает с
     переключателем вида ленты и концом контента, а не стоит сразу за датами. */
  margin-left: auto;
}

.calendar-group .dates {
  flex: 1;
}

.skeleton-month-title {
  width: 60px;
  height: 16px;
  background: var(--color-skeleton);
  border-radius: 100px;
  margin-bottom: 4px;
}

.skeleton-date {
  width: 50px;
  height: 60px;
  background: var(--color-skeleton);
  border-radius: 16px;
  flex-shrink: 0;
}

/* Лента дат на телефоне: две недели, листается пальцем от края до края экрана
   (сколько дней рисовать, решает desktop/js/dates.js). Закреплены название месяца —
   слева, пока его даты не ушли и не пришёл следующий, — и кнопка календаря справа. */
@media (max-width: 767px) {
  .date-block {
    overflow-x: auto;
    margin-inline: calc(-1 * var(--space-mobile));
    padding-inline: var(--space-mobile) 0;
    scrollbar-width: none;
  }

  .date-block::-webkit-scrollbar {
    display: none;
  }

  .month-group,
  .dates,
  .date,
  .calendar-btn {
    flex-shrink: 0;
  }

  .dates {
    overflow: visible;
  }

  .month-title {
    position: sticky;
    left: 0; /* отсчёт — от поля ленты, то есть 20px от края экрана */
    align-self: flex-start;
  }

  /* Даты уезжают под кнопку: подложка цвета фона закрывает их от зазора
     перед кнопкой до края экрана. */
  .calendar-group {
    position: sticky;
    right: 0;
    z-index: 1;
    margin-left: auto;
    padding: 0 var(--space-mobile) 0 var(--space-2);
    background: var(--color-bg);
  }
}



.filters {
  margin-top: 8px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.filter-btn {
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  padding: 12px 16px;
  border-radius: 16px;
  border: none;
  background: transparent;
  color: var(--color-ink);
  text-decoration: none; /* FilterButton со ссылкой (href) — понятия графа */
  cursor: pointer;
  transition: background var(--duration-base) var(--ease-out), color var(--duration-base) var(--ease-out);
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
}

/* Длинная подпись (понятие «Объединение „Выставочные залы Москвы“») не шире
   колонки — многоточие, полное название в title. */
.filter-btn > .count-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Только иконка (FilterButton без подписи): кнопка-иконка 44×44 с рамкой, как
   стрелки слайдера (11 + рамка 1 + иконка 20). Активная — как выбранный фильтр:
   белый фон, синяя иконка, без рамки; при наведении рамка уходит, как у кнопок. */
.filter-btn-icon {
  padding: 11px;
  border: 1px solid var(--color-border);
}

.filter-btn-icon.active,
.filter-btn-icon:hover:not(.active) {
  border-color: transparent;
}

.filter-btn:hover:not(.active) {
  background: var(--color-hover);
  color: var(--color-brand);
}

.filter-btn .material-symbols-rounded {
  font-size: 20px !important;
  line-height: 1;
  width: 20px;
  height: 20px;
  min-width: 20px;
  min-height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-skeleton);
  /* Тот же переход, что у текста кнопки: иконке задан собственный цвет
     по категории, без этой строки она перекрашивалась мгновенно, а подпись
     плыла 0.2s. */
  transition: color var(--duration-base) var(--ease-out);
}
.filter-btn.loaded .material-symbols-rounded {
  color: var(--color-type-art);
}
.filter-btn[data-type="music"].loaded .material-symbols-rounded { color: var(--color-type-music); }
.filter-btn[data-type="sport"].loaded .material-symbols-rounded { color: var(--color-brand); }
.filter-btn[data-type="cinema"].loaded .material-symbols-rounded { color: var(--color-type-cinema); }
.filter-btn[data-type="games"].loaded .material-symbols-rounded { color: var(--color-type-games); }
.filter-btn[data-type="theatre"].loaded .material-symbols-rounded { color: var(--color-type-theatre); }
.filter-btn[data-type="knowledge"].loaded .material-symbols-rounded { color: var(--color-type-knowledge); }
.filter-btn[data-type="city"].loaded .material-symbols-rounded { color: var(--color-type-city); }
.filter-btn[data-type="tech"].loaded .material-symbols-rounded { color: var(--color-type-tech); }

.filter-btn:hover:not(.active).loaded .material-symbols-rounded {
  color: var(--color-brand);
}

.filter-btn:hover:not(.active) .material-symbols-rounded {
  color: var(--color-brand);
}

.filter-btn[data-type="art"] .material-symbols-rounded { color: var(--color-type-art); }
.filter-btn[data-type="music"] .material-symbols-rounded { color: var(--color-type-music); }
.filter-btn[data-type="sport"] .material-symbols-rounded { color: var(--color-brand); }
.filter-btn[data-type="cinema"] .material-symbols-rounded { color: var(--color-type-cinema); }
.filter-btn[data-type="games"] .material-symbols-rounded { color: var(--color-type-games); }
.filter-btn[data-type="theatre"] .material-symbols-rounded { color: var(--color-type-theatre); }
.filter-btn[data-type="knowledge"] .material-symbols-rounded { color: var(--color-type-knowledge); }
.filter-btn[data-type="city"] .material-symbols-rounded { color: var(--color-type-city); }
.filter-btn[data-type="tech"] .material-symbols-rounded { color: var(--color-type-tech); }

.filter-btn:hover:not(.active) .material-symbols-rounded {
  color: var(--color-brand);
}

/* У пилюли без категории иконке нечем отличаться — она цвета подписи
   (на странице парсеров: «Разметка понятиями»). */
.filter-btn:not([data-type]) .material-symbols-rounded { color: currentColor; }

.filter-btn.active {
  background: #ffffff;
  color: var(--color-brand);
}

.divider {
  height: 1px;
  background: var(--color-border);
  margin-top: 24px;
}

/* ---------- Мобильная версия (≤ 767px) ----------
   Ряды фильтров не переносятся, а листаются пальцем одной лентой. Лента
   доходит до правого края экрана: обрезанная кнопка подсказывает, что
   дальше есть ещё. Слева она начинается от поля страницы. */
@media (max-width: 767px) {
  .filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    margin-right: calc(-1 * var(--space-mobile));
    padding-right: var(--space-mobile);
    scrollbar-width: none;
  }

  .filters::-webkit-scrollbar {
    display: none;
  }

  /* Правый край ряда затухает на поле страницы: обрезанная кнопка читается как «дальше есть ещё»,
     а не как ошибка. Затухание — в поле (padding-right), в конце прокрутки последняя кнопка
     полностью видна. */
  .filters:not(:has(> .filter-btn-icon)) {
    mask-image: linear-gradient(to right, #000 calc(100% - var(--space-mobile)), transparent);
  }

  .filters .filter-btn {
    flex-shrink: 0;
    white-space: nowrap;
  }

  .divider {
    margin-top: var(--space-mobile);
  }

  .divider + .filters {
    margin-top: var(--space-mobile) !important; /* перебивает инлайновый отступ ленты */
  }
}



.events {
  margin-top: 24px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 352px);
  gap: var(--grid-gap);
  grid-auto-flow: dense;
}

/* Лента всегда раздаёт 10 карточек, отсюда три ряда. На странице понятия их
   бывает одна-две — ряды по числу карточек, иначе под сеткой пустые 700px.
   То же у «Все похожие» (similar.html), выдачи поиска (search.html), подборки (podborka.html), «Моих событий» (my.html) и «Ленты» (lenta.html). */
.page-concept .events,
.page-similar .events,
.page-search .events,
.page-profile .events,
.page-my .events,
.page-lenta .events,
.page-podborka .events {
  grid-template-rows: none;
  grid-auto-rows: 352px;
}
/* «Первые события» (welcome.html): у карточек ещё «Подписаться» — ряд по самой высокой. */
.page-welcome .events {
  grid-template-rows: none;
  grid-auto-rows: auto;
}

/* Вместо карточек — состояние «пусто / ошибка» (400px): ряд по его высоте.
   В ряду 352px оно вылезало на 48px и наезжало на следующий блок, а в ленте
   (три ряда по 352) под ним оставалась пустота. Состояние стоит внутри сетки —
   отступ сверху у всех вариантов один, от .events (24, на телефоне 16). */
.events:has(> .empty-state, > .error-state) {
  grid-template-rows: none;
  grid-auto-rows: auto;
}



/* «Лента» (lenta.html): чипсы «Всё · Друзья · События · Новости · Темы» (FilterBar) — через 24 от
   шапки, сетка (.events) — через свои 24 от них; на телефоне — 20 и 20 (--space-mobile), ряд листается (filters.css). */
#lenta-root > .page-header + .filters {
  margin-top: var(--space-6);
}

/* Шапка ленты (h1 и вступление, PageHeader) — над вкладками; под шапкой 32, как
   на остальных страницах (concept.css), на телефоне то же. */
.feed-head > .page-header {
  margin-bottom: var(--space-8);
}

/* «Что вам интересно?» (DetailTitle + FilterBar) и полка «Для вас» (SimilarEvents) под
   шапкой ленты (Iwent.interestsRow / forYouShelf): между блоками 32, заголовок → пилюли 16.
   Только раскладка: вид — у компонентов. */
#interests:not(:empty) { margin-bottom: var(--space-8); }
#interests > .filters { margin-top: 0; }
#for-you > .similar-events { margin-top: 0; margin-bottom: var(--space-8); }
/* «Без срока давности» (Iwent.timelessShelf) — на «Прошедших» между рядом выбора и карточками
   (ряда подборок там нет): отдельный блок с заголовком — 32 от ряда выбора и 32 до карточек. */
#timeless > .similar-events { margin-top: var(--space-8); margin-bottom: var(--space-8); }

/* Ряд «категории — подкатегории — сброс — вид ленты» (feed.js): выбор категорий и
   подкатегорий (ui.TypePick, components.css) слева, переключатель
   «карточками / списком» справа; от линии — 24px, как было у ряда категорий.
   Только раскладка: вид — у Dropdown и FilterButton. */
.feed-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

/* Два ряда (ui.TypePick rows): первый — категории (в .type-pick--rows, components.css),
   второй — подкатегории, расширенные фильтры, порядок и вид. Между рядами 16, в ряду 8;
   порядок и вид — справа, между ними 16, как в одном ряду. */
@media (min-width: 768px) {
  .feed-controls:has(> .type-pick--rows) { flex-wrap: wrap; justify-content: flex-start; gap: var(--space-4) var(--space-2); }
  .feed-controls:has(> .type-pick--rows) > .feed-view { margin-left: var(--space-2); }
}

/* Порядок ленты (Iwent.feedSortPick, Dropdown) — справа, перед видом ленты. */
.feed-sort {
  flex-shrink: 0;
  margin-left: auto;
}

.feed-view {
  flex-shrink: 0;
}

.feed-view > .filters {
  margin-top: 0;
  flex-wrap: nowrap;
}

.show-more-container {
  padding: 24px 0;
}

.show-more-btn {
  width: 100%;
  padding: 12px 16px;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: 16px;
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  color: var(--color-ink);
  cursor: pointer;
  transition: var(--transition-colors);
}

/* Ссылкой (ShowMore с href: «Все» под новостями, следующая страница новостей) — тот же вид. */
a.show-more-btn {
  box-sizing: border-box;
  text-align: center;
  text-decoration: none;
}

.show-more-btn:hover {
  background: var(--color-hover);
  color: var(--color-brand);
  border-color: transparent;
}

/* Ожидание порции (ShowMore state busy, Iwent.loadMore — через Iwent.buttonAction marks: false): перед
   подписью крутится progress_activity, как у Button busy; подпись и высота те же (значок 20 = строка 20).
   Итога на кнопке нет — ни галочки «готово», ни тряски: после ответа значок убирается из разметки,
   кнопка сразу в обычном виде; ошибку говорит Toast. Вне ожидания значок не показывается никогда. */
.show-more-btn { display: flex; align-items: center; justify-content: center; gap: var(--space-2); }
.show-more-btn:not([data-state="busy"]) > .material-symbols-rounded { display: none !important; }
.show-more-btn[data-state="busy"] { cursor: progress; }
.show-more-btn[data-state="busy"] > .material-symbols-rounded {
  animation: iwent-fade-in var(--duration-fast) var(--ease-out), iwent-spin var(--duration-spin) linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .show-more-btn[data-state] > .material-symbols-rounded { animation: none; }
}
.motion-reduce .show-more-btn[data-state] > .material-symbols-rounded { animation: none; }

.events-row {
  display: contents;
}

.event-card-main {
  grid-column: 1 / 4;
  grid-row: span 1;
  height: 352px;
  border-radius: 32px;
  position: relative;
  overflow: hidden;
  background: var(--color-photo-bg);
}

.event-card-priority {
  grid-column: span 2;
  grid-row: span 1;
  height: 352px;
  border-radius: 32px;
  position: relative;
  overflow: hidden;
  background: var(--color-photo-bg);
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
}

/* Наведение на карточку — тень и цвет заголовка. Наведение — только у того, на что наведено: курсор на
   вложенном (ссылка, кнопка, плашка даты или места — и не ссылкой, тег, аватарка человека, стопка) — карточка
   не подсвечивается: :not(:has(:where(…):hover)), :where — чтобы не менять специфичность. Тот же список — у
   SimilarEventCard, у RecommendedEventCard (event-detail.css) — свои классы плашек и тегов; у новости в ленте — components.css. */
.event-card-priority:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) {
  box-shadow: 0 0 32px 0 var(--color-overlay-8);
}

.event-card-priority-vertical {
  grid-column: span 1;
  grid-row: span 2;
  width: 100%;
  height: calc(352px * 2 + 24px);
  min-height: calc(352px * 2 + 24px);
  border-radius: 32px;
  position: relative;
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
  overflow: hidden;
}

.event-card-priority-vertical:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) {
  box-shadow: 0 0 32px 0 var(--color-overlay-8);
}

.event-card-standard {
  grid-column: span 1;
  grid-row: span 1;
  height: 352px;
  background: #fff;
  border-radius: 32px;
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
}

.event-card-standard:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) {
  box-shadow: 0 0 32px 0 var(--color-overlay-8);
}

/* Фото крупных карточек — только в видимой части, а не под всей карточкой:
   cover по всей карточке показывал увеличенный кусок, а панель закрывала
   половину. Видимая часть — от края карточки до панели плюс скругление
   панели (--radius-xl): под углами панели фото, а не пустота. Размер панели
   и фото берут из одной переменной карточки — не разъедутся.
   Стеклянная панель (isVariant, .event-card-variant) просвечивает — под ней
   фото остаётся на всю карточку (:where — чтобы мобильные правила ниже,
   той же специфичности, его перекрывали). На телефоне фото сверху —
   мобильный блок в конце файла. */
.event-card-priority {
  --card-panel-width: calc(50% - var(--space-6) / 2); /* полколонки сетки без половины зазора */
}

.event-card-priority .priority-image {
  position: absolute;
  left: 0;
  top: 0;
  width: calc(100% - var(--card-panel-width) + var(--radius-xl));
  height: 100%;
  background: var(--color-photo-bg);
}

.event-card-priority .priority-image:where(:has(+ .event-card-variant)) {
  width: 100%;
}

.event-card-priority:not(.event-card-priority-vertical) .priority-panel {
  position: absolute;
  right: 0;
  top: 0;
  width: var(--card-panel-width);
  height: 100%;
  /* Скругление со всех сторон: правые углы нельзя доверять overflow:hidden
     карточки — стеклянная панель с backdrop-filter из-под него выходит. */
  border-radius: 32px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Две трети сетки (панель и описание) плюс половина зазора; фото — слева
   от них и под скруглением панели (см. .event-card-priority выше). */
.event-card-main {
  --card-info-width: calc((100% - var(--space-6)) * 2 / 3 + var(--space-6) / 2);
}

.event-card-main .priority-image {
  position: absolute;
  left: 0;
  top: 0;
  width: calc(100% - var(--card-info-width) + var(--radius-xl));
  height: 100%;
  background: var(--color-photo-bg);
}

.event-card-main .info-container {
  position: absolute;
  right: 0;
  top: 0;
  width: var(--card-info-width);
  height: 100%;
  display: flex;
}

.event-card-main .priority-panel {
  width: 50%;
  height: 100%;
  border-radius: 32px 0 0 32px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  min-width: 0;
}

.event-card-main .description-panel {
  width: 50%;
  height: 100%;
  padding: 24px;
  font-family: 'Onest', sans-serif;
  font-size: 14px;
  line-height: 20px;
  color: #fff;
  border-radius: 0 32px 32px 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.event-card-main .description-panel p {
  margin: 0;
}

.event-card-main .description-panel p:first-child {
  margin-bottom: 16px;
}

.event-card-main[data-type="tech"] .description-panel { background: var(--color-type-tech); }
.event-card-main[data-type="music"] .description-panel { background: var(--color-type-music); }
.event-card-main[data-type="art"] .description-panel { background: var(--color-type-art); }
.event-card-main[data-type="sport"] .description-panel { background: var(--color-brand); }
.event-card-main[data-type="cinema"] .description-panel { background: var(--color-type-cinema); }
.event-card-main[data-type="games"] .description-panel { background: var(--color-type-games); }
.event-card-main[data-type="theatre"] .description-panel { background: var(--color-type-theatre); }
.event-card-main[data-type="knowledge"] .description-panel { background: var(--color-type-knowledge); }
.event-card-main[data-type="city"] .description-panel { background: var(--color-type-city); }
.event-card-main[data-type="other"] .description-panel { background: var(--color-type-other); }

/* Панель снизу высотой с обычную карточку; фото — над ней и под её
   скруглением (см. .event-card-priority выше). Стеклянная — фото на всю. */
.event-card-priority-vertical {
  --card-panel-height: 352px;
}

.event-card-priority-vertical .priority-image {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: calc(100% - var(--card-panel-height) + var(--radius-xl));
  background: var(--color-photo-bg);
}

.event-card-priority-vertical .priority-image:where(:has(+ .event-card-variant)) {
  height: 100%;
}

.event-card-priority-vertical .priority-panel {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: var(--card-panel-height);
  border-radius: 32px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.event-card-standard {
  height: 352px;
  background: #fff;
  border-radius: 32px;
  padding: 24px;
}

.event-card-standard.event-card-bordered {
  background: transparent;
  border: 2px solid;
}

.event-card-standard.event-card-bordered[data-type="tech"] {
  border-color: var(--color-type-tech);
}

.event-card-standard.event-card-bordered[data-type="music"] {
  border-color: var(--color-type-music);
}

.event-card-standard.event-card-bordered[data-type="games"] {
  border-color: var(--color-type-games);
}
.event-card-standard.event-card-bordered[data-type="theatre"] {
  border-color: var(--color-type-theatre);
}
.event-card-standard.event-card-bordered[data-type="knowledge"] {
  border-color: var(--color-type-knowledge);
}
.event-card-standard.event-card-bordered[data-type="city"] {
  border-color: var(--color-type-city);
}
.event-card-standard.event-card-bordered[data-type="other"] {
  border-color: var(--color-type-other);
}

.event-card-standard.event-card-bordered[data-type="art"] {
  border-color: var(--color-type-art);
}

.event-card-standard.event-card-bordered[data-type="sport"] {
  border-color: var(--color-brand);
}

.event-card-standard.event-card-bordered[data-type="cinema"] {
  border-color: var(--color-type-cinema);
}

.event-card-standard.event-card-filled {
  border: none;
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
}

.event-card-standard.event-card-filled:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) {
  box-shadow: 0 0 32px 0 var(--color-overlay-8);
}

.event-card-standard.event-card-filled[data-type="tech"] {
  background: var(--color-type-tech);
}

.event-card-standard.event-card-filled[data-type="music"] {
  background: var(--color-type-music);
}

.event-card-standard.event-card-filled[data-type="art"] {
  background: var(--color-type-art);
}

.event-card-standard.event-card-filled[data-type="sport"] {
  background: var(--color-brand);
}

.event-card-standard.event-card-filled[data-type="cinema"] {
  background: var(--color-type-cinema);
}

.event-card-standard.event-card-filled[data-type="games"] {
  background: var(--color-type-games);
}
.event-card-standard.event-card-filled[data-type="theatre"] {
  background: var(--color-type-theatre);
}
.event-card-standard.event-card-filled[data-type="knowledge"] {
  background: var(--color-type-knowledge);
}
.event-card-standard.event-card-filled[data-type="city"] {
  background: var(--color-type-city);
}
.event-card-standard.event-card-filled[data-type="other"] {
  background: var(--color-type-other);
}

.event-card-standard.event-card-filled .event-avatar {
  border: 3px solid #fff !important;
  background: var(--color-photo-bg) !important;
}

.event-card-standard.event-card-filled .event-type-badge {
  background: #fff !important;
}

.event-card-standard.event-card-filled .event-type-badge .material-symbols-rounded {
  font-size: 18px;
}

.event-card-standard.event-card-filled[data-type="tech"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-tech) !important;
}

.event-card-standard.event-card-filled[data-type="music"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-music) !important;
}

.event-card-standard.event-card-filled[data-type="art"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-art) !important;
}

.event-card-standard.event-card-filled[data-type="sport"] .event-type-badge .material-symbols-rounded {
  color: var(--color-brand) !important;
}

.event-card-standard.event-card-filled[data-type="cinema"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-cinema) !important;
}

.event-card-standard.event-card-filled[data-type="games"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-games) !important;
}
.event-card-standard.event-card-filled[data-type="theatre"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-theatre) !important;
}
.event-card-standard.event-card-filled[data-type="knowledge"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-knowledge) !important;
}
.event-card-standard.event-card-filled[data-type="city"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-city) !important;
}
.event-card-standard.event-card-filled[data-type="other"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-other) !important;
}

.event-card-standard.event-card-filled .event-title,
.similar-event-card.service-card.event-card-filled .event-title {
  color: #fff;
  transition: color var(--duration-base) var(--ease-out);
}

.event-card-standard.event-card-filled:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) .event-title,
.similar-event-card.service-card.event-card-filled:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) .event-title {
  color: rgba(255, 255, 255, 0.6);
}

.event-card-standard.event-card-filled .event-tag {
  color: var(--color-on-dark-80);
}

.event-card-standard.event-card-filled .event-tag-dot {
  background: #fff;
}

.priority-panel.event-card-filled:not(.event-card-variant) .event-avatar {
  border: 3px solid #fff !important;
  background: var(--color-photo-bg) !important;
}

.priority-panel.event-card-filled:not(.event-card-variant) .event-type-badge {
  background: #fff !important;
}

.priority-panel.event-card-filled:not(.event-card-variant) .event-type-badge .material-symbols-rounded {
  font-size: 18px;
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="tech"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-tech) !important;
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="music"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-music) !important;
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="art"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-art) !important;
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="sport"] .event-type-badge .material-symbols-rounded {
  color: var(--color-brand) !important;
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="cinema"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-cinema) !important;
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="games"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-games) !important;
}
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="theatre"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-theatre) !important;
}
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="knowledge"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-knowledge) !important;
}
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="city"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-city) !important;
}
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="other"] .event-type-badge .material-symbols-rounded {
  color: var(--color-type-other) !important;
}

.priority-panel.event-card-filled:not(.event-card-variant) {
  background: #fff;
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="tech"] {
  background: var(--color-type-tech);
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="music"] {
  background: var(--color-type-music);
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="art"] {
  background: var(--color-type-art);
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="sport"] {
  background: var(--color-brand);
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="cinema"] {
  background: var(--color-type-cinema);
}

.priority-panel.event-card-filled:not(.event-card-variant)[data-type="games"] {
  background: var(--color-type-games);
}
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="theatre"] {
  background: var(--color-type-theatre);
}
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="knowledge"] {
  background: var(--color-type-knowledge);
}
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="city"] {
  background: var(--color-type-city);
}
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="other"] {
  background: var(--color-type-other);
}
/* Обложка поста вперемешку (PostSlide, type ''): фирменный синий, как у логотипа. */
.priority-panel.event-card-filled:not(.event-card-variant)[data-type="mixed"] {
  background: var(--color-brand);
}

.event-card-standard.event-card-filled .event-date,
.event-card-standard.event-card-filled .event-location {
  color: #fff;
  border-color: var(--color-on-dark-32);
}

.event-card-standard .event-avatar {
  position: relative;
  display: inline-block;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  border: 3px solid;
  background: var(--color-photo-bg);
}

.event-card-standard[data-type="tech"] .event-avatar {
  border-color: var(--color-type-tech);
}

.event-card-standard[data-type="music"] .event-avatar {
  border-color: var(--color-type-music);
}

.event-card-standard[data-type="games"] .event-avatar {
  border-color: var(--color-type-games);
}
.event-card-standard[data-type="theatre"] .event-avatar {
  border-color: var(--color-type-theatre);
}
.event-card-standard[data-type="knowledge"] .event-avatar {
  border-color: var(--color-type-knowledge);
}
.event-card-standard[data-type="city"] .event-avatar {
  border-color: var(--color-type-city);
}
.event-card-standard[data-type="other"] .event-avatar {
  border-color: var(--color-type-other);
}

.event-card-standard[data-type="art"] .event-avatar {
  border-color: var(--color-type-art);
}

.event-card-standard[data-type="art"] .event-type-badge {
  background: var(--color-type-art);
}

.event-card-standard[data-type="sport"] .event-avatar {
  border-color: var(--color-brand);
}

.event-card-standard[data-type="sport"] .event-type-badge {
  background: var(--color-brand);
}

.event-card-standard[data-type="cinema"] .event-avatar {
  border-color: var(--color-type-cinema);
}

.event-card-standard[data-type="cinema"] .event-type-badge {
  background: var(--color-type-cinema);
}

.event-card-standard[data-type="games"] .event-avatar {
  border-color: var(--color-type-games);
}
.event-card-standard[data-type="theatre"] .event-avatar {
  border-color: var(--color-type-theatre);
}
.event-card-standard[data-type="knowledge"] .event-avatar {
  border-color: var(--color-type-knowledge);
}
.event-card-standard[data-type="city"] .event-avatar {
  border-color: var(--color-type-city);
}

.event-card-standard[data-type="games"] .event-type-badge {
  background: var(--color-type-games);
}
.event-card-standard[data-type="theatre"] .event-type-badge {
  background: var(--color-type-theatre);
}
.event-card-standard[data-type="knowledge"] .event-type-badge {
  background: var(--color-type-knowledge);
}
.event-card-standard[data-type="city"] .event-type-badge {
  background: var(--color-type-city);
}
.event-card-standard[data-type="other"] .event-type-badge {
  background: var(--color-type-other);
}

.event-card-standard[data-type="tech"] .event-type-badge {
  background: var(--color-type-tech);
}

.event-card-standard[data-type="music"] .event-type-badge {
  background: var(--color-type-music);
}

.event-card-standard .event-type-badge {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  bottom: -4px;
  right: -4px;
}

.event-card-variant .event-avatar {
  border: 3px solid #fff !important;
  background: transparent !important;
}

.event-card-variant .event-type-badge {
  background: #fff !important;
  position: absolute !important;
  bottom: -4px !important;
  right: -4px !important;
  width: 32px !important;
  height: 32px !important;
  border: none !important;
}

.event-card-variant .event-type-badge .material-symbols-rounded {
  /* размер — общий, 20px из components.css */
}

.event-card-variant[data-type="tech"] .event-type-badge .material-symbols-rounded { color: var(--color-type-tech) !important; }
.event-card-variant[data-type="music"] .event-type-badge .material-symbols-rounded { color: var(--color-type-music) !important; }
.event-card-variant[data-type="art"] .event-type-badge .material-symbols-rounded { color: var(--color-type-art) !important; }
.event-card-variant[data-type="sport"] .event-type-badge .material-symbols-rounded { color: var(--color-brand) !important; }
.event-card-variant[data-type="cinema"] .event-type-badge .material-symbols-rounded { color: var(--color-type-cinema) !important; }
.event-card-variant[data-type="games"] .event-type-badge .material-symbols-rounded { color: var(--color-type-games) !important; }
.event-card-variant[data-type="theatre"] .event-type-badge .material-symbols-rounded { color: var(--color-type-theatre) !important; }
.event-card-variant[data-type="knowledge"] .event-type-badge .material-symbols-rounded { color: var(--color-type-knowledge) !important; }
.event-card-variant[data-type="city"] .event-type-badge .material-symbols-rounded { color: var(--color-type-city) !important; }
.event-card-variant[data-type="other"] .event-type-badge .material-symbols-rounded { color: var(--color-type-other) !important; }

.event-card-standard .event-type-badge .material-symbols-rounded {
  color: #fff;
  font-size: 18px;
}

.priority-panel.event-card-variant {
  background: var(--color-overlay-32) !important;
  backdrop-filter: blur(32px) !important;
  -webkit-backdrop-filter: blur(32px) !important;
}

.priority-panel.event-card-variant .event-avatar {
  border: 3px solid #fff !important;
  background: transparent !important;
}

.priority-panel.event-card-variant .event-type-badge {
  background: #fff !important;
}

.priority-panel.event-card-variant[data-type="tech"] .event-type-badge .material-symbols-rounded { color: var(--color-type-tech) !important; }
.priority-panel.event-card-variant[data-type="music"] .event-type-badge .material-symbols-rounded { color: var(--color-type-music) !important; }
.priority-panel.event-card-variant[data-type="art"] .event-type-badge .material-symbols-rounded { color: var(--color-type-art) !important; }
.priority-panel.event-card-variant[data-type="sport"] .event-type-badge .material-symbols-rounded { color: var(--color-brand) !important; }
.priority-panel.event-card-variant[data-type="cinema"] .event-type-badge .material-symbols-rounded { color: var(--color-type-cinema) !important; }
.priority-panel.event-card-variant[data-type="games"] .event-type-badge .material-symbols-rounded { color: var(--color-type-games) !important; }
.priority-panel.event-card-variant[data-type="theatre"] .event-type-badge .material-symbols-rounded { color: var(--color-type-theatre) !important; }
.priority-panel.event-card-variant[data-type="knowledge"] .event-type-badge .material-symbols-rounded { color: var(--color-type-knowledge) !important; }
.priority-panel.event-card-variant[data-type="city"] .event-type-badge .material-symbols-rounded { color: var(--color-type-city) !important; }
.priority-panel.event-card-variant[data-type="other"] .event-type-badge .material-symbols-rounded { color: var(--color-type-other) !important; }

.event-card-standard .event-title {
  font-family: 'Unbounded', sans-serif;
  font-size: 16px;
  font-weight: 700;
  line-height: 24px;
  color: var(--color-ink);
  margin-top: 16px;
  margin-bottom: 4px;
  transition: color var(--duration-base) var(--ease-out);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

.event-card-standard:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) .event-title {
  color: var(--color-brand);
}

.event-card-standard.event-card-filled .event-type-badge .material-symbols-rounded {
  font-size: 18px;
}

.event-card-standard .event-tags {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  overflow: hidden;
  flex-wrap: nowrap;
  white-space: nowrap;
}

.event-card-main .event-tags,
.event-card-priority .event-tags,
.event-card-priority-vertical .event-tags {
  display: flex;
  align-items: center;
  gap: 8px;
  overflow: hidden;
  flex-wrap: nowrap;
  white-space: nowrap;
}

.event-card-main .event-tag,
.event-card-priority .event-tag,
.event-card-priority-vertical .event-tag {
  font-family: 'Onest', sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  color: var(--color-on-dark-80);
  flex-shrink: 0;
}

.event-card-main .event-tag-dot,
.event-card-priority .event-tag-dot,
.event-card-priority-vertical .event-tag-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #fff;
}

.event-card-standard .event-tag {
  font-family: 'Onest', sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  color: var(--color-ink-secondary);
  flex-shrink: 0;
}

.event-card-standard .event-tag-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--color-ink);
}

.event-card-standard {
  min-width: 0;
}

.event-card-standard .event-place {
  display: none;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
  flex-shrink: 0;
}

.event-card-standard .event-place:has(.event-date:not(:empty)),
.event-card-standard .event-place:has(.event-location:not(:empty)) {
  display: flex;
}

.event-card-standard .event-date {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: var(--color-ink);
  padding: 6px 12px;
  border-radius: 100px;
  background: transparent;
  border: 1px solid var(--color-border);
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 1;
  min-width: 0;
}

.event-card-standard .event-date:empty {
  display: none;
}

.event-card-standard .event-location {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: var(--color-ink);
  padding: 6px 12px;
  border-radius: 100px;
  background: transparent;
  border: 1px solid var(--color-border);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-sizing: border-box;
  flex-shrink: 1;
  flex-basis: auto;
  min-width: 0;
  display: inline-block;
}

.event-card-standard .event-location:empty {
  display: none;
}

/* Диапазон дат — две ссылки в одной плашке (DatePlace): отступы плашки
   переходят к частям, у каждой своя заливка на всю высоту. Наведение — components.css. */
.event-card-standard .event-date.is-split {
  padding: 0;
  display: inline-flex;
}

/* Не влезает — сокращается первая часть (дата), «ещё N дат» остаётся целиком. */
.event-card-standard .event-date.is-split > :first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.event-card-standard .event-date.is-split > :not(:first-child) { flex-shrink: 0; white-space: nowrap; }

.event-card-standard .event-date-part {
  display: inline-block;
  padding: 6px 4px;
  border-radius: 100px;
}

/* Крайние поля — у крайних частей любого вида: первой может быть подпись
   («до 14 октября»), последней — «ещё N дат». */
.event-card-standard .event-date.is-split > :first-child { padding-left: 12px; }
.event-card-standard .event-date.is-split > :last-child { padding-right: 12px; }
.event-card-standard .event-date-sep { display: inline-block; padding: 6px 0; }

.event-skeleton {
  background: var(--color-skeleton);
  border-radius: 32px;
}

.event-skeleton-standard {
  height: 352px;
  background: var(--color-skeleton);
}

.event-skeleton-priority {
  grid-column: span 2;
  grid-row: span 1;
  height: 352px;
  background: var(--color-skeleton);
}

.event-skeleton-priority-vertical {
  grid-column: span 1;
  grid-row: span 2;
  height: calc(352px * 2 + 24px);
  background: var(--color-skeleton);
}

.event-skeleton-main {
  grid-column: 1 / 4;
  grid-row: span 1;
  height: 352px;
  background: var(--color-skeleton);
}
/* Пустая лента: занимает всю строку сетки. Оформление — общее,
   в components.css (состояния пусто / ошибка / не найдено). */
.empty-state {
  grid-column: 1 / 4;
}

.filters-skeleton,
.dates-skeleton {
  display: flex;
  gap: 12px;
  align-items: center;
}

.skeleton-filter:nth-child(2) { width: 100px; }
.skeleton-filter:nth-child(3) { width: 140px; }
.skeleton-filter:nth-child(4) { width: 90px; }
.skeleton-filter:nth-child(5) { width: 110px; }
.skeleton-filter:nth-child(6) { width: 130px; }
.skeleton-filter:nth-child(7) { width: 95px; }

/* ---------- Мобильная версия (≤ 767px) ----------
   Лента — одна колонка карточек во всю ширину экрана, от края до края,
   с отступом 16px. Внутри карточки аватарка 64px стоит слева от названия
   и жанров, плашки даты и места — ниже, через 16px. У крупных карточек
   (priority, priority-vertical, main) сверху фото высотой 210px, цветная
   или стеклянная панель заходит на него скруглёнными углами. Высота карточек
   — по содержимому. */
@media (max-width: 767px) {
  /* На телефоне сетка и список почти одинаковы (одна колонка), а ряд фильтров
     листается до края экрана — переключатель вида не показываем. */
  .feed-controls { display: block; margin-top: var(--space-mobile); }
  /* Ряд с порядком (TypePick rows): категории, затем «Расширенные фильтры» и порядок в одну строку. */
  .feed-controls:has(> .type-pick--rows) { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-2); }
  .feed-controls:has(> .type-pick--rows) > .feed-sort { flex: 1 1 0; min-width: 0; margin-top: 0; }
  .feed-controls:has(> .type-pick--rows) > .feed-sort > .dropdown { width: 100%; }
  .feed-view { display: none; }
  /* Порядок — своей строкой под выбором категорий: 16, как внутри блока. */
  .feed-sort { margin-top: var(--space-4); }

  .events {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    grid-auto-flow: row;
    gap: 16px;
    margin: var(--space-mobile) calc(-1 * var(--space-mobile)) 0;
  }

  /* Чипсы «Ленты» на телефоне — через --space-mobile от шапки, как сетка под ними (выше). */
  #lenta-root > .page-header + .filters { margin-top: var(--space-mobile); }

  /* Ряды страницы понятия (352px) сильнее правила выше — сбрасываем отдельно. */
  .page-concept .events,
  .page-similar .events,
  .page-search .events,
  .page-profile .events,
  .page-my .events,
  .page-lenta .events,
  .page-podborka .events {
    grid-auto-rows: auto;
  }

  .events > *,
  .events-row > * {
    grid-column: auto !important;
    grid-row: auto !important;
  }

  /* Простые карточки */
  .event-card-standard {
    height: auto;
    padding: var(--space-mobile);
  }

  .event-card-content {
    display: flex;
    align-items: center;
    gap: var(--space-4);
  }

  .event-info {
    min-width: 0;
  }

  .event-card-standard .event-avatar {
    width: 64px;
    height: 64px;
    flex-shrink: 0;
  }

  .event-card-standard .event-title {
    margin-top: 0;
  }

  .event-card-standard .event-tags {
    flex-wrap: nowrap;
    overflow: hidden;
  }

  .event-card-standard .event-place {
    margin-top: var(--space-4);
  }

  /* Крупные карточки: фото сверху, панель под ним */
  .event-card-priority,
  .event-card-priority-vertical,
  .event-card-main {
    height: auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  .event-card-priority .priority-image,
  .event-card-priority-vertical .priority-image,
  .event-card-main .priority-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: calc(210px + var(--radius-xl)); /* уходит под скругление панели */
  }

  .event-card-main .info-container {
    position: relative;
    inset: auto;
    width: 100%;
    height: auto;
    margin-top: 210px;
    padding: 0;
    display: block;
  }

  .event-card-main .description-panel {
    display: none;
  }

  .event-card-priority:not(.event-card-priority-vertical) .priority-panel,
  .event-card-priority-vertical .priority-panel,
  .event-card-main .priority-panel {
    position: relative;
    inset: auto;
    width: 100%;
    height: auto;
    margin-top: 210px;
    padding: var(--space-mobile);
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    grid-template-areas:
      "avatar title"
      "avatar tags"
      "place  place";
    column-gap: var(--space-4);
    align-content: start;
    align-items: center;
  }

  .event-card-main .priority-panel {
    margin-top: 0;
  }

  .priority-panel .event-avatar {
    grid-area: avatar;
    width: 64px;
    height: 64px;
  }

  .priority-panel .event-title {
    grid-area: title;
    align-self: end;
    margin: 0 0 4px;
  }

  .priority-panel .event-tags {
    grid-area: tags;
    align-self: start;
    flex-wrap: nowrap;
    overflow: hidden;
  }

  .priority-panel .event-place {
    grid-area: place;
    margin-top: var(--space-4);
  }

  .show-more-container {
    padding: var(--space-mobile) 0 0;
  }
}



/*
 * Шапка страницы дня: дата заголовком и кнопка-календарь справа.
 * Раньше жила во встроенном <style> day.html — оттуда её не перебить
 * мобильными правилами, да и стили компонентов в инлайн страниц не кладут.
 */

.day-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.day-page-title {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: var(--weight-bold);
  color: var(--color-ink);
}

.day-page-back-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: transparent;
  cursor: pointer;
  transition: var(--transition-colors);
  flex-shrink: 0;
  text-decoration: none;
}

.day-page-back-btn:hover {
  background: var(--color-hover);
  border-color: transparent;
}

.day-page-back-btn .material-symbols-rounded {
  color: var(--color-ink-alt);
}

.day-page-back-btn:hover .material-symbols-rounded {
  color: var(--color-brand);
}

/* Над рядом управления (.feed-controls: категории, порядок, вид — events.css, как в ленте)
   — разделитель .divider (24 от шапки, 24 до ряда; телефон 20/20), как в ленте и у понятия. */

/* ---------- Мобильная версия (≤ 767px) ----------
   Как в макете: дата в одну строку кеглем 24/32, кнопка 44×44, до фильтров 20px. */
@media (max-width: 767px) {
  .day-page-header {
    margin-bottom: var(--space-mobile);
  }

  .day-page-title {
    font-size: var(--text-2xl);
    line-height: 32px;
  }

  .day-page-back-btn {
    width: 44px;
    height: 44px;
  }
}



.event-detail {
  color: var(--color-ink);
}

.event-detail h1 {
  font-family: 'Unbounded', sans-serif;
  font-size: 24px;
  font-weight: 700;
  margin-bottom: 16px;
}

.event-detail p {
  font-family: 'Onest', sans-serif;
  font-size: 16px;
  color: #5c5f66;
}

/* Сетка ленты на главной: тело — ровно две колонки из трёх (--grid-gap, как у
   .events), правый край на месте. Промежуток герой → тело — 48 (--space-12),
   а не 24 сетки: лишние 24 забирает герой — он на столько же уже колонки ленты,
   левый край тоже на месте (решение 13.10.2026). Колонки считаются от ширины
   содержимого страницы. Так же устроен профиль: та же раскладка и тот же герой. */
.event-detail-layout {
  --event-gap: var(--space-12);
  --event-column: calc((100% - 2 * var(--grid-gap)) / 3 - (var(--event-gap) - var(--grid-gap)));
  display: flex;
  flex-wrap: wrap;
  gap: var(--event-gap);
  row-gap: var(--space-6);
  align-items: flex-start;
}

/* «Назад» (BackButton) — строкой над обеими колонками; отступ до них даёт row-gap. */
.event-detail-layout > .back-row {
  flex-basis: 100%;
  margin-bottom: 0;
}

/* Ленты слайдеров идут до края экрана (см. .similar-events-list), поэтому
   колонки не обрезают содержимое. Поле до края: отступ .content-inner (24px)
   и, на экране шире страницы, поле центрированного body. Горизонтальной
   прокрутки не будет: overflow-x: hidden у body действует на окно.
   min-width: 0 — раньше его неявно давал overflow: hidden; без него колонка
   растягивается под всю ленту. */
body.page-event .content,
body.page-event .content-inner.event-detail-layout {
  overflow: visible;
  min-width: 0;
}

body.page-event .event-detail-layout {
  --slider-bleed: calc(var(--space-6) + max(0px, (100vw - var(--page-max-width)) / 2));
}

#event-detail-left {
  width: var(--event-column);
  min-height: 600px;
  border-radius: 32px;
  flex-shrink: 0;
  overflow: visible;
  position: relative;
}

#event-detail-left.has-content {
  background: var(--color-hero-bg);
}

/* Фото события — над героем, а не на всю колонку. Колонка высокая, и cover
   по всей её высоте показывал над героем сильно увеличенный кусок снимка.
   Слой .event-hero-photo (ui.heroPhoto: Photo с размытым превью) высотой с
   видимую область: отступ героя плюс скругление его подложки — фото заходит под
   скруглённые углы, там нет пустоты. Отступ героя берётся из той же переменной
   (.event-hero), чтобы они не разъехались. Снимок — Iwent.heroBackground; нет
   снимка — слоя нет, видна тёмная подложка. z-index не задан: слой ниже героя
   (z-index: 1), а заглушку загрузки не закрывает — он есть только у .has-content. */
#event-detail-left {
  --event-hero-offset: 210px;
}

#event-detail-left.has-content > .event-hero-photo {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: calc(var(--event-hero-offset) + var(--radius-xl));
  border-top-left-radius: inherit;
  border-top-right-radius: inherit;
}

.event-hero {
  position: relative;
  min-height: 400px;
  padding: 24px 24px 24px;
  margin-top: var(--event-hero-offset);
  z-index: 1;
}

.event-hero-bg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: var(--radius-xl); /* под углы заходит фото: ::before колонки */
  background: var(--color-type-tech);
  z-index: -2;
}

.event-hero[data-type="tech"] .event-hero-bg {
  background: var(--color-type-tech);
}

.event-hero[data-type="music"] .event-hero-bg {
  background: var(--color-type-music);
}

.event-hero[data-type="art"] .event-hero-bg {
  background: var(--color-type-art);
}

.event-hero[data-type="sport"] .event-hero-bg {
  background: var(--color-brand);
}

.event-hero[data-type="cinema"] .event-hero-bg {
  background: var(--color-type-cinema);
}

.event-hero[data-type="games"] .event-hero-bg {
  background: var(--color-type-games);
}
.event-hero[data-type="theatre"] .event-hero-bg {
  background: var(--color-type-theatre);
}
.event-hero[data-type="knowledge"] .event-hero-bg {
  background: var(--color-type-knowledge);
}
.event-hero[data-type="city"] .event-hero-bg {
  background: var(--color-type-city);
}
.event-hero[data-type="other"] .event-hero-bg {
  background: var(--color-type-other);
}
/* Герой человека (PersonHero, профиль): подложка цвета бренда. */
.event-hero[data-type="person"] .event-hero-bg {
  background: var(--color-brand);
}

.event-avatar-wrap {
  position: relative;
  width: 128px;
  height: 128px;
  border-radius: 32px;
  margin-top: -92px;
  margin-bottom: 16px;
  overflow: visible;
}

.event-avatar-wrap .event-avatar-container {
  position: absolute;
  top: 0;
  left: 0;
}

.event-avatar-container {
  position: relative;
  margin-bottom: 16px;
}

/* Буква названия (AvatarLetter) и картинка — в одной ячейке сетки, картинка
   сверху. Не position: relative — бейдж категории позиционируется от
   .event-avatar-container и иначе обрезался бы краем круга (overflow). */
.event-avatar-large {
  display: grid;
  width: 128px;
  height: 128px;
  border-radius: 50%;
  border: 3px solid #fff;
  overflow: hidden;
  background: var(--color-on-dark-20);
}

.event-avatar-large > :is(.event-avatar-letter, .event-avatar-image) {
  grid-area: 1 / 1;
}

.event-avatar-large > .event-avatar-letter {
  position: static;
}

/* Слой картинки поверх буквы названия: прозрачный — не загрузилась
   картинка (404), видна буква, а не чёрный круг. */
.event-avatar-image {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: transparent;
  border-radius: 50%;
}

.event-type-icon-badge {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}

.event-type-icon-badge .material-symbols-rounded {
  font-size: 18px;
  color: var(--color-type-tech);
}

.event-hero[data-type="tech"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-tech);
}

.event-hero[data-type="music"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-music);
}

.event-hero[data-type="art"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-art);
}

.event-hero[data-type="sport"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-brand);
}

.event-hero[data-type="cinema"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-cinema);
}

.event-hero[data-type="games"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-games);
}
.event-hero[data-type="theatre"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-theatre);
}
.event-hero[data-type="knowledge"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-knowledge);
}
.event-hero[data-type="city"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-city);
}
.event-hero[data-type="other"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-type-other);
}
/* У человека в бейдже — уровень числом (как кружок уровня у UserAvatar), без уровня — иконка. */
.event-hero[data-type="person"] .event-type-icon-badge .material-symbols-rounded {
  color: var(--color-brand);
}
.event-hero-level {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: var(--space-4);
  color: var(--event-type-color, var(--color-brand)); /* цвет человека (PersonHero color), без него — бренд */
}

.event-title {
  font-family: 'Unbounded', sans-serif;
  font-size: 24px;
  font-weight: 700;
  line-height: 32px;
  color: #fff;
  margin-bottom: 4px;
  word-break: break-word;
  overflow-wrap: break-word;
}

.event-tags {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}

/* Плашки под тегами героя (ui.eventStatusChips): статус на источнике («Отменено»,
   «Перенесено на …», «Снято с афиши») и «18+»; строкой, без своей высоты строки;
   от тегов — их 16, до плашек даты и места — 16, как от тегов; между плашками — 8. */
.event-status {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.event-status + .event-datetime-location {
  margin-top: var(--space-4);
}

.event-tag {
  font-family: 'Onest', sans-serif;
  font-size: 14px;
  line-height: 20px;
  color: var(--color-on-dark-80); /* второстепенный текст на цветном (герой события) */
  white-space: nowrap;
}

.event-tag-dot {
  display: inline-block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #fff;
  flex-shrink: 0;
}

.event-datetime-location {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  align-items: flex-start;
  min-width: 0;
  width: 100%;
  box-sizing: border-box;
}

.event-datetime-location:has(.event-datetime:empty):has(.event-location:empty) {
  display: none;
}

.event-datetime,
.event-location {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: #fff;
  background: transparent;
  padding: 8px 12px;
  border: 1px solid var(--color-on-dark-32);
  border-radius: 100px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
}

.event-datetime {
  flex-shrink: 0;
}

.event-location {
  flex-shrink: 1;
  flex-basis: auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
}

.event-datetime:empty,
.event-location:empty {
  display: none;
}

/* Плашки-ссылки: дата ведёт на свой день, площадка — на её страницу.
   Наведение — как у кнопки (.btn:hover): рамка пропадает, плашка заливается
   цветом рамки. У диапазона ссылки — половинки внутри общей рамки: заливается
   наведённая половина, рамка плашки остаётся контуром второй. */
/* Только в плашках героя (.event-datetime-location): a.event-location — тот же
   класс, что у площадки в карточке, правило не должно туда протекать. */
.event-datetime-location :is(a.event-datetime, a.event-location, .event-datetime-part) {
  color: var(--color-surface);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out), color var(--duration-base) var(--ease-out);
}

/* Наведение на цветной подложке — одно для плашек и кнопок с обводкой (.btn-hero-outline): белый 24%. */
.event-datetime-location :is(a.event-datetime, a.event-location, .event-datetime-part):is(:hover, :focus-visible) {
  background: var(--color-on-dark-24);
  border-color: transparent;
}

/* Диапазон: начало и конец — отдельные ссылки, каждая со своей заливкой
   на всю высоту плашки; отступы плашки переходят к ним. */
.event-datetime.is-split {
  padding: 0;
}

.event-datetime-part {
  display: inline-block;
  padding: var(--space-2) var(--space-1);
  border-radius: var(--radius-pill);
}

.event-datetime-part:first-child { padding-left: var(--space-3); }
.event-datetime-part:last-child { padding-right: var(--space-3); }

.event-divider {
  height: 1px;
  background: var(--color-on-dark-24);
  margin: 24px 0;
}

.recommended-event {
  margin-top: 24px;
}

.recommended-event-card {
  background: #fff;
  border-radius: 24px;
  padding: 16px;
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
}

/* В записи ленты активности карточка не ссылка — без наведения (components.css, ActivityCard). */
.recommended-event-card:not(.activity-card *):hover:not(:has(:where(a:not(.recommended-title), button, .recommended-datetime, .recommended-location, .recommended-tags > span:not(.recommended-tag-dot)):hover)) {
  box-shadow: 0 0 32px 0 var(--color-overlay-8);
}

.recommended-event-main {
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
}

.recommended-avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 3px solid var(--color-photo-bg);
  overflow: visible;
  flex-shrink: 0;
  position: relative;
}

.recommended-avatar[data-type="tech"] {
  border-color: var(--color-type-tech);
}

.recommended-avatar[data-type="music"] {
  border-color: var(--color-type-music);
}

.recommended-avatar[data-type="art"] {
  border-color: var(--color-type-art);
}

.recommended-avatar[data-type="sport"] {
  border-color: var(--color-brand);
}

.recommended-avatar[data-type="cinema"] {
  border-color: var(--color-type-cinema);
}

.recommended-avatar[data-type="games"] {
  border-color: var(--color-type-games);
}
.recommended-avatar[data-type="theatre"] {
  border-color: var(--color-type-theatre);
}
.recommended-avatar[data-type="knowledge"] {
  border-color: var(--color-type-knowledge);
}
.recommended-avatar[data-type="city"] {
  border-color: var(--color-type-city);
}
.recommended-avatar[data-type="other"] {
  border-color: var(--color-type-other);
}

.recommended-avatar-image {
  position: relative; /* поверх буквы названия (AvatarLetter) */
  width: 100%;
  height: 100%;
  background-color: transparent;
  border-radius: 50%;
}

.recommended-avatar-image[data-type="tech"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-tech);
}

.recommended-avatar-image[data-type="music"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-music);
}

.recommended-avatar-image[data-type="art"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-art);
}

.recommended-avatar-image[data-type="sport"] {
  background: var(--color-photo-bg);
  border-color: var(--color-brand);
}

.recommended-avatar-image[data-type="cinema"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-cinema);
}

.recommended-avatar-image[data-type="games"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-games);
}
.recommended-avatar-image[data-type="theatre"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-theatre);
}
.recommended-avatar-image[data-type="knowledge"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-knowledge);
}
.recommended-avatar-image[data-type="city"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-city);
}
.recommended-avatar-image[data-type="other"] {
  background: var(--color-photo-bg);
  border-color: var(--color-type-other);
}

.recommended-type-badge {
  position: absolute;
  bottom: -4px;
  right: -4px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-photo-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.recommended-type-badge[data-type="tech"] {
  background: var(--color-type-tech);
}

.recommended-type-badge[data-type="music"] {
  background: var(--color-type-music);
}

.recommended-type-badge[data-type="art"] {
  background: var(--color-type-art);
}

.recommended-type-badge[data-type="sport"] {
  background: var(--color-brand);
}

.recommended-type-badge[data-type="cinema"] {
  background: var(--color-type-cinema);
}

.recommended-type-badge[data-type="games"] {
  background: var(--color-type-games);
}
.recommended-type-badge[data-type="theatre"] {
  background: var(--color-type-theatre);
}
.recommended-type-badge[data-type="knowledge"] {
  background: var(--color-type-knowledge);
}
.recommended-type-badge[data-type="city"] {
  background: var(--color-type-city);
}
.recommended-type-badge[data-type="other"] {
  background: var(--color-type-other);
}

.recommended-type-badge .material-symbols-rounded {
  font-size: 16px;
  color: #fff;
}

.recommended-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
}

.recommended-title {
  font-family: 'Unbounded', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: var(--color-ink);
  margin-bottom: 4px;
  transition: color var(--duration-base) var(--ease-out);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-word;
}

.recommended-event-card:not(.activity-card *):hover:not(:has(:where(a:not(.recommended-title), button, .recommended-datetime, .recommended-location, .recommended-tags > span:not(.recommended-tag-dot)):hover)) .recommended-title {
  color: var(--color-brand);
}

.recommended-tags {
  display: flex;
  align-items: center;
  gap: 8px;
  overflow: hidden;
}

.recommended-tags span {
  font-family: 'Onest', sans-serif;
  font-size: 12px;
  line-height: 16px;
  color: var(--color-ink-secondary);
  white-space: nowrap;
}

.recommended-tag-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background-color: var(--color-ink) !important;
}

/* Пометка рекламы (RecommendedEventCard, ad): строка вида жанров под плашками,
   через 16; не обрезается — переносится (рекламодатель и erid по 38-ФЗ видны целиком). */
.recommended-ad {
  margin-top: var(--space-4);
  flex-wrap: wrap;
}

.recommended-datetime-location {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  align-items: flex-start;
  min-width: 0;
}

.recommended-datetime,
.recommended-location {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: var(--color-ink);
  padding: 8px 12px;
  border: 1px solid var(--color-border);
  border-radius: 100px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.recommended-datetime {
  flex-shrink: 0;
}

.recommended-location {
  flex-shrink: 1;
  flex-basis: auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
}

/* Диапазон дат в RecommendedEventCard — как в карточке ленты (DatePlace): две ссылки в одной плашке,
   отступы плашки переходят к частям, у каждой своя заливка на всю высоту; не влезает — сокращается
   первая часть. Наведение — components.css (плашки-ссылки карточек). */
.recommended-datetime.is-split { padding: 0; display: inline-flex; }
.recommended-datetime .event-date-part { display: inline-block; padding: var(--space-2) var(--space-1); border-radius: var(--radius-pill); color: inherit; }
.recommended-datetime .event-date-sep { display: inline-block; padding: var(--space-2) 0; }
.recommended-datetime.is-split > :first-child { padding-left: var(--space-3); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recommended-datetime.is-split > :not(:first-child) { flex-shrink: 0; white-space: nowrap; }
.recommended-datetime.is-split > :last-child { padding-right: var(--space-3); }

.similar-events {
  margin-top: 32px;
  position: relative;
  z-index: 1;
}

/* --slider-bleed — сколько ленте до правого края экрана. Лента заходит туда
   отрицательным отступом, а внутренним возвращает карточки к краю колонки: в
   покое и в конце прокрутки лента ровно под стрелками, при листании карточки
   уходят до края экрана, а не обрезаются колонкой. Вне страницы события — 0. */
.similar-events-list {
  display: flex;
  gap: 24px;
  overflow-x: auto;
  padding-bottom: 8px;
  margin-right: calc(-1 * var(--slider-bleed, 0px));
  padding-right: var(--slider-bleed, 0px);
}

.event-detail-title {
  font-family: 'Unbounded', sans-serif;
  font-size: 16px;
  font-weight: 700;
  line-height: 24px;
  color: var(--color-ink);
  margin: 0 0 16px;
}

/* Ширина строки — не больше --text-measure: тело события — две колонки сетки из
   трёх, на 1440 в публичной версии это 920px, строка описания выходила в 111
   знаков. Ряды фото и похожих событий остаются во всю колонку. */
.event-description {
  max-width: var(--text-measure);
  max-height: 200px;
  overflow: hidden;
  position: relative;
  /* Раскрытие по клику — единственная анимация высоты (Iwent.expandDescription). */
  transition: max-height var(--duration-slow) var(--ease-in-out);
}

.event-description::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 48px;
  background: linear-gradient(transparent, var(--color-bg));
  pointer-events: none;
  transition: opacity var(--duration-slow) var(--ease-out);
  opacity: 0;
}

.event-description.truncated::after {
  opacity: 1;
}

.event-description p {
  font-family: 'Onest', sans-serif;
  font-size: 16px;
  line-height: 24px;
  color: var(--color-ink);
  margin: 0;
}

.event-description p + p {
  margin-top: 16px;
}

/* Сноска последним абзацем (EventDescription, note): мелким серым, как подписи
   EventExtraInfo; источник — ссылка .concept-tag (цвет текста, синяя при наведении). */
.event-description p.event-description-note {
  font-size: var(--text-sm);
  line-height: 20px;
  color: var(--color-ink-secondary);
}

/* «Узнать больше» — MoreLink (вид — .more-link, components.css); здесь только
   место: скрыта, пока описание не обрезано, от текста — 16. */
.event-description-link {
  display: none;
  margin-top: 16px;
}

.event-description-link.visible {
  display: block;
}

/* До скрипта (страница от сервера, seo.js) описание ещё не измерено: обрезка
   и «Узнать больше» — там, где по оценке EventDescription (data-overflow)
   текст выше 200px. initDescriptionToggle потом меряет точно (data-toggle). */
@media (max-width: 767px) {
  .event-description[data-overflow~="sm"]:not([data-toggle])::after { opacity: 1; }
  .event-description[data-overflow~="sm"]:not([data-toggle]) + .event-description-link { display: block; }
}
@media (min-width: 768px) and (max-width: 1279px) {
  .event-description[data-overflow~="md"]:not([data-toggle])::after { opacity: 1; }
  .event-description[data-overflow~="md"]:not([data-toggle]) + .event-description-link { display: block; }
}
@media (min-width: 1280px) {
  .event-description[data-overflow~="lg"]:not([data-toggle])::after { opacity: 1; }
  .event-description[data-overflow~="lg"]:not([data-toggle]) + .event-description-link { display: block; }
}

.event-extra-info {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  margin-top: 24px;
}

/* В ряду не больше двух пар: третья переносится на новый ряд и занимает его
   целиком (у сериала «Дата», «Место», «Платформа» — «Платформа» ниже). */
.event-extra-block {
  flex: 1 1 calc(50% - 12px);
  min-width: 0;
}

.event-extra-label {
  font-family: 'Onest', sans-serif;
  font-size: 14px;
  line-height: 20px;
  color: var(--color-ink-secondary);
  margin-bottom: 4px;
}

.event-extra-value {
  font-family: 'Onest', sans-serif;
  font-size: 16px;
  line-height: 24px;
  color: var(--color-ink);
}


/* Счётчики события (StatList layout 'spread') — отдельный блок после
   сведений и тегов, до фото: снаружи 32, как у фото. Нет счётчиков —
   обёртка пустая и места не занимает. */
#event-stats > .stat-list {
  margin-top: var(--space-8);
}

/* Плитки медиаблока (снимки, видео) — в сетке новостей: .events, три колонки на всю колонку,
   обычная плитка — квадрат (ряды — от ширины, components.css «Новости»), двойные — как у
   новостей (Iwent.newsLayout). Кликабельные: курсор, фокус. */
.event-image {
  border-radius: var(--radius-lg);
  background: var(--color-photo-bg);
  min-width: 0;
  cursor: pointer;
  background-size: cover;
  background-position: center;
}

.event-image--wide { grid-column: span 2; }
.event-image--tall { grid-row: span 2; }

/* Наведение — тень, как у карточек событий (.event-card-standard:hover). */
.event-image { position: relative; transition: box-shadow var(--duration-base) var(--ease-out); }
.event-image:hover { box-shadow: 0 0 var(--space-8) 0 var(--color-overlay-8); }
.event-image .event-image-play { z-index: 1; }

.event-image:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
}

/* «Где и сколько» (VenueAddress в варианте страницы события) — отдельный блок
   после фото: снаружи 32, как у счётчиков и фото. */
#event-detail-right > .venue-address {
  margin-top: var(--space-8);
}

.event-detail-divider {
  height: 1px;
  background: var(--color-border);
  margin-top: 32px;
}

/* Заголовок блока под линией — через 32, как блоки между собой (не вплотную). */
.event-detail-divider + #event-news:not(:empty) {
  margin-top: var(--space-8);
}

.similar-events-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  /* Высота — как у стрелок и тогда, когда их нет (все карточки видны): иначе
     шапка после скрипта (initSimilarSlider) становилась ниже и страница,
     пришедшая от сервера готовой (seo.js), прыгала. */
  min-height: var(--control-height);
}

/* Ряд фильтров слайдера (SimilarEvents filters — режимы полки «Для вас»): от заголовка 16,
   до ленты или пустого состояния 24 — как заголовок до ленты. Только раскладка. */
.similar-events-header:has(+ .filters) { margin-bottom: var(--space-4); }
.similar-events-header + .filters { margin: 0 0 var(--space-6); }

.similar-events-title {
  font-family: 'Unbounded', sans-serif;
  font-size: 16px;
  font-weight: 700;
  line-height: 24px;
  color: var(--color-ink);
  margin: 0;
}

.similar-events-nav {
  display: flex;
  gap: 8px;
}

.similar-events-btn {
  width: 44px;
  height: 44px;
  border-radius: 16px;
  background: transparent;
  border: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition-colors);
}

/* Выключенная стрелка — как выключенная кнопка ДС (.btn:disabled, «Сегодня» в
   календаре): мягкая рамка, обычный курсор, на наведение не отзывается. */
.similar-events-btn:hover:not(:disabled) {
  background: var(--color-hover);
  border-color: transparent;
}

.similar-events-btn:hover:not(:disabled) .material-symbols-rounded {
  color: var(--color-brand);
}

/* Листать нечего — все карточки видны — стрелок нет (Iwent.initSimilarSlider). */
.similar-events-btn[hidden] {
  display: none;
}

.similar-events-btn:disabled {
  border-color: var(--color-border-soft);
  cursor: default;
}

.similar-events-btn:disabled .material-symbols-rounded {
  color: var(--color-ink-disabled);
}

.similar-events-btn .material-symbols-rounded {
  font-size: 24px;
  color: var(--color-ink);
}

.similar-events-list::-webkit-scrollbar {
  display: none;
}

.similar-event-card {
  width: 278px;
  min-height: 278px;
  flex-shrink: 0;
  border-radius: 24px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  background: #fff;
  cursor: pointer;
  transition: box-shadow var(--duration-base) var(--ease-out);
}

/* Курсор на ссылке внутри (тег, дата, площадка) — карточка не подсвечивается, как в ленте. */
.similar-event-card:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) {
  box-shadow: 0 0 32px 0 var(--color-overlay-8);
}

.similar-event-card .event-avatar {
  position: relative;
  display: inline-block;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  border: 3px solid;
  background: var(--color-photo-bg);
}

.similar-event-card[data-type="tech"] .event-avatar {
  border-color: var(--color-type-tech);
}

.similar-event-card[data-type="music"] .event-avatar {
  border-color: var(--color-type-music);
}

.similar-event-card[data-type="art"] .event-avatar {
  border-color: var(--color-type-art);
}

.similar-event-card[data-type="sport"] .event-avatar {
  border-color: var(--color-brand);
}

.similar-event-card[data-type="cinema"] .event-avatar {
  border-color: var(--color-type-cinema);
}

.similar-event-card[data-type="games"] .event-avatar {
  border-color: var(--color-type-games);
}
.similar-event-card[data-type="theatre"] .event-avatar {
  border-color: var(--color-type-theatre);
}
.similar-event-card[data-type="knowledge"] .event-avatar {
  border-color: var(--color-type-knowledge);
}
.similar-event-card[data-type="city"] .event-avatar {
  border-color: var(--color-type-city);
}
.similar-event-card[data-type="other"] .event-avatar {
  border-color: var(--color-type-other);
}

.similar-event-card .event-type-badge {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  bottom: -4px;
  right: -4px;
}

.similar-event-card[data-type="tech"] .event-type-badge {
  background: var(--color-type-tech);
}

.similar-event-card[data-type="music"] .event-type-badge {
  background: var(--color-type-music);
}

.similar-event-card[data-type="art"] .event-type-badge {
  background: var(--color-type-art);
}

.similar-event-card[data-type="sport"] .event-type-badge {
  background: var(--color-brand);
}

.similar-event-card[data-type="cinema"] .event-type-badge {
  background: var(--color-type-cinema);
}

.similar-event-card[data-type="games"] .event-type-badge {
  background: var(--color-type-games);
}
.similar-event-card[data-type="theatre"] .event-type-badge {
  background: var(--color-type-theatre);
}
.similar-event-card[data-type="knowledge"] .event-type-badge {
  background: var(--color-type-knowledge);
}
.similar-event-card[data-type="city"] .event-type-badge {
  background: var(--color-type-city);
}
.similar-event-card[data-type="other"] .event-type-badge {
  background: var(--color-type-other);
}

.similar-event-card .event-type-badge .material-symbols-rounded {
  color: #fff;
  font-size: 18px;
}

.similar-event-card .event-title {
  font-family: 'Unbounded', sans-serif;
  font-size: 16px;
  font-weight: 700;
  line-height: 24px;
  color: var(--color-ink);
  margin-top: 12px;
  margin-bottom: 4px;
  transition: color var(--duration-base) var(--ease-out);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-word;
}

.similar-event-card:hover:not(:has(:where(a:not(.event-title), button, .event-date, .event-location, .event-datetime, .event-tag, .user-avatar-wrap, .calendar-day-events):hover)) .event-title {
  color: var(--color-brand);
}

/* Карточка сервиса (ServiceCard, «Где посмотреть»): карточка «Похожих» как есть (белая,
   наведение — её тень), ниже ростом: только знак и название. Вся — ссылка. Сверху знак 48
   и справа на его линии значок внешней ссылки; название через 16. Опция filled — вид
   event-card-filled (подложка, светлое название и наведение — правила events.css,
   те же токены); здесь — только светлые значок и знак-SVG на подложке. */
.similar-event-card.service-card { min-height: 0; gap: var(--space-4); color: inherit; text-decoration: none; }
.service-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.similar-event-card.service-card .event-title { margin-top: 0; }
/* Фокус с клавиатуры — рамка вокруг всей карточки, как у ссылок ДС. */
.similar-event-card.service-card.event-card-filled { border: none; }
/* Подложка — фирменный цвет сервиса (токены знаков ProviderMark); знак — на светлой
   подложке, его глиф в том же цвете. Жёлтые сервисы — тёмные текст и значок. */
.similar-event-card.service-card.event-card-filled { position: relative; background: var(--service-brand); }
.similar-event-card.service-card[data-provider="kinopoisk"] { --service-brand: var(--color-kinopoisk); }
.similar-event-card.service-card[data-provider="steam"] { --service-brand: var(--color-steam); }
.similar-event-card.service-card[data-provider="gog"] { --service-brand: var(--color-gog); }
.similar-event-card.service-card[data-provider="okko"] { --service-brand: var(--color-okko); }
.similar-event-card.service-card[data-provider="ivi"] { --service-brand: var(--color-ivi); }
.similar-event-card.service-card[data-provider="wink"] { --service-brand: var(--color-wink); }
.similar-event-card.service-card[data-provider="start"] { --service-brand: var(--color-start); }
.similar-event-card.service-card[data-provider="premier"] { --service-brand: var(--color-premier); }
.similar-event-card.service-card[data-provider="kion"] { --service-brand: var(--color-kion); }
.similar-event-card.service-card[data-provider="yandexmusic"] { --service-brand: var(--color-yandexmusic); }
.similar-event-card.service-card[data-provider="vkmusic"], .similar-event-card.service-card[data-provider="vkplay"] { --service-brand: var(--color-vk); }
.similar-event-card.service-card[data-provider="zvuk"] { --service-brand: var(--color-zvuk); }
.similar-event-card.service-card[data-provider="mtsmusic"] { --service-brand: var(--color-mtsmusic); }
.similar-event-card.service-card[data-provider="litres"] { --service-brand: var(--color-litres); }
.similar-event-card.service-card[data-provider="yandexbooks"] { --service-brand: var(--color-yandexbooks); }
.similar-event-card.service-card.event-card-filled .provider-mark--plate { background: var(--color-surface); color: var(--service-brand); }
.similar-event-card.service-card.event-card-filled[data-provider="premier"] .provider-mark--plate, .similar-event-card.service-card.event-card-filled[data-provider="yandexmusic"] .provider-mark--plate { color: var(--color-ink); }
.similar-event-card.service-card.event-card-filled[data-provider="premier"] .event-title, .similar-event-card.service-card.event-card-filled[data-provider="yandexmusic"] .event-title,
.similar-event-card.service-card.event-card-filled[data-provider="premier"] .service-card-head > .material-symbols-rounded, .similar-event-card.service-card.event-card-filled[data-provider="yandexmusic"] .service-card-head > .material-symbols-rounded { color: var(--color-ink); }
/* Значок внешней ссылки — в правом верхнем углу карточки, по её полю. */
.similar-event-card.service-card .service-card-head > .material-symbols-rounded { position: absolute; top: var(--space-6); right: var(--space-6); }
.similar-event-card.service-card.event-card-filled .service-card-head > .material-symbols-rounded { color: var(--color-surface); }
.similar-event-card.service-card:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }

.similar-event-card .event-tags {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  overflow: hidden;
}

.similar-event-card .event-place {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  align-items: flex-start;
  white-space: nowrap;
  margin-top: 0 !important;
}

.similar-event-card .event-date,
.similar-event-card .event-location {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: var(--color-ink);
  padding: 6px 12px;
  border-radius: 100px;
  background: transparent;
  border: 1px solid var(--color-border);
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 1;
  min-width: 0;
  white-space: nowrap;
}

.similar-event-card .event-date {
  flex-shrink: 0;
}

.similar-event-card .event-location {
  flex-shrink: 1;
  flex-basis: auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
}

/* Диапазон дат — две ссылки в одной плашке (DatePlace), как в обычной карточке. */
.similar-event-card .event-date.is-split {
  padding: 0;
  display: inline-flex;
}

/* Не влезает — сокращается первая часть (дата), «ещё N дат» остаётся целиком. */
.similar-event-card .event-date.is-split > :first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.similar-event-card .event-date.is-split > :not(:first-child) { flex-shrink: 0; white-space: nowrap; }

.similar-event-card .event-date-part {
  display: inline-block;
  padding: 6px 4px;
  border-radius: 100px;
}

.similar-event-card .event-date.is-split > :first-child { padding-left: 12px; }
.similar-event-card .event-date.is-split > :last-child { padding-right: 12px; }
.similar-event-card .event-date-sep { display: inline-block; padding: 6px 0; }

.similar-event-card .event-tag {
  font-family: 'Onest', sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  color: var(--color-ink-secondary);
}

.similar-event-card .event-tag-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--color-ink);
}

.similar-event-card .event-place {
  display: flex;
  gap: 4px;
  margin-top: auto;
  white-space: nowrap;
  flex-shrink: 0;
  flex-wrap: wrap;
}

.similar-event-card .event-place:has(.event-date:empty):has(.event-location:empty) {
  display: none;
}

.similar-event-card .event-date,
.similar-event-card .event-location {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: var(--color-ink);
  padding: 6px 12px;
  border-radius: 100px;
  background: transparent;
  border: 1px solid var(--color-border);
  display: inline-block;
}

.similar-event-card .event-date:empty,
.similar-event-card .event-location:empty {
  display: none;
}

.event-skeleton {
  background: var(--color-skeleton);
}

#event-detail-left {
  width: var(--event-column);
  min-height: 600px;
  border-radius: 32px;
  flex-shrink: 0;
  overflow: visible;
  position: relative;
}

#event-detail-right {
  flex: 1;
  min-width: 0;
  overflow: visible;
  position: relative;
  background: var(--color-bg);
}

/* Без описания колонка начинается с жанра или тегов — их верхний отступ
   сдвинул бы колонку ниже героя. */
#event-detail-right > :first-child {
  margin-top: 0;
}

.event-skeleton {
  background: var(--color-skeleton);
}

#event-detail-left .event-skeleton-left {
  width: 100%;
  height: 600px;
  border-radius: 32px;
  background: var(--color-skeleton);
}

.event-skeleton-right {
  flex: 1;
  height: 600px;
  border-radius: 32px;
  background: var(--color-skeleton);
}

.skeleton-line {
  background: var(--color-skeleton);
  border-radius: 4px;
}

.event-skeleton-right-content {
  width: 100%;
}

/* Ошибка и «не найдено» на странице события — во всю ширину раскладки.
   Раньше это правило жило в инлайновом <style> event.html и до каталога
   не доходило: там ошибка сжималась до ширины текста. */
#event-error-container {
  display: none;
  grid-column: 1 / 3;
  width: 100%;
}

#event-error-container.visible {
  display: block;
}

/* ---------- Мобильная версия (≤ 767px) ----------
   Колонки встают одна под другой. Герой — во всю ширину экрана сразу под
   шапкой: фото 210px, на нём цветная панель; аватарка 128px заходит на
   панель на 64px (на десктопе на 92px). Ниже правая колонка с полями
   24px сверху и 20px по бокам. Фото и похожие события листаются пальцем,
   стрелок у слайдера нет. Размеры — из макета: фото 160×120, карточки
   похожих 290×290 через 20px. */
@media (max-width: 767px) {
  .content-inner.event-detail-layout {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0;
  }

  /* Колонки без полей — у строки «Назад» свои, как в макете: 20px вокруг. */
  .event-detail-layout > .back-row {
    padding: var(--space-mobile);
  }

  #event-detail-left {
    width: 100%;
    min-height: 0;
  }

  .event-hero {
    padding: var(--space-mobile);
    min-height: 0;
  }

  /* Без фото тёмный блок над героем нужен только аватарке (она на 84px выше панели): 210 -> 84 + 12. */
  #event-detail-left.no-photo:not(.is-light) {
    --event-hero-offset: calc(84px + var(--space-3));
  }

  .event-avatar-wrap {
    margin-top: -84px; /* аватарка на 64px выше панели + поле панели 20px */
  }

  #event-detail-right {
    width: 100%;
    padding: var(--space-6) var(--space-mobile) var(--space-mobile);
  }

  /* Пары «подпись — значение» на телефоне — столбиком: дата и место с полным
     адресом в две колонки по ~165px переносились бы по слову. */
  .event-extra-info {
    flex-direction: column;
    gap: var(--space-4);
  }
  .event-extra-block {
    flex-basis: auto;
  }

  /* Плитки медиаблока на телефоне — как карточки новостей: одна колонка от края до края. */
  .event-image {
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-lg);
  }

  .similar-events-nav {
    display: none;
  }

  /* Стрелок на телефоне нет вовсе — высоту под них не держим. */
  .similar-events-header {
    min-height: 0;
  }

  .similar-events-list {
    gap: var(--space-mobile);
    margin-inline: calc(-1 * var(--space-mobile));
    padding-inline: var(--space-mobile);
    scroll-padding-inline: var(--space-mobile);
    scroll-snap-type: x mandatory;
  }

  .similar-event-card {
    width: 290px;
    min-height: 290px;
    scroll-snap-align: start;
  }

  /* Заглушки: блок героя во всю ширину, справа строки не шире экрана. */
  #event-detail-left .event-skeleton-left {
    width: 100%;
    height: 650px;
  }

  .event-skeleton-right-content {
    overflow: hidden;
  }

  /* Ошибка и «не найдено» — во всю ширину, как остальные состояния. */
  #event-error-container {
    padding: var(--space-mobile) 0;
  }
}

/* Плашка «Предпросмотр» (Callout floating): внизу по центру, поверх страницы. */
.event-preview-notice {
  position: fixed;
  left: 50%;
  bottom: var(--space-6);
  z-index: 50;
  width: min(760px, calc(100vw - var(--space-4) * 2));
  transform: translateX(-50%);
}

/* ---------- Светлый герой (heroMarkup tone 'light': профиль, PersonHero) ----------
   Белая подложка, как у белых карточек, вместо цветной: текст и плашки тёмные.
   Фото над героем — то же, что у события: слой .event-hero-photo колонки (Photo,
   заглушка и проявление — data-load). Колонка прозрачна, чтобы под белой
   подложкой не торчали тёмные углы; без фото область над героем — тёмная, как
   у события без фото (полоса высотой с слой ::before). Аватарка стоит внутри
   поля героя. Бейдж — цвета бренда с белым числом. */
#event-detail-left.is-light {
  background: linear-gradient(var(--color-hero-bg), var(--color-hero-bg)) top / 100% calc(var(--event-hero-offset) + var(--radius-xl)) no-repeat;
}
/* Светлый герой без фото: блока над ним нет — начинается с белой плашки. */
#event-detail-left.is-light.no-photo {
  --event-hero-offset: 0px;
  background: none;
}
.event-hero[data-tone="light"] .event-hero-bg {
  background: var(--color-surface);
}
.event-hero[data-tone="light"] .event-avatar-wrap {
  margin-top: 0;
}
.event-hero[data-tone="light"] .event-avatar-large {
  border-color: var(--event-type-color, var(--color-brand));
  background: var(--color-surface);
}
/* Как в белой карточке: подложка под фото и круг с буквой — цвета плашки (белые), обводка и буква —
   цвета категории (у человека — бренд). В тёмном герое наоборот: подложка цвета панели, обводка белая. */
.event-hero[data-tone="light"] .event-avatar-letter {
  background: var(--color-surface);
  color: var(--event-type-color, var(--color-muted));
}
/* Кнопка героя (белая) на белом герое не видна — тонкая серая рамка, как у обычной кнопки;
   нажатая («Вы подписаны») — тёмная, без рамки. */
.event-hero[data-tone="light"] .btn-hero:not(.is-pressed),
.event-hero[data-tone="light"] .btn-hero:not(.is-pressed):hover:not(:disabled) { border-color: var(--color-border); }
.event-hero[data-tone="light"] .event-title {
  color: var(--color-ink);
}
/* Теги светлого героя — как в карточке события (.event-card-standard): текст --color-ink-secondary, точка — сплошная. */
.event-hero[data-tone="light"] .event-tag {
  color: var(--color-ink-secondary);
}
.event-hero[data-tone="light"] a.event-tag:is(:hover, :focus-visible) { color: var(--color-ink); }
.event-hero[data-tone="light"] .event-tag-dot {
  background: var(--color-ink);
}
.event-hero[data-tone="light"] :is(.event-datetime, .event-location) {
  color: var(--color-ink);
  border-color: var(--color-border);
}
.event-hero[data-tone="light"] .event-datetime-location :is(a.event-datetime, a.event-location, .event-datetime-part) {
  color: var(--color-ink);
}
/* Наведение — как у плашек-ссылок белой карточки ленты (components.css): подложка --color-hover, текст
   бренда; не --color-bg — на сером (карточка с рамкой в ленте активности) он сливался с фоном. */
.event-hero[data-tone="light"] .event-datetime-location :is(a.event-datetime, a.event-location, .event-datetime-part):is(:hover, :focus-visible) {
  background: var(--color-hover);
  color: var(--color-brand);
}
.event-hero[data-tone="light"] .event-divider {
  background: var(--color-border-soft);
}
/* Бейдж — цвета категории (у человека — бренд, --event-type-color от data-type="person"), значок белый. */
.event-hero[data-tone="light"] .event-type-icon-badge {
  background: var(--event-type-color, var(--color-brand));
}
.event-hero[data-tone="light"] .event-type-icon-badge :is(.material-symbols-rounded, .event-hero-level) {
  color: var(--color-surface);
}
.event-hero[data-tone="light"] .recommended-event-card {
  background: var(--color-bg);
}

/* Разделы человека на светлом герое — в серой плашке, как карточка рекомендации под ними. */
.event-hero[data-tone="light"] .event-hero-menu {
  background: var(--color-bg);
  border-radius: 24px;
  padding: 16px;
}

/* Рекомендация, залитая цветом категории (filled): белый текст и обводка аватарки, значок — цветом заливки. */
.recommended-event-card--filled { background: var(--event-type-color, var(--color-brand)) !important; }
.recommended-event-card--filled .recommended-title { color: var(--color-surface); }
/* Наведение на залитой — белый 64%, как у названий на залитых карточках, а не бренд. */
.event-hero .recommended-event-card--filled:hover .recommended-title, .recommended-event-card--filled:hover .recommended-title, .recommended-event-card--filled .recommended-title:is(:hover, :focus-visible) { color: var(--color-on-dark-64); }
.event-hero .recommended-event-card--filled:hover:has(:where(a:not(.recommended-title), button, .recommended-datetime, .recommended-location):hover) .recommended-title:not(:hover) { color: var(--color-surface); }
.recommended-event-card--filled .recommended-tags span { color: var(--color-on-dark-80); }
.recommended-event-card--filled .recommended-tag-dot { background-color: var(--color-surface) !important; }
.recommended-event-card--filled :is(.recommended-datetime, .recommended-location) { color: var(--color-surface); border-color: var(--color-on-dark-32); }
.recommended-event-card--filled .recommended-avatar { border-color: var(--color-surface); }
/* Буква без фото — на цвете карточки, белая (как в залитых карточках ленты), а не белым кругом. */
.event-hero .recommended-event-card--filled .event-avatar-letter, .recommended-event-card--filled .event-avatar-letter { background: var(--event-type-color, var(--color-brand)); color: var(--color-surface); }
.recommended-event-card--filled .recommended-type-badge { background: var(--color-surface) !important; }
.recommended-event-card--filled .recommended-type-badge .material-symbols-rounded { color: var(--event-type-color, var(--color-brand)); }

@media (max-width: 767px) {
  .event-hero[data-tone="light"] .event-avatar-wrap {
    margin-top: 0;
  }
}



body.page-calendar .content-inner {
  overflow: visible;
  max-width: 100%;
}

.calendar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
}

.calendar-header-left {
  /* Якорь для .calendar-month-picker: она position:absolute и без этого
     считает координаты от окна, а не от шапки. */
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
}

.calendar-title-btn-wrapper {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-width: 180px;
}

body.fonts-loaded .calendar-title-btn-wrapper {
  min-width: unset;
}

.calendar-title {
  font-family: 'Unbounded', sans-serif;
  font-size: 24px;
  font-weight: 700;
  line-height: 32px;
  color: var(--color-ink);
  margin: 0;
  visibility: hidden;
}

body.fonts-loaded .calendar-title {
  visibility: visible;
}

.skeleton-title {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  visibility: hidden;
  width: 180px;
  height: 14px;
  background: var(--color-skeleton);
  border-radius: 100px;
  pointer-events: none;
}

body:not(.fonts-loaded) .skeleton-title {
  visibility: visible;
}

body:not(.fonts-loaded) .calendar-title {
  visibility: hidden;
}

.calendar-title-btn {
  width: 44px;
  height: 44px;
  border-radius: 16px;
  background: transparent;
  border: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition-colors);
}

.calendar-title-btn:hover {
  background: var(--color-hover);
  border-color: transparent;
}

.calendar-title-btn:hover .material-symbols-rounded {
  color: var(--color-brand);
}

.calendar-title-btn .material-symbols-rounded {
  font-size: 24px;
  color: var(--color-ink);
}

.calendar-header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.calendar-month-picker {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 360px;
  background: #fff;
  border-radius: 24px;
  /* Снизу 12: месяцы — плашки с полем 8, текст остаётся в 24 от края. */
  padding: var(--space-6) var(--space-6) var(--space-3);
  box-shadow: var(--shadow-panel);
  z-index: 100;
}

.calendar-month-picker.active {
  display: block;
}

.calendar-month-picker-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.calendar-month-picker-btn {
  width: 44px;
  height: 44px;
  border-radius: 16px;
  background: transparent;
  border: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition-colors);
}

.calendar-month-picker-btn:hover {
  background: var(--color-hover);
  border-color: transparent;
}

.calendar-month-picker-btn:hover .material-symbols-rounded {
  color: var(--color-brand);
}

.calendar-month-picker-btn .material-symbols-rounded {
  font-size: 24px;
  color: var(--color-ink);
}

.calendar-month-picker-year {
  font-family: 'Montserrat', sans-serif;
  font-size: 24px;
  font-weight: 700;
  line-height: 32px;
  color: var(--color-ink);
}

.calendar-month-picker-divider {
  height: 1px;
  background: var(--color-border);
  margin-top: 20px;
}

/* Месяцы — плашки, как пункты Dropdown: поля 8/12, радиус 12, наведение и
   фокус — фон --color-hover и синий текст. Сетка выходит на 12 за поле
   панели — плашки стоят в 12 от её краёв, текст — на прежнем месте; шаг
   строк прежний, 44 (36 + 8). */
.calendar-month-picker-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-2) 0;
  margin: var(--space-3) calc(-1 * var(--space-3)) 0;
}

.calendar-month-picker-item {
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  color: var(--color-ink);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  text-align: left;
  transition: color var(--duration-base) var(--ease-out), background-color var(--duration-base) var(--ease-out);
}

.calendar-month-picker-item:hover,
.calendar-month-picker-item:focus-visible {
  background: var(--color-hover);
  outline: none;
}

.calendar-month-picker-item:not(.active):hover,
.calendar-month-picker-item:focus-visible {
  color: var(--color-brand);
}

.calendar-month-picker-item.active {
  cursor: default;
  pointer-events: none;
}

.calendar-month-picker-item.active span:first-child {
  opacity: 0.24;
}

.calendar-month-picker-item.current .calendar-month-picker-dot {
  background: var(--color-brand);
}

.calendar-month-picker-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: transparent;
}

.calendar-today-btn {
  padding: 12px 16px;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: 16px;
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  line-height: 20px;
  color: var(--color-ink);
  cursor: pointer;
  transition: var(--transition-colors), opacity var(--duration-base) var(--ease-out);
}

.calendar-today-btn:hover:not(.disabled) {
  background: var(--color-hover);
  color: var(--color-brand);
  border-color: transparent;
}

.calendar-today-btn.disabled {
  border-color: var(--color-border-soft);
  cursor: default;
}

.calendar-today-btn.disabled span {
  color: var(--color-ink);
  opacity: 0.24;
}

.calendar-today-btn.disabled:hover {
  background: transparent;
  border-color: var(--color-border-soft);
}

.calendar-nav-btn {
  width: 44px;
  height: 44px;
  border-radius: 16px;
  background: transparent;
  border: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition-colors);
}

.calendar-nav-btn:hover {
  background: var(--color-hover);
  border-color: transparent;
}

.calendar-nav-btn:hover .material-symbols-rounded {
  color: var(--color-brand);
}

.calendar-nav-btn .material-symbols-rounded {
  font-size: 24px;
  color: var(--color-ink);
}

#calendar-filters-container {
  margin-top: 24px;
}

/* Два ряда (ui.TypePick rows, как в ленте — events.css): категории, ниже остальное; между рядами 16. */
@media (min-width: 768px) {
  #calendar-filters-container:has(> .type-pick--rows) { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-2); }
}

.calendar-divider {
  height: 1px;
  background: var(--color-border);
  margin-top: 24px;
}

.calendar-weekdays {
  display: flex;
  gap: 8px;
  margin-top: 24px;
  width: 100%;
}

.calendar-weekday {
  flex: 1;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 400;
  line-height: 16px;
  color: var(--color-ink-secondary);
  text-transform: uppercase;
}

.calendar-weekday.weekend {
  color: var(--color-danger);
}

.calendar-grid {
  margin-top: 8px;
  padding-bottom: 24px;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
}

.calendar-day {
  min-height: 245px;
  min-width: 0;
  border-radius: 24px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  transition: box-shadow var(--duration-base) var(--ease-out);
}

.calendar-day.has-events {
  cursor: pointer;
}

.calendar-day.has-events:hover {
  box-shadow: 0 0 32px 0 var(--color-overlay-8);
}

.calendar-day.has-events:hover:has(.calendar-day-ad:hover),
.calendar-day.has-events:hover:has(.calendar-day-ad-filled:hover) {
  box-shadow: none;
}

.calendar-day.has-events:hover .calendar-day-num,
.calendar-day.has-events.past:hover .calendar-day-num {
  color: var(--color-brand);
}

.calendar-day.has-events:hover:has(.calendar-day-ad:hover) .calendar-day-num,
.calendar-day.has-events:hover:has(.calendar-day-ad-filled:hover) .calendar-day-num {
  color: var(--color-ink);
}

.calendar-day.has-events.past:hover:has(.calendar-day-ad:hover) .calendar-day-num,
.calendar-day.has-events.past:hover:has(.calendar-day-ad-filled:hover) .calendar-day-num {
  color: var(--color-muted);
}

.calendar-day.past {
  background: transparent;
  border: 1px solid var(--color-border-soft);
}

.calendar-day.today {
  background: #fff;
  border: 2px solid var(--color-brand);
}

.calendar-day.future {
  background: #fff;
  border: none;
}

.calendar-day.past {
  background: transparent;
  border: 1px solid var(--color-border-soft);
}

.calendar-day.future-month {
  background: transparent;
  border: 1px solid var(--color-border);
}

/* Прозрачный день — на фоне страницы: круг буквы в аватарке (AvatarLetter) того же цвета,
   а не белый диск в цветном кольце. */
.calendar-day.past,
.calendar-day.future-month { --avatar-bg: var(--color-bg); }

.calendar-day-num {
  font-family: 'Montserrat', sans-serif;
  font-size: 20px;
  font-weight: 700;
  line-height: 26px;
  color: var(--color-ink);
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  transition: color var(--duration-base) var(--ease-out);
}

.calendar-day.past .calendar-day-num {
  color: var(--color-muted);
}

.calendar-day-num-wrap {
  max-width: 100%;
  display: flex;
  align-items: center;
  gap: 4px;
}

.calendar-today-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-brand);
  display: inline-block;
  flex-shrink: 0;
}

/* Стопка аватарок (CalendarAvatarStack) — одна у календаря и подборок (CollectionCard):
   место аватарки — круг на --stack-ring шире неё, следующее место заходит на 16 (сами
   аватарки — на 10): шаг 38 у 48 (Figma 661:74), 22 у 32 (образец пользователя 15.10.2026).
   Зазор --stack-ring = --avatar-cut (3) — прозрачный вырез-«полумесяц» маской в
   предыдущей аватарке: в нём фон дня или карточки (белый, серый, цветной), своих колец и
   подложек нет. Обводка цвета категории остаётся. --stack-size — диаметр аватарки с обводкой. */
.calendar-day-events {
  --stack-size: 32px;
  --stack-ring: var(--avatar-cut);
  --stack-overlap: var(--space-4);
  margin-top: 12px;
  display: flex;
  align-items: center;
}

.event-avatar-wrapper {
  position: relative;
  box-sizing: border-box;
  width: calc(var(--stack-size) + 2 * var(--stack-ring));
  height: calc(var(--stack-size) + 2 * var(--stack-ring));
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* Вырез — у каждой аватарки, на которую заходит следующее место: следующая аватарка или
   невидимый круг «+N» (у последней перед «+N» вырез тоже есть; нет только у последней в
   стопке без счётчика). Центр выреза — центр следующего места: 1,5 диаметра + 2 зазора −
   наложение от левого края. */
.event-avatar-wrapper:not(:last-child) .event-avatar {
  --cut: radial-gradient(circle at calc(1.5 * var(--stack-size) + 2 * var(--stack-ring) - var(--stack-overlap)) 50%,
    transparent calc(var(--stack-size) / 2 + var(--stack-ring)),
    #000 calc(var(--stack-size) / 2 + var(--stack-ring) + 0.5px));
  -webkit-mask: var(--cut);
  mask: var(--cut);
}

/* Следующая аватарка и круг «+N» заходят на предыдущую на --stack-overlap. */
.event-avatar-wrapper:not(:first-child),
.event-counter {
  margin-left: calc(-1 * var(--stack-overlap));
}

.event-avatar-wrapper .event-avatar {
  position: relative;
  overflow: hidden;
  width: var(--stack-size);
  height: var(--stack-size);
  border-radius: 50%;
  border: 3px solid;
  background: var(--color-photo-bg);
}

.event-avatar-wrapper[data-type="tech"] .event-avatar { border-color: var(--color-type-tech); }
.event-avatar-wrapper[data-type="music"] .event-avatar { border-color: var(--color-type-music); }
.event-avatar-wrapper[data-type="art"] .event-avatar { border-color: var(--color-type-art); }
.event-avatar-wrapper[data-type="sport"] .event-avatar { border-color: var(--color-brand); }
.event-avatar-wrapper[data-type="cinema"] .event-avatar { border-color: var(--color-type-cinema); }
.event-avatar-wrapper[data-type="games"] .event-avatar { border-color: var(--color-type-games); }
.event-avatar-wrapper[data-type="theatre"] .event-avatar { border-color: var(--color-type-theatre); }
.event-avatar-wrapper[data-type="knowledge"] .event-avatar { border-color: var(--color-type-knowledge); }
.event-avatar-wrapper[data-type="city"] .event-avatar { border-color: var(--color-type-city); }
.event-avatar-wrapper[data-type="other"] .event-avatar { border-color: var(--color-type-other); }

/* «+N» — последний в стопке: невидимый круг (без заливки и обводки) того же места, что
   аватарка, на том же шаге; текст по центру круга. Круг виден только прозрачным вырезом
   3px в последней аватарке (правило выреза выше). Образец пользователя 15.10.2026. */
.event-counter {
  position: relative;
  box-sizing: border-box;
  width: calc(var(--stack-size) + 2 * var(--stack-ring));
  height: calc(var(--stack-size) + 2 * var(--stack-ring));
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  white-space: nowrap;
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: var(--color-ink);
}

/* Крупная стопка вне ячейки дня (карточка подборки, CollectionCard; макет Figma 661:74):
   аватарка 48; зазор 3, наложение 16 и круг «+N» — из общих правил выше. */
.calendar-day-events--large { --stack-size: var(--space-12); margin-top: 0; }

/* Загрузка — не нажимается: без руки и наведения (docs/design-system.md, «Курсор и наведение»). */
.calendar-day-skeleton {
  min-height: 245px;
  border-radius: 24px;
  background: var(--color-skeleton);
}

/* Ошибка в сетке календаря: занимает всю строку. Оформление — общее,
   в components.css (состояния пусто / ошибка / не найдено). */
.error-state {
  grid-column: 1 / 8;
}

.calendar-day-ad-divider {
  height: 1px;
  background: var(--color-border);
  width: 100%;
  margin-top: 12px;
}

.calendar-day-top {
  padding: 16px 16px 12px 16px;
  min-width: 0;
}

.calendar-day-ad-filled {
  border-radius: 24px;
  padding: 12px 16px 16px 16px;
  flex: 1;
  min-width: 0;
}

.calendar-day-ad-filled--tech { background: var(--color-type-tech); color: var(--color-type-tech); }
.calendar-day-ad-filled--music { background: var(--color-type-music); color: var(--color-type-music); }
.calendar-day-ad-filled--art { background: var(--color-type-art); color: var(--color-type-art); }
.calendar-day-ad-filled--sport { background: var(--color-brand); color: var(--color-brand); }
.calendar-day-ad-filled--cinema { background: var(--color-type-cinema); color: var(--color-type-cinema); }
.calendar-day-ad-filled--games { background: var(--color-type-games); color: var(--color-type-games); }
.calendar-day-ad-filled--theatre { background: var(--color-type-theatre); color: var(--color-type-theatre); }
.calendar-day-ad-filled--knowledge { background: var(--color-type-knowledge); color: var(--color-type-knowledge); }
.calendar-day-ad-filled--city { background: var(--color-type-city); color: var(--color-type-city); }
.calendar-day-ad-filled--other { background: var(--color-type-other); color: var(--color-type-other); }

.calendar-day-ad {
  padding-top: 12px;
  cursor: pointer;
}

.calendar-day-ad:hover .calendar-day-ad-title {
  color: var(--color-brand);
}

.calendar-day-ad-filled {
  border-radius: 24px;
  padding: 12px 16px 16px 16px;
  flex: 1;
  cursor: pointer;
}

.calendar-day-ad-title--white {
  color: #fff !important;
}

.calendar-day-ad-tag--white {
  color: var(--color-on-dark-80) !important;
}

.calendar-day-ad-tag-separator--white {
  background: #fff !important;
}

.calendar-day-ad-filled .calendar-day-ad-icon {
  background: #fff !important;
}

.calendar-day-ad-filled .calendar-day-ad-icon .material-symbols-rounded {
  color: inherit !important;
}

.calendar-day-ad-filled:hover .calendar-day-ad-title--white {
  color: rgba(255, 255, 255, 0.6) !important;
}

.calendar-day-ad-avatar-wrapper {
  position: relative;
  width: 64px;
  height: 64px;
  flex-shrink: 0;
}

.calendar-day-ad-avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 3px solid;
  background: var(--color-photo-bg);
}

.calendar-day-ad-avatar--white {
  border-color: #fff !important;
}

.calendar-day-ad-avatar-wrapper[data-type="tech"] .calendar-day-ad-avatar { border-color: var(--color-type-tech); }
.calendar-day-ad-avatar-wrapper[data-type="music"] .calendar-day-ad-avatar { border-color: var(--color-type-music); }
.calendar-day-ad-avatar-wrapper[data-type="art"] .calendar-day-ad-avatar { border-color: var(--color-type-art); }
.calendar-day-ad-avatar-wrapper[data-type="sport"] .calendar-day-ad-avatar { border-color: var(--color-brand); }
.calendar-day-ad-avatar-wrapper[data-type="cinema"] .calendar-day-ad-avatar { border-color: var(--color-type-cinema); }
.calendar-day-ad-avatar-wrapper[data-type="games"] .calendar-day-ad-avatar { border-color: var(--color-type-games); }
.calendar-day-ad-avatar-wrapper[data-type="theatre"] .calendar-day-ad-avatar { border-color: var(--color-type-theatre); }
.calendar-day-ad-avatar-wrapper[data-type="knowledge"] .calendar-day-ad-avatar { border-color: var(--color-type-knowledge); }
.calendar-day-ad-avatar-wrapper[data-type="city"] .calendar-day-ad-avatar { border-color: var(--color-type-city); }
.calendar-day-ad-avatar-wrapper[data-type="other"] .calendar-day-ad-avatar { border-color: var(--color-type-other); }

.calendar-day-ad-icon {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.calendar-day-ad-icon .material-symbols-rounded {
  font-size: 18px;
  color: #fff;
}

.calendar-day-ad-avatar-wrapper[data-type="tech"] .calendar-day-ad-icon { background: var(--color-type-tech); }
.calendar-day-ad-avatar-wrapper[data-type="music"] .calendar-day-ad-icon { background: var(--color-type-music); }
.calendar-day-ad-avatar-wrapper[data-type="art"] .calendar-day-ad-icon { background: var(--color-type-art); }
.calendar-day-ad-avatar-wrapper[data-type="sport"] .calendar-day-ad-icon { background: var(--color-brand); }
.calendar-day-ad-avatar-wrapper[data-type="cinema"] .calendar-day-ad-icon { background: var(--color-type-cinema); }
.calendar-day-ad-avatar-wrapper[data-type="games"] .calendar-day-ad-icon { background: var(--color-type-games); }
.calendar-day-ad-avatar-wrapper[data-type="theatre"] .calendar-day-ad-icon { background: var(--color-type-theatre); }
.calendar-day-ad-avatar-wrapper[data-type="knowledge"] .calendar-day-ad-icon { background: var(--color-type-knowledge); }
.calendar-day-ad-avatar-wrapper[data-type="city"] .calendar-day-ad-icon { background: var(--color-type-city); }
.calendar-day-ad-avatar-wrapper[data-type="other"] .calendar-day-ad-icon { background: var(--color-type-other); }

.calendar-day-ad-title {
  font-family: 'Unbounded', sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 16px;
  color: var(--color-ink);
  margin-top: 12px;
  transition: color var(--duration-base) var(--ease-out);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

.calendar-day-ad-tags {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
  margin-top: 4px;
  overflow: hidden;
  white-space: nowrap;
}

.calendar-day-ad-tag {
  font-family: 'Onest', sans-serif;
  font-size: 12px;
  line-height: 16px;
  color: var(--color-ink-secondary);
  flex-shrink: 0;
}

.calendar-day-ad-tag-separator {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--color-ink);
  flex-shrink: 0;
}

/* ---------- Мобильная версия (≤ 767px) ----------
   По макету календаря 375px.
   Шапка — два ряда: «Месяц Год» и кнопка выбора месяца; под ними
   «‹ · Сегодня · ›», где «Сегодня» занимает всё между стрелками.
   Сетка — семь колонок по ~44px через 4px, ячейка 135px. Вместо стопки
   аватарок в ячейке цветные чёрточки по типам событий (24×3, через 2px),
   под ними «+N» без кружка. Выделенное событие — аватарка 32px у нижнего
   края; у залитой карточки — на цветном квадрате. Выбор месяца открывается
   шторкой снизу. Разметка та же, что на десктопе: всё делает CSS. */
@media (max-width: 767px) {
  /* Шапка */
  .calendar-header {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) 44px;
    grid-template-areas:
      "title title pick"
      "prev  today next";
    column-gap: var(--space-2);
    row-gap: var(--space-4);
    align-items: center;
  }

  .calendar-header-left,
  .calendar-header-right {
    display: contents;
  }

  .calendar-title-btn-wrapper {
    grid-area: title;
    min-width: 0;
  }

  .calendar-title-btn {
    grid-area: pick;
  }

  /* 44px, как стрелки рядом: рамка входит в высоту. */
  .calendar-today-btn {
    grid-area: today;
    width: 100%;
    height: 44px;
    padding-top: 0;
    padding-bottom: 0;
  }

  .calendar-header-right .calendar-nav-btn:nth-child(2) {
    grid-area: prev;
  }

  .calendar-header-right .calendar-nav-btn:nth-child(3) {
    grid-area: next;
  }

  /* Выбор месяца — шторка снизу поверх затемнения */
  .calendar-month-picker {
    position: fixed;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    /* Снизу 16: последний ряд месяцев — плашки с полем 8, текст в 24 от края. */
    padding: var(--space-6) var(--space-mobile) calc(var(--space-4) + env(safe-area-inset-bottom));
    box-shadow: 0 0 0 100vmax var(--color-overlay-24);
    z-index: 1000;
  }

  /* Прозрачная подложка на весь экран: затемнение — это тень, сквозь неё
     страница ловила бы наведение и клики. Клик по подложке приходит с
     target = шторка — calendar.html закрывает её по координатам. */
  .calendar-month-picker::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
  }

  .calendar-month-picker::before {
    content: '';
    position: absolute;
    top: var(--space-2);
    left: 50%;
    width: 40px;
    height: 4px;
    margin-left: -20px;
    border-radius: var(--radius-pill);
    background: var(--color-border);
  }

  #calendar-filters-container {
    margin-top: var(--space-mobile);
  }

  .calendar-divider {
    margin-top: var(--space-mobile);
  }

  /* Дни недели: короткие названия из data-short */
  .calendar-weekdays {
    gap: 4px;
    margin-top: var(--space-mobile);
  }

  .calendar-weekday {
    font-size: 0;
  }

  .calendar-weekday::after {
    content: attr(data-short);
    font-size: var(--text-xs);
  }

  /* Сетка и ячейка */
  .calendar-grid {
    gap: 4px;
    margin-top: 4px;
    padding-bottom: var(--space-mobile);
  }

  .calendar-day,
  .calendar-day-skeleton {
    min-height: 135px;
    border-radius: var(--radius-sm);
  }

  .calendar-day {
    padding: var(--space-4) 0 6px;
    align-items: center;
  }

  /* Ячейка без боковых полей — свои, чтобы многоточие не упиралось в рамку */
  .calendar-day-num-wrap {
    padding: 0 var(--space-1);
  }

  .calendar-day-num {
    font-size: var(--text-xs);
    line-height: 16px;
  }

  /* Месяц у первого числа — три буквы из data-short, как дни недели */
  /* line-height: 0 у span с нулевым кеглем — иначе его строка в 16px
     центрируется по базовой линии, ячейка вырастает до 20px и чёрточки
     съезжают вниз. Высоту строки задаёт ::after. */
  .calendar-day-month {
    font-size: 0;
    line-height: 0;
  }

  .calendar-day-month::after {
    content: ' ' attr(data-short);
    font-size: var(--text-xs);
    line-height: 16px;
  }

  .calendar-today-dot {
    width: 4px;
    height: 4px;
  }

  /* Аватарки событий → цветные чёрточки по типу */
  .calendar-day-events {
    margin-top: var(--space-3);
    flex-direction: column;
    gap: 2px;
  }

  /* Крупная стопка вне ячейки дня остаётся рядом, а не чёрточками. */
  .calendar-day-events--large { margin-top: 0; flex-direction: row; gap: 0; }

  .calendar-day .event-avatar-wrapper,
  .calendar-day .event-avatar-wrapper:not(:first-child) {
    width: 24px;
    height: 3px;
    margin-left: 0;
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--color-type-art);
  }

  .calendar-day .event-avatar-wrapper[data-type="tech"] { background: var(--color-type-tech); }
  .calendar-day .event-avatar-wrapper[data-type="music"] { background: var(--color-type-music); }
  .calendar-day .event-avatar-wrapper[data-type="sport"] { background: var(--color-type-sport); }
  .calendar-day .event-avatar-wrapper[data-type="cinema"] { background: var(--color-type-cinema); }
  .calendar-day .event-avatar-wrapper[data-type="games"] { background: var(--color-type-games); }
  .calendar-day .event-avatar-wrapper[data-type="theatre"] { background: var(--color-type-theatre); }
  .calendar-day .event-avatar-wrapper[data-type="knowledge"] { background: var(--color-type-knowledge); }
  .calendar-day .event-avatar-wrapper[data-type="city"] { background: var(--color-type-city); }
  .calendar-day .event-avatar-wrapper[data-type="other"] { background: var(--color-type-other); }

  .calendar-day .event-avatar-wrapper .event-avatar {
    display: none;
  }

  /* «+N» — просто текст под чёрточками */
  .calendar-day .event-counter {
    min-width: 0;
    width: auto;
    height: auto;
    padding: 0;
    background: none;
    margin: var(--space-3) 0 0;
    font-size: var(--text-xs);
    line-height: 16px;
  }

  /* Выделенное событие — только аватарка 32px внизу ячейки */
  .calendar-day-ad-divider,
  .calendar-day-ad-title,
  .calendar-day-ad-tags,
  .calendar-day-ad-icon {
    display: none;
  }

  .calendar-day-ad {
    margin-top: auto;
    padding-top: var(--space-3);
  }

  .calendar-day-ad-avatar-wrapper,
  .calendar-day-ad-avatar {
    width: 32px;
    height: 32px;
  }

  /* Залитая карточка: цветной квадрат во всю ширину ячейки, аватарка в нём */
  .calendar-day-top {
    padding: var(--space-4) 0 0;
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .calendar-day-ad-filled {
    flex: 0 0 auto;
    align-self: stretch;
    margin-top: auto;
    padding: 6px;
    border-radius: var(--radius-sm);
    display: flex;
    justify-content: center;
  }
}




/*
 * Страница понятия (concept.html), «Все похожие» (similar.html, #similar-root), «Мои события» (my.html, #my-root),
 * выдача поиска (search.html, #search-root), люди события и темы (people.html, #people-root) и темы события
 * (event-topics.html, #topics-root; там же темы человека), достижения и стикеры человека (profile-list.html,
 * #profile-list-root) — раскладка у них одна. Только раскладка. Вид блоков — из ДС:
 * шапка PageHeader (через ConceptHeader), вкладки TabBar «Будущие / Прошедшие»,
 * EventGrid, ShowMore, ConceptLinks, состояния. Своих элементов у страницы нет.
 */

/* Между блоками — 64px (--space-16), кроме шапка → первый блок (32): «Как добраться», «Связи», события,
   «Ещё»; на общей странице — группы понятий по видам. Внутри блоков шаг 16–24,
   так блоки читаются раздельно без линий (пробовали Divider — убрали).
   У ConceptLinks свой отступ 24 — он для строки «Теги» внутри блока на
   странице события, здесь его перекрывает этот. */
#concept-root > * + *,
#similar-root > * + *,
#my-root > * + *,
#search-root > * + *,
#people-root > * + *,
#profile-list-root > * + *,
#topics-root > * + * {
  margin-top: var(--space-16);
}

/* Под шапкой страницы — 32 (--space-8), как на остальных страницах; между
   прочими блоками остаётся 64. Телефон — то же, своего правила нет. */
#concept-root > .page-header + *,
#similar-root > .page-header + *,
#my-root > .page-header + *,
#search-root > .page-header + *,
#people-root > .page-header + *,
#profile-list-root > .page-header + *,
#topics-root > .page-header + * {
  margin-top: var(--space-8);
}

/* «← Назад» (BackButton) — не блок, а часть шапки: до неё свой отступ 24/20. */
#concept-root > .back-row + *,
#similar-root > .back-row + *,
#my-root > .back-row + *,
#search-root > .back-row + *,
#people-root > .back-row + *,
#profile-list-root > .back-row + *,
#topics-root > .back-row + * {
  margin-top: 0;
}

/* «Сохранённые подборки» в «Моих событиях»: DetailTitle (16 под ним — его поле) и ряд ссылок-пилюль вплотную. */
#my-root > .my-filters > .filters { margin-top: 0; }

/* Под последним блоком — вдвое больше обычного поля страницы. */
#concept-root,
#similar-root,
#my-root,
#search-root,
#people-root,
#profile-list-root,
#topics-root {
  padding-bottom: var(--space-12);
}

@media (max-width: 767px) {
  #concept-root,
  #similar-root,
  #my-root,
  #search-root,
  #people-root,
  #profile-list-root,
  #topics-root {
    padding-bottom: calc(var(--space-mobile) * 2);
  }
}

/* Заголовок «События» у площадки нужен рядом с разделом «Как добраться»
   (VenueAddress) — когда он есть. Нет ни адреса, ни названия — заголовка нет. */
#concept-root:not(:has(.venue-address)) #concept-events > .event-detail-title {
  display: none;
}

/* У понятия, «Все похожие» и поиска ряд стоит в ряду управления, как в ленте (.feed-controls,
   events.css): TypePick слева (у поиска его нет), порядок и вид «карточками / списком» справа
   (вид на телефоне скрыт). От вкладок и периодов — 16. */
#concept-events > .feed-controls,
#similar-events > .feed-controls,
#search-events > .feed-controls {
  margin-top: var(--space-4);
}

/* Над рядом выбора всегда разделитель (.divider), как в ленте: ряд — от него на 24.
   У «Все похожие» так же — разделитель между вкладками и рядом категорий. */
#concept-events > .divider + .feed-controls,
#similar-events > .divider + .feed-controls,
#search-events > .divider + .feed-controls {
  margin-top: var(--space-6);
}
@media (max-width: 767px) {
  #concept-events > .divider + .feed-controls,
  #similar-events > .divider + .feed-controls,
  #search-events > .divider + .feed-controls { margin-top: var(--space-mobile); }
}

/* Лента дней (ui.DateStrip) приходит от сервера с запасом, лишние даты браузер
   снимает (Iwent.fitDateStrip). До того — не шире колонки, кнопка календаря
   закреплена справа поверх лишних дат, как на телефоне (dates.css). */
@media (min-width: 768px) {
  #concept-events .date-block {
    overflow: hidden;
  }

  #concept-events .calendar-group {
    position: sticky;
    right: 0;
    background: var(--color-bg);
  }
}

/* Ряд периодов у «Будущих» понятия (Iwent.feedDateFilters с «Все») — тоже 16 от
   вкладок; ряд выбора под ним — через те же 16. У «Прошедших» ряда нет (hidden). */
#concept-events > .concept-dates > .filters {
  margin-top: var(--space-4);
}


/* Категорий во вкладке нет (createTypePicker прячет ряд через display: none) — в ряду остаются
   порядок и вид; на телефоне порядок встаёт первым, без отступа от скрытого ряда. */
@media (max-width: 767px) {
  .feed-controls > .type-pick[style*="display: none"] + .feed-sort,
  .feed-controls > .feed-sort:first-child { margin-top: 0; }
}



/*
 * Входы и профиль — только раскладка. Вид блоков — из ДС.
 * Страница входа (.login-page) общая: администратор (login.html, LoginForm) и
 * пользователь (signin.html, SignInCard) — логотип и карточка по центру, без
 * меню и шапки сайта.
 */

.login-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  padding: var(--space-12) var(--space-4);
}
.login-logo { display: flex; justify-content: center; }
.login-root { width: 100%; display: flex; justify-content: center; }

/* Под карточкой входа — «Вернуться к афише» и (при разработке) тестовый вход:
   столбиком по центру, между ними 16px. Отступ строки «Назад» здесь не нужен —
   расстояние задаёт gap. */
.signin-after {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}
.signin-after .back-row { margin-bottom: 0; }

/* «Добро пожаловать» (welcome.html) — та же страница входа, шаги на всю ширину (Stepper 'page'); снизу
   без поля — к низу экрана прилипают кнопки шага. На телефоне поля --space-mobile: сетка карточек и
   ряд пилюль выходят к краю экрана ровно на них. */
.page-welcome .login-page { padding-bottom: 0; }
/* Интересы — ряд выбора в два ряда (ui.TypePick rows, как в ленте и календаре): пилюли категорий, ниже
   подкатегории и «Сбросить»; между рядами 16. */
@media (min-width: 768px) {
  #welcome-step:has(> .type-pick--rows) { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4) var(--space-2); }
}
/* Пилюли категорий переносятся, а не листаются (и на телефоне): здесь выбор — главное, все сферы на виду. */
#welcome-step > .type-pick--rows > .filters { flex-wrap: wrap; overflow-x: visible; margin-right: 0; padding-right: 0; max-width: none; }
/* Сетка и списки шага — сразу под шапкой: расстояние задаёт Stepper (32), своё поле .events не нужно. */
#welcome-step > .events { margin-top: 0; }
@media (max-width: 767px) {
  .page-welcome .login-page { padding: var(--space-8) var(--space-mobile) 0; }
}

/* Профиль — раскладка страницы события (.event-detail-layout): слева колонка
   героя человека (PersonDetailLeft, разделы под героем), справа выбранный раздел
   (.profile-body). Разделы — через 64 (как блоки страницы понятия), на телефоне 32; первый — вровень с героем. */
.profile-section {
  margin-top: var(--space-16);
}
@media (max-width: 767px) {
  .profile-section { margin-top: var(--space-8); }
}
.profile-body > .profile-section:first-child { margin-top: 0; }

/* Заголовок раздела профиля со своим действием справа (достижения — выбор
   рода и титула): DetailTitle и Dropdown одной строкой по нижнему краю; отступ до
   содержимого — 16, как у DetailTitle без действия. */
.profile-section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.profile-section-head .event-detail-title { margin: 0; }
/* Несколько действий справа (свой профиль: род и титул) — рядом, шаг 16, по нижнему краю. */
.profile-section-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4);
}
/* Настройки: поля выбора → «Уведомления» / «Аккаунт», «Уведомления» (Callout) → «Аккаунт» — 32, как между блоками. */
.profile-section-actions + .event-detail-title,
#profile-settings > .callout + .event-detail-title { margin-top: var(--space-8); }

/* Заголовок раздела → его список: 16 (поле DetailTitle), своё поле .events снято.
   Вкладки «События / Прошедшие» → список: 24 — поле .events, как в ленте.
   Рекомендации — группы по причине: между группами 32, заголовок → события 16. */
.profile-section-head + .events,
.profile-section-head + div > .events:first-child,
.profile-rec-group > .events,
#profile-feed-filter:empty + #profile-feed > .events { margin-top: 0; }
.profile-rec-group + .profile-rec-group { margin-top: var(--space-8); }

/* Под последним блоком — вдвое больше обычного поля страницы. */
#profile-root { padding-bottom: var(--space-12); }
@media (max-width: 767px) {
  #profile-root { padding-bottom: calc(var(--space-mobile) * 2); }
}

/* Новое событие (create.html): поля столбиком с шагом 24, короткие — рядом
   (дата, время, окончание; ссылка и картинка). Шапка → форма — 32, как между
   блоками страницы. */
.create-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  max-width: 800px;
  margin-top: var(--space-8);
}
.create-form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-6) var(--space-4);
}
.create-form-actions { display: flex; gap: var(--space-2); }
#create-root > .callout { margin-top: var(--space-8); }
#create-root { padding-bottom: var(--space-12); }
@media (max-width: 767px) {
  #create-root { padding-bottom: calc(var(--space-mobile) * 2); }
  .create-form-actions > * { flex: 1; }
}

/* Кабинет организатора (organizer.html): шапка → список — 32, как у «Моих событий»;
   под последним блоком — вдвое больше обычного поля страницы. */
#organizer-root > .page-header + * { margin-top: var(--space-8); }
#organizer-root { padding-bottom: var(--space-12); }
@media (max-width: 767px) {
  #organizer-root { padding-bottom: calc(var(--space-mobile) * 2); }
}

/* Лента активности в профиле — две колонки (проба 16.10.2026): та же сетка новостей,
   высота ряда прежняя; dense — двойные карточки не оставляют дыр. На телефоне — колонкой, как было. */
@media (min-width: 768px) {
  #profile-activity .events { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-flow: row dense; }
}

/* Разделы профиля: под «Показать ещё» своего поля нет — до следующего раздела 32 (margin раздела), не 24 + 32. */
.profile-section > .show-more-container,
.profile-section .concept-links > .show-more-container { padding-bottom: 0; }
/* «Слежу за темами»: кнопки-темы прозрачные (FilterButton) — ряд сдвинут на поле кнопки, чтобы текст стоял
   по линии заголовка; строки вплотную (видимый промежуток — поля кнопок), снизу — минус поле. */
.profile-section .concept-links-list { margin-inline: calc(-1 * var(--space-4)); margin-bottom: calc(-1 * var(--space-3)); row-gap: 0; }




/**
 * Раскладка служебных страниц: вход (login.html) и парсеры (parsers.html).
 * Только расположение блоков — вид компонентов в components.css.
 *
 * Парсеры — три экрана в одной странице (адрес после #):
 *   #/          источники: шапка с главным действием «Собрать», напоминание
 *               о незаписанном сборе, группы источников;
 *   #/runs      список сборов;
 *   #/runs/<id> сбор: шапка, итог и «Записать в базу», события, источники, лог.
 * Шапка страницы закреплена при прокрутке: главное действие всегда на виду.
 * Шкала отступов — «внешнее больше внутреннего»: между блоками 24, внутри
 * раздела (заголовок → содержимое) 16.
 */

.admin-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: 0 var(--space-6) var(--space-12);
  max-width: 1152px;
}

/* Закреплённая шапка: фон страницы под ней, чтобы список не просвечивал. */
.page-parsers .content { overflow: visible; min-width: 0; }
.admin-head {
  position: sticky;
  top: 0;
  z-index: 5;
  padding: var(--space-6) 0 var(--space-4);
  background: var(--color-bg);
}

.admin-body { display: flex; flex-direction: column; gap: var(--space-6); }
.source-groups { display: grid; gap: var(--space-4); }

/* Разделы на телефоне: бокового меню там нет — вкладки над шапкой. */
.admin-mobile-nav { display: none; }

.admin-section { display: flex; flex-direction: column; gap: var(--space-4); }
.admin-section-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  line-height: 24px;
  color: var(--color-ink);
}

/* Лог: вывод как в терминале. */
.run-log {
  margin: 0;
  max-height: 480px;
  overflow-y: auto;
  padding: var(--space-4) var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--color-ink);
  color: var(--color-skeleton);
  font-family: ui-monospace, Menlo, monospace;
  font-size: var(--text-xs);
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
}
.run-log:empty::before { content: 'Лог пуст.'; color: var(--color-ink-secondary); }
.run-log .log-error { color: var(--color-danger); }
.run-log .log-start { color: var(--color-type-sport); }
.run-log .log-ok { color: var(--color-type-games); }
.run-log .log-done { color: var(--color-type-cinema); }

/* Настройки источника — общее модальное окно ui.Modal (components.css). */

/* Страница входа (.login-page) — в account.css: она общая со входом пользователя. */

@media (max-width: 767px) {
  .admin-main { padding: 0 var(--space-mobile) var(--space-12); }
  .admin-mobile-nav { display: block; padding-top: var(--space-4); }
  /* Шапка с выбором и кнопкой на телефоне — четверть экрана: не закрепляем. */
  .admin-head { position: static; padding-top: var(--space-4); }
}

/* Заявки на события (moderation.html): причина отказа — под строкой заявки,
   поле и кнопки с шагом 16, кнопки справа. */
.moderation-reject { display: flex; flex-direction: column; gap: var(--space-4); }
.moderation-reject-actions { display: flex; justify-content: flex-end; gap: var(--space-2); }
.page-moderation .admin-body > .events { margin-top: 0; }



/* Документы сайта (legal.html: /about, /terms, /privacy, /copyright, /cookies) —
   только раскладка: шапка → текст (Prose) → форма жалобы, между блоками 32;
   поля формы столбиком через 24, как у «Нового события». */
.legal-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
.legal-section { max-width: var(--text-measure); }
.legal-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.legal-form-actions { display: flex; gap: var(--space-2); }

@media (max-width: 767px) {
  .legal-form-actions > * { flex: 1; }
}


/* components.css — последним: базовые стили атомов, которые раньше жили
   только внутри карточек и в инлайновых стилях страниц. */

/**
 * Базовые стили атомов дизайн-системы.
 *
 * Зачем файл нужен: раньше у аватарки, бейджа категории и скелетона не было
 * собственных стилей — они существовали только внутри конкретной карточки
 * (`.event-card-standard .event-avatar`) или в инлайновом <style> страницы.
 * Вне этого контекста атом разваливался: бейдж терял круг, скелетон был невидим.
 *
 * Здесь лежит минимум, с которым атом выглядит правильно сам по себе.
 * Контекстные правила карточек имеют более высокую специфичность и, как и раньше,
 * перекрывают эти значения — поэтому на существующие страницы файл не влияет.
 *
 * Подключается последним в main.css.
 */

/* ---------- Аватарка события ---------- */

.event-avatar {
  position: relative;
  display: inline-block;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  border: 3px solid var(--color-border);
  background: var(--color-photo-bg);
  box-sizing: border-box;
}

.event-avatar:where([data-type="tech"]) { border-color: var(--color-type-tech); }
.event-avatar:where([data-type="music"]) { border-color: var(--color-type-music); }
.event-avatar:where([data-type="art"]) { border-color: var(--color-type-art); }
.event-avatar:where([data-type="sport"]) { border-color: var(--color-type-sport); }
.event-avatar:where([data-type="cinema"]) { border-color: var(--color-type-cinema); }
.event-avatar:where([data-type="games"]) { border-color: var(--color-type-games); }
.event-avatar:where([data-type="theatre"]) { border-color: var(--color-type-theatre); }
.event-avatar:where([data-type="knowledge"]) { border-color: var(--color-type-knowledge); }
.event-avatar:where([data-type="city"]) { border-color: var(--color-type-city); }
.event-avatar:where([data-type="other"]) { border-color: var(--color-type-other); }
/* badge 'filled' — «инверсия, как в Telegram» (решение 27.10.2026): обводка цвета категории и на
   стеклянной / залитой панели. !important и [data-type] — чтобы перекрыть белую обводку панелей
   (events.css: .event-card-filled / .event-card-variant .event-avatar … !important). */
.event-avatar.event-avatar--badge-filled[data-type] { border-color: var(--event-type-color) !important; }

/*
 * Картинка события поверх круга атома Avatar. Только внутри .event-avatar:
 * тем же классом называется картинка в крупной аватарке героя страницы
 * события, и там растягивание на весь круг закрывало белую обводку 3px
 * (.event-avatar-large в event-detail.css). :where() держит вес правила
 * в один класс — как у остальных базовых правил этого файла.
 */
.event-avatar-image:where(.event-avatar > *) {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background-size: cover;
  background-position: center;
  z-index: 0;
}

/*
 * Буква названия вместо картинки (AvatarLetter): слой под картинкой — она
 * загрузилась и закрыла букву, нет (пусто или 404) — буква видна. Круг
 * заливается сам, поэтому чёрный фон аватарок (в карточках он с !important)
 * больше не виден. Цвет категории — --event-type-color от ближайшего
 * [data-type] (карточка, аватарка, герой). На белом — буква цвета категории,
 * на цветной подложке (filled, стекло, герой) — белая на цвете категории.
 * Размер буквы — как у заголовка карточки, в маленьком круге — половина
 * круга: внешний span — контейнер, cqh от него.
 */
:where([data-type="tech"]) { --event-type-color: var(--color-type-tech); }
:where([data-type="music"]) { --event-type-color: var(--color-type-music); }
:where([data-type="art"]) { --event-type-color: var(--color-type-art); }
:where([data-type="sport"]) { --event-type-color: var(--color-type-sport); }
:where([data-type="cinema"]) { --event-type-color: var(--color-type-cinema); }
:where([data-type="games"]) { --event-type-color: var(--color-type-games); }
:where([data-type="theatre"]) { --event-type-color: var(--color-type-theatre); }
:where([data-type="knowledge"]) { --event-type-color: var(--color-type-knowledge); }
:where([data-type="city"]) { --event-type-color: var(--color-type-city); }
:where([data-type="other"]) { --event-type-color: var(--color-type-other); }
/* Герой человека (PersonHero): «категория» — цвет бренда, им же буква имени. */
:where([data-type="person"]) { --event-type-color: var(--color-brand); }

.event-avatar-letter {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  overflow: hidden;
  container-type: size;
  /* Круг — всегда цвета фона под аватаркой: подложка задаёт --avatar-bg.
     Белая карточка — белый, прозрачная (bordered, на фоне страницы) — фон
     страницы, цветная — цвет категории (ниже). */
  background: var(--avatar-bg, var(--color-surface));
  color: var(--event-type-color, var(--color-muted));
  pointer-events: none;
}

:where(.event-card-bordered) { --avatar-bg: var(--color-bg); }

/* Буква — размером с заголовок рядом: в карточке — как заголовок карточки
   (Unbounded 16, --text-base), в шапке события — как заголовок события.
   Половина круга (40px в карточке) спорила с названием. В маленьком круге — меньше. */
.event-avatar-letter > span {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: min(50cqh, var(--text-base));
  line-height: 1;
}

/* В шапке страницы события — как заголовок события (Unbounded 24, --text-2xl). */
.event-hero .event-avatar-letter > span {
  font-size: min(50cqh, var(--text-2xl));
}

:where(.event-card-filled, .event-card-variant, .event-hero) .event-avatar-letter {
  background: var(--event-type-color, var(--color-muted));
  color: var(--color-surface);
}

/* Рекомендация в шапке события — белая карточка внутри цветной подложки:
   буква как в белых карточках — белый круг, буква цвета категории. */
:where(.recommended-event-card) .event-avatar-letter {
  background: var(--color-surface);
  color: var(--event-type-color, var(--color-muted));
}
/* На карточке с рамкой (фон страницы) — буква аватарки события без фото на фоне карточки, не белым кругом. */
.activity-card.event-card-bordered .recommended-event-card .event-avatar-letter { background: var(--color-bg); }
/* Событие внутри залитой карточки активности — как в залитых карточках ленты: заливка цветом карточки, буква белая. */
.activity-card.event-card-filled .event-avatar-letter {
  background: var(--achievement-color);
  color: var(--color-surface);
}

/* ---------- Бейдж категории ---------- */

.event-type-badge {
  position: absolute;
  bottom: -4px;
  right: -4px;
  z-index: 1;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-type-other);
  box-sizing: border-box;
}

.event-type-badge:where([data-type="tech"]) { background: var(--color-type-tech); }
.event-type-badge:where([data-type="music"]) { background: var(--color-type-music); }
.event-type-badge:where([data-type="art"]) { background: var(--color-type-art); }
.event-type-badge:where([data-type="sport"]) { background: var(--color-type-sport); }
.event-type-badge:where([data-type="cinema"]) { background: var(--color-type-cinema); }
.event-type-badge:where([data-type="games"]) { background: var(--color-type-games); }
.event-type-badge:where([data-type="theatre"]) { background: var(--color-type-theatre); }
.event-type-badge:where([data-type="knowledge"]) { background: var(--color-type-knowledge); }
.event-type-badge:where([data-type="city"]) { background: var(--color-type-city); }
.event-type-badge:where([data-type="other"]) { background: var(--color-type-other); }

.event-type-badge .material-symbols-rounded {
  color: #fff;
  font-size: 18px;
}
/* filled — залит цветом категории, значок белый и на панелях, где бейдж белый (Avatar badge 'filled').
   Вес и !important — чтобы перекрыть events.css (.event-card-filled / .event-card-variant … !important;
   у значка там вес 5 классов — .priority-panel.event-card-variant[data-type] …, отсюда повтор класса). */
.event-type-badge.event-type-badge--filled[data-type] { background: var(--event-type-color) !important; }
.event-type-badge.event-type-badge--filled.event-type-badge--filled[data-type] .material-symbols-rounded { color: var(--color-surface) !important; }

/* ---------- Скелетон ---------- */

.show-skeleton {
  background-color: var(--color-skeleton);
  border-radius: var(--radius-xl);
  height: 352px;
}

.show-skeleton.skeleton-standard { height: 352px; }
.show-skeleton.skeleton-filled { height: 352px; }
.show-skeleton.skeleton-bordered { height: 352px; }
.show-skeleton.skeleton-priority { grid-column: span 2; height: 352px; }
.show-skeleton.skeleton-priority-vertical {
  grid-column: span 1;
  grid-row: span 2;
  height: calc(352px * 2 + 24px);
}
.show-skeleton.skeleton-main { grid-column: 1 / 4; height: 352px; }

/* ---------- Состояния: пусто, ошибка, не найдено ----------
   Одно оформление на все: EmptyState (лента), ErrorState (лента, календарь),
   EventErrorState и NotFoundState (страница события). Раньше оно было
   записано трижды — в calendar.css, events.css и здесь, — и копии
   расходились. Раскладку (сколько колонок сетки занимает блок) задают
   файлы страниц, оформление — только здесь. */

.empty-state,
.error-state,
.event-error-state,
.event-not-found-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  height: 400px;
  width: 100%;
  padding: 0 var(--space-6);
  background: var(--color-surface);
  border-radius: var(--radius-xl);
}

.empty-state-icon,
.error-state-icon,
.event-error-state-icon,
.event-not-found-state-icon {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-md);
  background: var(--color-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-6);
}

.empty-state-icon .material-symbols-rounded,
.error-state-icon .material-symbols-rounded,
.event-error-state-icon .material-symbols-rounded,
.event-not-found-state-icon .material-symbols-rounded {
  --icon-size: var(--icon-state);
  --icon-weight: var(--icon-weight-state);
  --icon-opsz: var(--icon-opsz-state);
  color: var(--color-ink);
  visibility: visible !important;
}

.empty-state-text,
.error-state-text,
.event-error-state-text,
.event-not-found-state-text {
  text-align: center;
}

.empty-state-title,
.error-state-title,
.event-error-state-title,
.event-not-found-state-title {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  line-height: 24px;
  color: var(--color-ink);
  margin-bottom: var(--space-2);
}

.empty-state-subtitle,
.error-state-subtitle,
.event-error-state-subtitle,
.event-not-found-state-subtitle {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-regular);
  line-height: 24px;
  color: var(--color-ink);
}

/* Кнопка пустого состояния (EmptyState action) — на том же расстоянии, что у ошибки. */
.empty-state-btn { margin-top: var(--space-6); }

/* Отступ до кнопки — только там, где кнопка есть: у пустого состояния её нет. */
.error-state-subtitle,
.event-error-state-subtitle,
.event-not-found-state-subtitle {
  margin-bottom: var(--space-6);
}

/* ---------- Иконки ----------
   В base.css размер стоит с !important, поэтому контекстные правила вида
   `.calendar-nav-btn .material-symbols-rounded { font-size: 24px }` не срабатывают.
   Здесь то же правило переписано на переменные: значения по умолчанию прежние,
   а вариант состояния включается классом .material-symbols-rounded--state.

   Варианты — обычный (20/600) и состояние (40/400); иллюстрация достижения (96/400) —
   у .achievement-icon. Иконки контурные: --icon-fill (ось FILL) включает только
   подложка двухтонной иллюстрации достижения. */

.material-symbols-rounded {
  font-size: var(--icon-size, var(--icon-base)) !important;
  width: var(--icon-size, var(--icon-base)) !important;
  height: var(--icon-size, var(--icon-base)) !important;
  font-variation-settings:
    'FILL' var(--icon-fill, 0),
    'wght' var(--icon-weight, var(--icon-weight-base)),
    'GRAD' 0,
    'opsz' var(--icon-opsz, var(--icon-opsz-base));
}

.material-symbols-rounded--state {
  --icon-size: var(--icon-state);
  --icon-weight: var(--icon-weight-state);
  --icon-opsz: var(--icon-opsz-state);
}

/* ---------- Анимация скелетонов ----------
   Пульсация оттенка: серая заглушка плавно темнеет и возвращается. Бегущий
   блик (shimmer) убран. Вторая точка — --color-skeleton-pulse, а не цвет фона:
   почти все заглушки лежат на фоне страницы (--color-bg), и при пульсации в
   его цвет они на середине цикла пропадали целиком.
   Анимируется background-color, поэтому список ниже — только сами заглушки,
   без обёрток: обёртка .skeleton-text своего фона не имеет, и анимация
   залила бы её целиком, вместо строк вышел бы сплошной прямоугольник.
   Анимация перебивает и инлайновый цвет заглушек страницы события. */

@keyframes iwent-skeleton-pulse {
  0%, 100% { background-color: var(--color-skeleton); }
  50% { background-color: var(--color-skeleton-pulse); }
}

.show-skeleton,
.skeleton-line,
.event-skeleton,
.calendar-day-skeleton,
.skeleton-title,
.skeleton-date,
.skeleton-filter,
.skeleton-month-title {
  animation: iwent-skeleton-pulse var(--duration-pulse) var(--ease-in-out) infinite;
}

/* Уважаем системную настройку «меньше движения». */
@media (prefers-reduced-motion: reduce) {
  .show-skeleton,
  .skeleton-line,
  .event-skeleton,
  .calendar-day-skeleton,
  .skeleton-title,
  .skeleton-date,
  .skeleton-filter,
  .skeleton-month-title {
    animation: none;
  }
}
/* То же по переключателю «Меньше движения» в каталоге (tokens.css, :root.motion-reduce). */
.motion-reduce :is(.show-skeleton, .skeleton-line, .event-skeleton, .calendar-day-skeleton,
  .skeleton-title, .skeleton-date, .skeleton-filter, .skeleton-month-title),
.motion-reduce [data-img="wait"],
.motion-reduce .photo[data-load="wait"] { animation: none; }

/* ---------- Загрузка фото ----------
   Фоновые картинки (аватарки календаря и рекомендации, обложки песен, превью видео)
   ждут загрузки под заглушкой. Iwent.fixBrokenImages (из showIcons) ставит
   data-img="wait": картинка спрятана, вместо неё пульсация, как у Skeleton.
   Пришла — "in": слой цвета заглушки над снимком (inset-тень лежит над фоном, под
   содержимым) за --duration-fade становится прозрачным — фото проявляется.
   --img-shade — затемнение заглушки там, где поверх фото белый текст (стеклянная
   панель крупной карточки): текст читается и пока снимка нет.
   Круглая аватарка (слой картинки над буквой AvatarLetter) пульсации не
   получает: data-img="letter" — слой прозрачен, видна буква, как у события без
   фото; пришла — "letter-in", снимок проявляется над буквой за --duration-fade.
   Фото <img> (Photo) — ниже, «Фото»: те же заглушка и проявление. */
@keyframes iwent-img-in {
  from { box-shadow: inset 0 0 0 100vmax var(--img-shade, transparent), inset 0 0 0 100vmax var(--color-photo-bg); }
  to { box-shadow: inset 0 0 0 100vmax transparent, inset 0 0 0 100vmax transparent; }
}

[data-img="wait"] {
  background-image: none !important;
  background-color: var(--color-photo-bg);
  box-shadow: inset 0 0 0 100vmax var(--img-shade, transparent);
  animation: iwent-skeleton-pulse var(--duration-pulse) var(--ease-in-out) infinite;
}

[data-img="in"] {
  animation: iwent-img-in var(--duration-fade) var(--ease-out);
}

@keyframes iwent-img-in-letter {
  from { opacity: 0; }
  to { opacity: 1; }
}

[data-img="letter"] { opacity: 0; }
[data-img="letter-in"] { animation: iwent-img-in-letter var(--duration-fade) var(--ease-out); }

.priority-image:has(+ .event-card-variant) { --img-shade: var(--color-overlay-32); }

@media (prefers-reduced-motion: reduce) {
  [data-img="wait"] {
    background-color: var(--color-photo-bg) !important;
    animation: none;
  }
  [data-img="in"],
  [data-img="letter-in"] {
    animation: none;
  }
}

/* ---------- Фото (Photo) ----------
   <img> события на всю площадь обёртки (круг аватарки, фон крупной карточки, плитка
   снимка, область над героем): обёртка задаёт место, .photo — слой на всю её площадь со
   скруглением обёртки. Фото — по ссылке источника, лениво (loading="lazy").
   Под ним — размытое превью (.photo-preview: копия ~16 px, data: из API), растянутое и
   размытое (--blur-photo-preview), чуть крупнее рамки (--photo-preview-scale): видно сразу.
   Состояние — data-load (Iwent.fixBrokenImages → watchPhoto):
     blur   — превью есть, фото ещё нет: видно превью;
     letter — круглая аватарка над буквой без превью: видна буква;
     wait   — без превью: пульсация заглушки, как у Skeleton (--img-shade — затемнение
              под белым текстом стеклянной панели, как у фоновых);
     in     — фото пришло и проявляется поверх за --duration-fade, затем атрибут снимается
              (превью остаётся под фото — его не видно);
     bad    — не загрузилось и запасного снимка нет: фото нет, видна буква или подложка.
   Без скрипта (или уже загруженное) — фото сразу, превью под ним. */
.photo {
  position: absolute;
  inset: 0;
  display: block;
  overflow: hidden;
  border-radius: inherit;
}

.photo > img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  border-radius: inherit;
}

.photo > .photo-preview {
  filter: var(--blur-photo-preview);
  transform: scale(var(--photo-preview-scale));
}

.photo:is([data-load="blur"], [data-load="letter"], [data-load="wait"]) > .photo-img { opacity: 0; }
.photo[data-load="in"] > .photo-img { animation: iwent-img-in-letter var(--duration-fade) var(--ease-out); }
.photo[data-load="bad"] { display: none; }

.photo[data-load="wait"] {
  background-color: var(--color-photo-bg);
  box-shadow: inset 0 0 0 100vmax var(--img-shade, transparent);
  animation: iwent-skeleton-pulse var(--duration-pulse) var(--ease-in-out) infinite;
}

@media (prefers-reduced-motion: reduce) {
  .photo[data-load="wait"] { animation: none; }
  .photo[data-load="in"] > .photo-img { animation: none; }
}

/* ---------- Галерея фото: полноэкранный просмотр ----------
   Открывается по клику на плитку фото (Iwent.openGallery). Сверху счётчик
   и крестик, по центру снимок со стрелками, внизу лента миниатюр. Стрелки
   у края гаснут — как в слайдере похожих событий. --inline — та же галерея
   в потоке страницы, для каталога. */

.gallery {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  background: var(--color-backdrop);
  color: var(--color-surface);
}

.gallery--inline {
  position: relative;
  inset: auto;
  z-index: 0;
  height: 560px;
  border-radius: var(--radius-xl);
  overflow: hidden;
}

.gallery-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-6);
}

.gallery-counter {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 24px;
  font-variant-numeric: tabular-nums;
}

.gallery-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  gap: var(--space-6);
  padding: 0 var(--space-6);
}

.gallery-frame {
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gallery-image {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--radius-lg);
}

.gallery-btn {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--color-on-dark-12);
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-out), opacity var(--duration-base) var(--ease-out);
}

.gallery-btn .material-symbols-rounded {
  color: var(--color-surface);
}

.gallery-btn:hover:not(:disabled),
.gallery-btn:focus-visible {
  background: var(--color-on-dark-32);
}

.gallery-btn:focus-visible,
.gallery-thumb:focus-visible {
  outline: 2px solid var(--color-surface);
  outline-offset: 2px;
}

.gallery-btn:disabled {
  opacity: 0.32;
  cursor: default;
  flex-shrink: 0;
}

.gallery-thumbs {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-6);
  overflow-x: auto;
}

.gallery-thumb {
  width: 64px;
  height: 48px;
  flex-shrink: 0;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  background-color: var(--color-ink);
  background-size: cover;
  background-position: center;
  opacity: 0.5;
  cursor: pointer;
  transition: opacity var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out);
}

.gallery-thumb:hover {
  opacity: 0.8;
}

.gallery-thumb[aria-current="true"] {
  opacity: 1;
  border-color: var(--color-surface);
}

/* Страница под открытой галереей не прокручивается. */
body.gallery-open {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .gallery-btn, .gallery-thumb { transition: none; }
}

/* Кнопка без подписи: padding со всех сторон делает её квадратной 44×44 —
   тот же размер, что у .calendar-nav-btn. Доступное имя даёт aria-label. */
.btn-icon {
  /* 11px + рамка 1px + иконка 20px = 44×44, как стрелки слайдера и календаря.
     С 12px кнопка выходила 46×46. */
  padding: 11px;
}

/* Button({ size: 'small' }) — 32px: 5 + иконка 20 + 5 + рамка 2. Вид как у
   обычной (рамка --color-border, наведение --color-hover и синий текст),
   меньше только поля, кегль и промежуток. */
.btn-small {
  padding: calc(var(--space-1) + 1px) var(--space-3);
  gap: var(--space-1);
  font-size: var(--text-xs);
  line-height: 16px;
}

/* Button({ compactOnMobile }) — на телефоне только иконка, квадрат 44×44 как
   .btn-icon («Войти» в шапке гостя: с подписью кнопка прилипала к городу).
   Подпись скрыта, имя для чтеца — aria-label кнопки. Разметка одна на обе ширины. */
@media (max-width: 767px) {
  .btn-compact-mobile {
    /* как у .btn-icon: 11 + рамка 1 + иконка 20 = 44 */
    padding: calc(var(--space-3) - 1px);
    flex-shrink: 0;
  }
  .btn-compact-mobile > .btn-label { display: none; }
}

/* Мелкие заглушки: заголовок, строки текста, кнопка, аватарка.
   Размер и радиус задаёт Iwent.ui.Skeleton — здесь только заливка,
   поверх которой идёт общий блик. */
.skeleton-line {
  background-color: var(--color-skeleton);
}
/* glass — поверх фото или заглушки карточки (столбик «Листать» на телефоне): стекло, как у
   Button glass; пульсации нет — она перекрасила бы стекло в серый. */
.skeleton-line--glass {
  background-color: var(--color-overlay-32);
  -webkit-backdrop-filter: var(--blur-panel);
  backdrop-filter: var(--blur-panel);
  animation: none;
}

.skeleton-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* ---------- Граф понятий: блоки ссылок ----------
   Ссылка-понятие — FilterButton (ConceptChip), шапка страницы — PageHeader:
   своего вида у них нет. Здесь только раскладка блока. */

.concept-links { margin-top: var(--space-6); }

.concept-links-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Свёрнутый список (ConceptLinks с rows, Iwent.initConceptLinksToggle):
   лишние ряды скрыты, «Показать все» видна, только пока что-то скрыто. */
.concept-links-list > .is-beyond { display: none; }
.concept-links:not(.is-collapsed) > .show-more-container { display: none; }
/* Кнопка — последняя в блоке: снизу отступ даёт раскладка страницы, не она. */
.concept-links > .show-more-container { padding-bottom: 0; }
/* До скрипта (страница от сервера, seo.js) ряды ещё не посчитаны: список
   обрезан по высоте rows рядов, «Показать все» — там, где по оценке
   ConceptLinks (data-overflow) рядов больше. initConceptLinksToggle потом
   считает точно; совпала оценка — ничего не сдвигается. */
.concept-links[data-rows]:not([data-toggle]) > .concept-links-list {
  max-height: calc(var(--rows) * var(--control-height) + (var(--rows) - 1) * var(--space-2));
  overflow: hidden;
}
@media (max-width: 767px) {
  .concept-links[data-overflow~="sm"]:not([data-toggle]) > .show-more-container { display: block; }
}
@media (min-width: 768px) and (max-width: 1279px) {
  .concept-links[data-overflow~="md"]:not([data-toggle]) > .show-more-container { display: block; }
}
@media (min-width: 1280px) {
  .concept-links[data-overflow~="lg"]:not([data-toggle]) > .show-more-container { display: block; }
}

/* «Связано» на странице события — как «Жанр»: подпись и строка ссылок через
   точку, как теги в карточках. Шрифт и цвет — от .event-extra-label/-value.
   .concept-tag — и ссылки в значении EventExtraInfo («Дата» — на день,
   «Место» — на площадку): своего вида у них нет. */
.concept-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
}

.concept-tag {
  color: inherit;
  text-decoration: none;
  transition: color var(--duration-base) var(--ease-out);
}

.concept-tag:hover { color: var(--color-brand); }
.concept-tag:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }

.concept-tags .event-tag-dot { background: var(--color-ink); }

/* Ссылка и точка за ней (ConceptLinks inline) — один неразрывный элемент:
   при переносе строки точка остаётся в конце строки. */
.concept-tags-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  min-width: 0;
}

/* Строки «Теги» (ConceptLinks inline с rows, Iwent.initConceptLinksToggle):
   лишние ссылки скрыты, последней в видимых строках — «ещё N» (MoreLink),
   видна, только пока что-то скрыто. До скрипта (страница от сервера) строк
   никто не считал: скрыто и «ещё N» — по оценке ConceptLinks (data-beyond,
   data-more: sm / md / lg / xl); после замера — data-toggle, решают классы. */
.concept-tags > .is-beyond,
.concept-tags > .concept-tags-more:not(.is-shown) { display: none; }
@media (max-width: 767px) {
  .concept-tags:not([data-toggle]) > [data-beyond~="sm"] { display: none; }
  .concept-tags:not([data-toggle]) > .concept-tags-more[data-more~="sm"] { display: block; }
}
@media (min-width: 768px) and (max-width: 1279px) {
  .concept-tags:not([data-toggle]) > [data-beyond~="md"] { display: none; }
  .concept-tags:not([data-toggle]) > .concept-tags-more[data-more~="md"] { display: block; }
}
@media (min-width: 1280px) and (max-width: 1439px) {
  .concept-tags:not([data-toggle]) > [data-beyond~="lg"] { display: none; }
  .concept-tags:not([data-toggle]) > .concept-tags-more[data-more~="lg"] { display: block; }
}
@media (min-width: 1440px) {
  .concept-tags:not([data-toggle]) > [data-beyond~="xl"] { display: none; }
  .concept-tags:not([data-toggle]) > .concept-tags-more[data-more~="xl"] { display: block; }
}



/* ---------- Админка: статус, ход работы, поля, источники, прогоны ----------
   Язык тот же, что у ленты и календаря: плашки как у даты и площадки,
   пилюли-фильтры для выбора, вкладки для режима, белые карточки со
   скруглением 24/32, выбранное — синяя рамка. */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  font-family: var(--font-alt);
  color: var(--color-ink); /* не чёрный по умолчанию: токена #000 больше нет (аудит ДС) */
}

/* Статус — плашка того же вида, что дата и площадка в карточке. */
.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  font-family: var(--font-alt);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 16px;
  color: var(--color-ink);
  white-space: nowrap;
}
.status-chip::before {
  content: '';
  width: var(--space-2);
  height: var(--space-2);
  border-radius: 50%;
  background: var(--chip-dot, var(--color-muted));
  flex-shrink: 0;
}
.status-chip[data-tone="active"] { --chip-dot: var(--color-brand); color: var(--color-brand); }
.status-chip[data-tone="success"] { --chip-dot: var(--color-type-games); }
.status-chip[data-tone="warning"] { --chip-dot: var(--color-type-cinema); }
.status-chip[data-tone="danger"] { --chip-dot: var(--color-danger); color: var(--color-danger); }
.status-chip[data-tone="neutral"] { color: var(--color-ink-secondary); }
/* На цветной подложке (StatusChip surface 'dark' — «Прошло» в герое события):
   как плашки даты и места рядом — белый текст и полупрозрачная белая рамка. */
.status-chip[data-surface="dark"] {
  --chip-dot: var(--color-on-dark-64);
  color: var(--color-surface);
  border-color: var(--color-on-dark-32);
}
/* Плашка-ссылка (StatusChip href — «Перенесено на …» ведёт на новое событие): наведение —
   как у плашек даты и места в герое: рамка пропадает, плашка заливается цветом рамки. */
a.status-chip {
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out);
}
a.status-chip:is(:hover, :focus-visible) {
  background: var(--color-border);
  border-color: transparent;
}
a.status-chip[data-surface="dark"]:is(:hover, :focus-visible) {
  background: var(--color-on-dark-32);
}

.progress { --progress-color: var(--color-brand); }
.progress[data-tone="success"] { --progress-color: var(--color-type-games); }
.progress[data-tone="warning"] { --progress-color: var(--color-type-cinema); }
.progress[data-tone="danger"] { --progress-color: var(--color-danger); }

.progress-track {
  height: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--color-skeleton);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  border-radius: inherit;
  background: var(--progress-color);
  transition: width var(--duration-slow) var(--ease-out);
}
/* Неизвестно, сколько осталось: бегущая полоса вместо доли. */
.progress[data-indeterminate] .progress-fill {
  width: 30% !important;
  animation: progress-run var(--duration-progress) var(--ease-in-out) infinite;
}
@keyframes progress-run {
  from { transform: translateX(-100%); }
  to { transform: translateX(340%); }
}
@media (prefers-reduced-motion: reduce) {
  .progress[data-indeterminate] .progress-fill { animation: none; width: 100% !important; opacity: 0.4; }
}
.motion-reduce .progress[data-indeterminate] .progress-fill { animation: none; width: 100% !important; opacity: 0.4; }
.progress-label {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  color: var(--color-ink-secondary);
}
.progress--label-top .progress-label { margin-top: 0; margin-bottom: var(--space-2); }
.progress-count {
  font-family: var(--font-alt);
  font-weight: var(--weight-bold);
  color: var(--color-ink);
  white-space: nowrap;
}

/* Подпись поля — как подпись месяца над лентой дат. */
.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field-label {
  padding: 0;
  font-family: var(--font-alt);
  font-size: var(--text-xs);
  line-height: 16px;
  color: var(--color-ink-secondary);
  text-transform: uppercase;
}
.field-input {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  transition: border-color var(--duration-base) var(--ease-out);
}
/* Пример в пустом поле — приглушённо и не жирно: иначе его принимают за введённое. */
.field-input::placeholder { color: var(--color-muted); font-weight: var(--weight-regular); opacity: 1; }
.field-input:hover { border-color: var(--color-muted); }
/* is-focus — вид фокуса для каталога (SearchField focus), где фокус не поставить. */
.field-input:focus-visible,
.field-input.is-focus { outline: none; border-color: var(--color-brand); box-shadow: 0 0 0 1px var(--color-brand); }
/* Телефон: iOS Safari приближает страницу к полю, если текст в нём мельче 16px, —
   на телефоне поле 16 (высота та же: строка 20). */
@media (max-width: 767px) {
  .field-input { font-size: var(--text-base); }
}
.field.has-error .field-input { border-color: var(--color-danger); }
.field-msg { font-family: var(--font-body); font-size: var(--text-xs); color: var(--color-ink-secondary); }
.field.has-error .field-msg { color: var(--color-danger); }

.login-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: 100%;
  max-width: 400px;
  padding: var(--space-6);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}
.login-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  line-height: 32px;
  color: var(--color-ink);
}
.login-lede { margin: 0; font-family: var(--font-body); font-size: var(--text-sm); color: var(--color-ink-secondary); }

/* Шаги с документом (Stepper, accept.html — правила после первого входа): карточка
   входа шире — под строку текста документа (--text-measure) и поля карточки. Полоса
   шагов: кружок 24 (номер Montserrat 12 жирный, у пройденного — галочка) и подпись
   Onest 14; открытый — синий кружок, подпись основным цветом; между шагами — полоска
   --color-border. Текст прокручивается внутри карточки между линиями, кнопки — строкой
   через 8, последняя («Принимаю») — справа. Высота текста — половина экрана (на
   телефоне 40%: заголовок там в несколько строк, кнопки остаются на экране). */
.stepper { max-width: calc(var(--text-measure) + 2 * var(--space-6)); }
.stepper-steps { display: flex; align-items: center; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.stepper-step {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 20px;
  color: var(--color-ink-secondary);
}
.stepper-step:first-child { flex: 0 1 auto; }
.stepper-step + .stepper-step::before {
  content: '';
  flex: 1 1 var(--space-4);
  min-width: var(--space-4);
  height: 1px;
  background: var(--color-border);
}
.stepper-mark {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: var(--space-6);
  height: var(--space-6);
  border-radius: 50%;
  background: var(--color-bg);
  font-family: var(--font-alt);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--color-ink-secondary);
}
.stepper-mark .material-symbols-rounded { font-size: var(--text-base); }
.stepper-label { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.stepper-step[data-state="current"] { color: var(--color-ink); }
.stepper-step[data-state="current"] .stepper-mark { background: var(--color-brand); color: var(--color-surface); }
.stepper-step[data-state="done"] .stepper-mark { color: var(--color-brand); }
.stepper-body {
  max-height: 50vh;
  overflow-y: auto;
  padding: var(--space-4) var(--space-2) var(--space-4) 0;
  border-top: 1px solid var(--color-border-soft);
  border-bottom: 1px solid var(--color-border-soft);
}
.stepper-body:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }
.stepper-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.stepper-actions > :last-child { margin-left: auto; }

/* Шаги на всю страницу (Stepper variant 'page', welcome.html — «Добро пожаловать» после правил): без
   карточки, на фоне страницы — внутри белые блоки ДС (пилюли, строки, карточки событий). Полоса шагов →
   шапка → содержимое → кнопки через 32 (внешнее); в шапке украшение (стикеры) → заголовок 24, заголовок →
   строка 16. Заголовок крупнее карточки: Unbounded 40. Кружки следующих шагов — белые (на фоне --color-bg
   его же цвет пропал бы). Содержимое не прокручивается и без линий; кнопки прилипают к низу экрана на
   фоне страницы — «Дальше» под рукой и под длинным списком. */
.stepper--page { display: flex; flex-direction: column; gap: var(--space-8); width: 100%; max-width: var(--stepper-page-width); }
.stepper--page .stepper-mark { background: var(--color-surface); }
.stepper-head { display: flex; flex-direction: column; gap: var(--space-4); }
.stepper-art { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-2); margin-bottom: var(--space-2); }
.stepper--page .login-title { font-size: var(--text-4xl); line-height: 48px; }
.stepper--page .login-lede { font-size: var(--text-base); }
.stepper--page .stepper-body { max-height: none; overflow: visible; padding: 0; border: 0; }
.stepper--page .stepper-actions { position: sticky; bottom: 0; z-index: 2; padding: var(--space-4) 0; background: var(--color-bg); }

@media (max-width: 767px) {
  .stepper-step:not([data-state="current"]) .stepper-label { display: none; }
  .stepper-step[data-state="current"] { flex: 0 1 auto; }
  .stepper-body { max-height: 40vh; }
  .stepper-actions > * { flex: 1; }
  .stepper--page .login-title { font-size: var(--text-2xl); line-height: 32px; }
  .stepper--page .stepper-art .sticker { height: var(--sticker-height-mobile); }
  /* Ряд кнопок — от края до края экрана, как сетка карточек на телефоне (.events): под ним ничего не видно сбоку. */
  .stepper--page .stepper-actions { margin-inline: calc(-1 * var(--space-mobile)); padding: var(--space-4) var(--space-mobile) calc(var(--space-4) + env(safe-area-inset-bottom)); }
  /* Уведомление (Toast) на телефоне — над прилипшими кнопками шага, как над нижней панелью меню:
     иначе оно закрывает «Дальше». Высота ряда — кнопка 44 и поля 16 сверху и снизу. */
  body:has(.stepper--page) { --bottom-nav-offset: calc(var(--control-height) + 2 * var(--space-4)); }
}

/* Знак сервиса на кнопке входа (ProviderMark): 20×20, как иконка кнопки. */
.provider-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border-radius: var(--radius-xs);
  font-family: var(--font-alt);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 1;
  color: var(--color-surface);
}
.provider-mark[data-provider="yandex"] { background: var(--color-yandex); border-radius: 50%; }
/* Официальные знаки (VK, Telegram, WhatsApp) — SVG в фирменном цвете, без подложки. */
.provider-mark > svg { width: 100%; height: 100%; display: block; }
.provider-mark[data-provider="vk"] { color: var(--color-vk); }
.provider-mark[data-provider="telegram"] { color: var(--color-telegram); }
.provider-mark[data-provider="whatsapp"] { color: var(--color-whatsapp); }
.provider-mark > svg path { fill: currentColor; }
/* Знаки сервисов «Где посмотреть…»: у Кинопоиска, Steam, GOG — SVG в фирменном цвете,
   у остальных — буква на фирменном цвете (на жёлтом — тёмная). */
.provider-mark[data-provider="kinopoisk"] { color: var(--color-kinopoisk); }
.provider-mark[data-provider="steam"] { color: var(--color-steam); }
.provider-mark[data-provider="gog"] { color: var(--color-gog); }
.provider-mark[data-provider="okko"] { color: var(--color-okko); }
.provider-mark[data-provider="ivi"] { color: var(--color-ivi); }
.provider-mark[data-provider="wink"] { background: var(--color-wink); }
.provider-mark[data-provider="start"] { color: var(--color-start); }
.provider-mark[data-provider="premier"] { background: var(--color-premier); color: var(--color-ink); }
.provider-mark[data-provider="kion"] { background: var(--color-kion); }
.provider-mark[data-provider="yandexmusic"] { color: var(--color-ink); }
.provider-mark[data-provider="zvuk"] { color: var(--color-zvuk); }
.provider-mark[data-provider="mtsmusic"] { background: var(--color-mtsmusic); }
.provider-mark[data-provider="litres"] { background: var(--color-litres); }
.provider-mark[data-provider="yandexbooks"] { background: var(--color-yandexbooks); }
/* Крупный знак — в карточке сервиса (ServiceCard): 48, как аватарка поменьше. */
.provider-mark--plate { background: var(--color-surface); padding: var(--space-2); box-sizing: border-box; }
.provider-mark--lg { width: 48px; height: 48px; border-radius: var(--radius-md); font-size: var(--text-base); }
.login-error {
  padding: 12px 16px;
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-danger);
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}

/* Группа источников (SourceGroup) — белая карточка-список: заголовок
   категории и строки источников без своих подложек. Строка подсвечивается
   при наведении и выборе — так 20 источников помещаются на экран, а не на
   четыре. Внутри: 12 по краям, строки вплотную. */
.source-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}
.source-group-list { display: flex; flex-direction: column; gap: var(--space-1); }

/* Заголовок группы: Montserrat 16, на ступень тише h1 страницы; иконка в
   цвете категории, число источников — сразу за названием. Галочка — в одной
   колонке с галочками строк. */
.source-group-head { display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--space-3) 0 0; min-height: 44px; }
.source-group-head:not(.has-pick) { padding-left: var(--space-3); }
.source-group-head.has-pick .source-group-icon { margin-left: var(--space-1); }
.source-group-icon { display: inline-flex; color: var(--color-type-other); }
.source-group-head[data-type="music"] .source-group-icon { color: var(--color-type-music); }
.source-group-head[data-type="art"] .source-group-icon { color: var(--color-type-art); }
.source-group-head[data-type="sport"] .source-group-icon { color: var(--color-type-sport); }
.source-group-head[data-type="cinema"] .source-group-icon { color: var(--color-type-cinema); }
.source-group-head[data-type="games"] .source-group-icon { color: var(--color-type-games); }
.source-group-head[data-type="theatre"] .source-group-icon { color: var(--color-type-theatre); }
.source-group-head[data-type="knowledge"] .source-group-icon { color: var(--color-type-knowledge); }
.source-group-head[data-type="city"] .source-group-icon { color: var(--color-type-city); }
.source-group-head[data-type="other"] .source-group-icon { color: var(--color-type-other); }
.source-group-head[data-type="tech"] .source-group-icon { color: var(--color-type-tech); }
.source-group-name {
  margin: 0;
  font-family: var(--font-alt);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  line-height: 24px;
  color: var(--color-ink);
}
.source-group-count {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  line-height: 20px;
  color: var(--color-ink-secondary);
}

/* Строка источника: [выбор] название и сайт | состояние | объём и пауза | настройки.
   Колонки состояния и объёма фиксированы — строки читаются как таблица. */
.source-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 60px;
  padding: var(--space-2) 0;
  border-radius: var(--radius-md);
  transition: background-color var(--duration-base) var(--ease-out);
}
.source-row.is-readonly { padding-left: var(--space-3); padding-right: var(--space-3); }
.source-row[data-selected] { background: var(--color-bg); }
.source-row-title { flex: 1; min-width: 0; }
.source-row-name {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink);
  overflow-wrap: anywhere;
}
.source-row[data-disabled] .source-row-name { color: var(--color-muted); }
.source-row-meta { font-family: var(--font-body); font-size: var(--text-xs); line-height: 16px; color: var(--color-ink-secondary); }
.source-row-status { flex: 0 0 320px; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.source-row.is-readonly .source-row-status { flex-basis: 420px; }
.source-row-config { flex: 0 0 136px; font-family: var(--font-body); font-size: var(--text-xs); line-height: 16px; color: var(--color-ink-secondary); text-align: right; }
.source-row > .btn:last-child { border-color: transparent; }
.source-pick,
.source-pick:disabled { border-color: transparent; }

.source-status-main { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.source-status-text { font-family: var(--font-alt); font-size: var(--text-sm); font-weight: var(--weight-bold); line-height: 20px; color: var(--color-ink); }
.source-status-when { font-family: var(--font-body); font-size: var(--text-xs); line-height: 16px; color: var(--color-ink-secondary); }
/* Пояснение — одной строкой с многоточием; целиком — в подсказке (title). */
.source-status-note {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: 16px;
  color: var(--color-ink-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.source-status-note.is-error { color: var(--color-danger); }
.source-row-status .progress-label { font-size: var(--text-xs); }

/* Узко: состояние уходит второй строкой под название; объём и пауза на
   телефоне прячутся — они есть в настройках источника. */
@media (max-width: 900px) {
  .source-row { flex-wrap: wrap; row-gap: 0; }
  .source-row-title { flex: 1 1 0; }
  .source-row-config { flex: 0 0 auto; }
  .source-row-status { flex: 1 1 100%; order: 3; padding: 0 0 var(--space-1) calc(44px + var(--space-4)); }
  .source-row.is-readonly .source-row-status { padding-left: 0; }
}
@media (max-width: 767px) {
  .source-row-config { display: none; }
  .page-header-actions { width: 100%; }
  .page-header-actions > * { flex: 1 1 auto; }
}

/* Форма настроек в окне: настройки источника (SourceSettings) и расширенные
   фильтры ленты (AdvancedFiltersBody, .settings-form) — группы через 24. */
.source-settings, .settings-form { display: flex; flex-direction: column; gap: var(--space-6); }
.source-settings .field { max-width: 240px; }
/* min-width: 0 — fieldset по умолчанию не уже своего содержимого: на телефоне ряд
   пилюль (не переносится, листается) раздвигал группу, и подсказка уходила за край окна. */
.settings-group { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
/* Группа выбора (ChoiceGroup): подпись → ряд 16, ряд → подсказка 8. Подпись — legend:
   у fieldset она не участвует в flex и отступа gap не получала (было 4px); float
   делает её обычным элементом ряда. */
.settings-group > legend { float: left; width: 100%; margin-bottom: var(--space-2); }
.settings-group .filters { margin-top: 0; }
.settings-group .filter-btn { background: var(--color-bg); }
/* Выбранный фильтр на белом (настройки, окна: показ серии в «Добавить в календарь»):
   белый фон выбранного не виден на белом — синяя обводка. */
.settings-group .filter-btn.active,
.modal .filter-btn.active { background: var(--color-surface); box-shadow: inset 0 0 0 2px var(--color-brand); }
.settings-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.settings-msg { font-family: var(--font-alt); font-size: var(--text-sm); font-weight: var(--weight-bold); color: var(--color-type-games); }
.settings-msg.is-error { color: var(--color-danger); }

/* Список сборов. «Не записан» — цветом предупреждения: это незаконченное дело. */
.run-history { overflow-x: auto; padding: var(--space-2) var(--space-4); border-radius: var(--radius-xl); background: var(--color-surface); }
.run-history-table { width: 100%; border-collapse: collapse; font-family: var(--font-alt); font-size: var(--text-sm); color: var(--color-ink); }
.run-history-table th {
  text-align: left;
  font-weight: var(--weight-regular);
  font-size: var(--text-xs);
  color: var(--color-ink-secondary);
  text-transform: uppercase;
  padding: var(--space-3);
  white-space: nowrap;
}
.run-history-table td { padding: var(--space-2) var(--space-3); border-top: 1px solid var(--color-border-soft); white-space: nowrap; }
.run-history-table td:last-child { text-align: right; }
.run-history-row { cursor: pointer; transition: background-color var(--duration-base) var(--ease-out); }
.run-history-row:hover { background: var(--color-hover); }
.run-history-row .btn { border-color: transparent; }
.run-history-when { font-weight: var(--weight-bold); }
.run-history-ok { color: var(--color-ink); }
.run-history-todo { font-weight: var(--weight-bold); color: var(--color-type-cinema); }
.run-history-none { color: var(--color-ink-secondary); }


/* ---------- Мобильная версия (≤ 767px): состояния ----------
   Пусто, ошибка, «не найдено» — белая карточка от края до края экрана, как в
   макетах; иначе подзаголовок не помещается в строку. В ленте карточка уже
   стоит в сетке, растянутой на всю ширину, там поля не вычитаем. */
@media (max-width: 767px) {
  .empty-state,
  .error-state {
    width: auto;
    margin-left: calc(-1 * var(--space-mobile));
    margin-right: calc(-1 * var(--space-mobile));
  }

  .events > .empty-state,
  .events > .error-state {
    margin-left: 0;
    margin-right: 0;
  }
}

/* ---------- Мобильная версия (≤ 767px): заглушки ленты ----------
   Как в макете: крупные карточки — квадрат 375×375, простые — 156px. */
@media (max-width: 767px) {
  .show-skeleton.skeleton-priority,
  .show-skeleton.skeleton-priority-vertical,
  .show-skeleton.skeleton-main {
    height: 375px;
  }

  .show-skeleton.skeleton-standard {
    height: 156px;
  }
}

/* Главная кнопка страницы — заливка цветом бренда. Одна на экран: «Собрать»,
   «Записать в базу». Остальные кнопки — в рамке. */
.btn-primary {
  background: var(--color-brand);
  border-color: var(--color-brand);
  color: var(--color-surface);
}
/* :not([aria-disabled]) — та же сила селектора, что у .btn:hover (base.css): иначе под
   курсором главная кнопка брала вид обычной (светлая с синим). */
.btn-primary:hover:not(:disabled):not([aria-disabled="true"]),
.btn-primary.is-hover {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: var(--color-surface);
}
.btn-primary:disabled { background: var(--color-skeleton); border-color: var(--color-skeleton); color: var(--color-muted); }

/* Выпадающий список (Dropdown) — панель того же вида, что выбор месяца в
   календаре: белая, радиус 24, мягкая тень снизу; пункты — Montserrat 14
   жирный, плашками: наведённый — фон --color-hover и синий текст, как у
   кнопок и фильтров; выбранный приглушён. */
.dropdown { position: relative; display: inline-flex; flex-direction: column; gap: var(--space-2); }
.dropdown-trigger { justify-content: space-between; }
.dropdown-value { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dropdown-trigger .material-symbols-rounded { transition: transform var(--duration-base) var(--ease-in-out); }
.dropdown.open .dropdown-trigger .material-symbols-rounded { transform: rotate(180deg); }
.dropdown.open .dropdown-trigger { background: var(--color-hover); color: var(--color-brand); border-color: transparent; }
.dropdown-panel {
  display: none;
  position: absolute;
  top: calc(100% + var(--space-2));
  left: 0;
  z-index: 100;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  min-width: 100%;
  width: max-content;
  max-width: 400px;
  max-height: 400px;
  overflow-y: auto;
  /* Поле 12 + поле пункта 12 = текст в 24 от края, как раньше; плашка
     наведения стоит в 12 от края со всех сторон, её радиус 12 = 24 − 12 —
     концентрична углу панели. */
  padding: var(--space-3);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-panel);
}
/* Раскрытие: проявление со сдвигом вниз (fast), закрытие — обратно (display — вместе с ними,
   allow-discrete); начальное состояние — @starting-style. Сервер рисует список закрытым. */
.dropdown-panel {
  opacity: 0;
  transform: translateY(calc(var(--space-1) * -1));
  transition: opacity var(--duration-fast) var(--ease-in), transform var(--duration-fast) var(--ease-in),
    display var(--duration-fast) allow-discrete;
}
.dropdown.is-up .dropdown-panel { transform: translateY(var(--space-1)); }
.dropdown.open .dropdown-panel {
  display: flex;
  opacity: 1;
  transform: none;
  transition: opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out),
    display var(--duration-fast) allow-discrete;
}
@starting-style {
  .dropdown.open .dropdown-panel { opacity: 0; transform: translateY(calc(var(--space-1) * -1)); }
  .dropdown.is-up.open .dropdown-panel { transform: translateY(var(--space-1)); }
}
/* В окне (Modal) список поверх, окно не растёт: пока он открыт, края окна не обрезают панель. */
.modal:has(.dropdown.open) { overflow: visible; }
.modal .dropdown-panel { max-height: 240px; }
.dropdown.is-up .dropdown-panel { top: auto; bottom: calc(100% + var(--space-2)); }
.dropdown.is-right .dropdown-panel { left: auto; right: 0; }
/* Пункт — плашка во всю ширину панели: поля 8/12, между пунктами 0, поэтому
   шаг строк прежний — 36 (20 + 8 + 8). Наведение и фокус — как у кнопок и
   фильтров: фон --color-hover, синий текст. */
.dropdown-item {
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  text-align: left;
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink);
  cursor: pointer;
  transition: color var(--duration-base) var(--ease-out), background-color var(--duration-base) var(--ease-out);
}
/* Подсказка поиска, выбранная стрелками (SearchSuggest): фокус остаётся в поле
   (aria-activedescendant), поэтому вид наведения — по aria-selected. */
.dropdown-item:hover,
.dropdown-item:focus-visible,
.search-option[aria-selected="true"] { background: var(--color-hover); outline: none; }
.dropdown-item:not(.active):hover,
.dropdown-item:focus-visible,
.search-option[aria-selected="true"] { color: var(--color-brand); }
.dropdown-item.active { opacity: 0.24; cursor: default; }
.dropdown-item.active:focus-visible { opacity: 1; }
/* Пункт с иконкой: иконка и цвет категории — как у фильтров ленты
   (--event-type-color от data-type); при наведении иконка синеет вместе с
   подписью, тоже как у фильтров. */
.dropdown-label { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; vertical-align: top; }
.dropdown-label[data-type] .material-symbols-rounded { color: var(--event-type-color); transition: color var(--duration-base) var(--ease-out); }
.dropdown-item:hover .dropdown-label .material-symbols-rounded,
.dropdown-item:focus-visible .dropdown-label .material-symbols-rounded { color: currentColor; }
/* Мультивыбор (multiple): флажок — атом Checkbox, тот же, что у галочек
   источников. Выбранные не приглушаются — их несколько, и снять отметку
   можно тем же щелчком. Флажок → подпись 12, иконка → название 8: флажок
   — элемент управления, иконка — часть подписи, и шаг между ними крупнее. */
.dropdown.is-multiple .dropdown-item { display: flex; align-items: center; gap: var(--space-3); }
/* Группы (groups): заголовок — подпись поля (.field-label) с полями пункта,
   чтобы стоять по тексту пунктов; между группами — линия, как у разделителей
   ленты. Текст последнего пункта → линия 16, линия → заголовок 16, заголовок →
   первый пункт 16. */
.dropdown-group { display: flex; flex-direction: column; align-items: stretch; }
.dropdown-group > .field-label { padding: var(--space-2) var(--space-3); }
/* Ряд выбора категорий (TypePick: TypeDropdown, SubtypeDropdown, «Сбросить»)
   — лента, календарь, день, понятие, «Все похожие». Только раскладка: через 8px. */
.type-pick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; }
/* Категорий меньше пяти — пилюлями (FilterBar в ряду): свой отступ сверху ряду не нужен. */
.type-pick > .filters { margin-top: 0; }
/* Два ряда (TypePick rows: ленты и страницы со списком событий): корень сам не рамка —
   его пункты встают в ряд управления (.feed-controls, events.css). Категории — первый
   ряд на всю ширину, листается без переноса; подкатегории, расширенные фильтры и
   «Сбросить» — второй, вместе с порядком и видом. Расстояние между рядами — 16.
   Пилюли «Бесплатно» и «Детям» (TypePickQuick, pick-quick) — во втором ряду, не своим рядом. */
@media (min-width: 768px) {
  .type-pick--rows { display: contents; }
  .type-pick--rows > .filters:not([data-filter-group="pick-quick"]) { flex: 0 0 100%; min-width: 0; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .type-pick--rows > .filters::-webkit-scrollbar { display: none; }
  .type-pick--rows > .filters .filter-btn { flex-shrink: 0; white-space: nowrap; }
}
.dropdown-panel > * + .dropdown-group { margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px solid var(--color-border); }

/* Флажок (Checkbox) — один на систему: Dropdown с мультивыбором, галочки
   источников. Квадрат 20×20 вместе с обводкой (как иконка), радиус --radius-xs.
   Не отмечен — белый с серой обводкой 2px (--color-border), при наведении на
   родителя обводка темнеет (--color-muted); отмечен — синий с белой галочкой,
   частично — синий с белым тире (обводка того же синего — размер тот же).
   В выключенной кнопке приглушён: пустой — светлая обводка
   --color-border-soft, отмеченный — --color-ink-disabled. */
.checkbox {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 20px;
  height: 20px;
  border: 2px solid var(--color-border);
  border-radius: var(--radius-xs);
  background: var(--color-surface);
  transition: background-color var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out);
}
.checkbox .material-symbols-rounded { color: transparent; }
.checkbox:not([data-state="off"]) { background: var(--color-brand); border-color: var(--color-brand); }
.checkbox:not([data-state="off"]) .material-symbols-rounded { color: var(--color-surface); }
:not(:disabled):hover > .checkbox[data-state="off"]:not([data-disabled]),
:focus-visible > .checkbox[data-state="off"] { border-color: var(--color-muted); }
:disabled > .checkbox[data-state="off"],
.checkbox[data-disabled][data-state="off"] { border-color: var(--color-border-soft); }
:disabled > .checkbox:not([data-state="off"]),
.checkbox[data-disabled]:not([data-state="off"]) { background: var(--color-ink-disabled); border-color: transparent; }
/* Флажок с подписью (Checkbox с label) — флажок формы: кнопка role="checkbox", флажок
   на уровне первой строки подписи, подпись — основной текст. Наведение и фокус —
   правила флажка выше (рамка темнеет), фокус ещё и обводкой всей кнопки. */
.checkbox-field {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 24px;
  color: var(--color-ink);
}
.checkbox-field > .checkbox { margin-top: 2px; }
.checkbox-field:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; border-radius: var(--radius-xs); }
.checkbox-field:disabled { cursor: default; color: var(--color-muted); }

/* Сообщение со следующим шагом (Callout). Тон — цвет иконки и её круга. */
.callout {
  --callout-color: var(--color-brand);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}
.callout--floating { box-shadow: 0 var(--space-2) calc(var(--space-4) * 2) calc(var(--space-2) * -1) var(--color-overlay-24); }
.callout[data-tone="success"] { --callout-color: var(--color-type-games); }
.callout[data-tone="warning"] { --callout-color: var(--color-type-cinema); }
.callout[data-tone="danger"] { --callout-color: var(--color-danger); }
.callout-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--callout-color);
  background: color-mix(in srgb, var(--callout-color) 12%, transparent);
}
.callout-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.callout-title { font-family: var(--font-alt); font-size: var(--text-base); font-weight: var(--weight-bold); line-height: 24px; color: var(--color-ink); }
.callout-text { font-family: var(--font-body); font-size: var(--text-sm); line-height: 20px; color: var(--color-ink-secondary); }
.callout-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
@media (max-width: 720px) {
  .callout { flex-wrap: wrap; padding: var(--space-4); }
  .callout-actions { flex-basis: 100%; }
}

/* Баннер выбора cookie (CookieBanner): Callout floating поверх страницы внизу по центру —
   над «Наверх» (900) и нижней панелью меню, под уведомлениями (1100). Только раскладка. */
.cookie-banner {
  position: fixed;
  left: 50%;
  bottom: var(--space-6);
  z-index: 1000;
  width: min(var(--banner-width), calc(100vw - var(--space-6) * 2));
  transform: translateX(-50%);
}
.cookie-banner[hidden] { display: none; }
.cookie-banner .callout-actions { flex-wrap: nowrap; }
.cookie-banner.is-inline { position: static; width: auto; transform: none; }
@media (max-width: 767px) {
  .cookie-banner {
    left: var(--space-mobile);
    right: var(--space-mobile);
    bottom: calc(var(--bottom-nav-offset, 0px) + var(--space-mobile) + env(safe-area-inset-bottom, 0px));
    width: auto;
    transform: none;
  }
  .cookie-banner.is-inline { left: auto; right: auto; }
  .cookie-banner .callout-actions { flex-wrap: wrap; }
  .cookie-banner .callout-actions > .btn { flex: 1 1 auto; }
}

/* Уведомление об итоге нажатия (Toast, Iwent.toast): тёмная плашка, радиус
   как у кнопок; иконка цвета тона, текст по левому краю, справа «Закрыть» —
   .gallery-btn (иконочная кнопка на тёмном). Стоит в .toast-region: справа
   сверху под шапкой, поверх страницы, вёрстку не сдвигает; одно за раз. */
.toast {
  --toast-color: var(--color-type-games);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  max-width: var(--toast-max-width);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-ink);
  color: var(--color-surface);
  box-shadow: 0 var(--space-2) calc(var(--space-4) * 2) calc(var(--space-2) * -1) var(--color-overlay-24);
}
.toast[data-tone="danger"] { --toast-color: var(--color-danger); }
.toast-icon { flex: 0 0 auto; display: inline-flex; }
.toast-icon .material-symbols-rounded { color: var(--toast-color); }
.toast-text {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  text-align: left;
  overflow-wrap: anywhere;
}
.toast-region {
  position: fixed;
  top: calc(var(--header-height) + var(--space-4));
  right: var(--space-6);
  left: var(--space-6);
  z-index: 1100;
  display: flex;
  justify-content: flex-end;
  pointer-events: none;
}
.toast-region > .toast { pointer-events: auto; animation: toast-in var(--duration-base) var(--ease-out); }
.toast-region > .toast.is-leaving { animation: toast-out var(--duration-base) var(--ease-in) forwards; }
/* Иконка успеха «щёлкает» пружиной, как галочка в кнопке (Button state done). */
.toast-region > .toast[data-tone="success"] .toast-icon .material-symbols-rounded { animation: iwent-pop var(--duration-slow) var(--ease-spring); }
/* Сдвиг появления: на десктопе сверху вниз, на телефоне снизу вверх. */
.toast-region { --toast-shift: calc(var(--space-4) * -1); }
@keyframes toast-in { from { opacity: 0; transform: translateY(var(--toast-shift)); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(var(--toast-shift)); } }
@media (prefers-reduced-motion: reduce) {
  .toast-region > .toast,
  .toast-region > .toast.is-leaving { animation: none; }
}
@media (max-width: 767px) {
  /* Телефон: внизу экрана, во всю ширину между полями страницы, над вырезом
     (safe-area) и над нижней панелью меню (--bottom-nav-offset — его ставит
     sidebar.css, пока панель есть; нет панели — 0). */
  .toast-region {
    top: auto;
    bottom: calc(var(--bottom-nav-offset, 0px) + var(--space-mobile) + env(safe-area-inset-bottom, 0px));
    right: var(--space-mobile);
    left: var(--space-mobile);
    --toast-shift: var(--space-4);
  }
  .toast-region > .toast { flex: 1 1 auto; max-width: none; }
}

/* Раскрывающийся блок: технический лог и прочее второстепенное. */
.disclosure { border-radius: var(--radius-xl); background: var(--color-surface); }
.disclosure-summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  font-family: var(--font-alt);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  line-height: 24px;
  color: var(--color-ink);
  cursor: pointer;
  list-style: none;
}
.disclosure-summary::-webkit-details-marker { display: none; }
.disclosure-summary:hover { color: var(--color-brand); }
.disclosure-summary .material-symbols-rounded { transition: transform var(--duration-base) var(--ease-in-out); }
.disclosure[open] > .disclosure-summary .material-symbols-rounded { transform: rotate(90deg); }
.disclosure-meta { font-weight: var(--weight-regular); font-size: var(--text-sm); color: var(--color-ink-secondary); }
.disclosure-body { padding: 0 var(--space-6) var(--space-6); }
/* Тело проявляется и гаснет (высота не анимируется); без поддержки ::details-content — сразу. */
@supports selector(::details-content) {
  .disclosure::details-content {
    opacity: 0;
    transition: opacity var(--duration-base) var(--ease-in), content-visibility var(--duration-base) allow-discrete;
  }
  .disclosure[open]::details-content { opacity: 1; transition-timing-function: var(--ease-out); }
}

/* Шапка служебной страницы: заголовок и сведения слева, действия справа. */
.page-header { display: flex; flex-direction: column; gap: var(--space-4); }
/* BackButton: «← Назад» своей строкой над шапкой страницы; сама кнопка —
   FilterButton. Отступ до шапки — как в макете: 24px, на телефоне 20px. */
.back-row { display: flex; margin-bottom: var(--space-6); }
@media (max-width: 767px) {
  .back-row { margin-bottom: var(--space-mobile); }
}
.page-header-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4); }
.page-header-titles { min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.page-header-title-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.page-header-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  line-height: 32px;
  color: var(--color-ink);
}
/* Часть заголовка ссылкой (PageHeader title массивом: тема, событие, человек на странице группы ленты) — как название
   карточки ссылкой (a.event-title): цвет текста, без подчёркивания, наведение и фокус — бренд, кольцо фокуса. */
.page-header-title a { color: inherit; text-decoration: none; transition: color var(--duration-base) var(--ease-out); }
.page-header-title a:is(:hover, :focus-visible) { color: var(--color-brand); }
.page-header-title a:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }
.page-header-meta,
.modal-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); font-family: var(--font-body); font-size: var(--text-sm); line-height: 20px; color: var(--color-ink-secondary); }
/* Части строки сведений разделяет TagDot — как теги, цвета самой строки. */
.page-header-meta .event-tag-dot,
.modal-meta .event-tag-dot { background: currentColor; }
.page-header-actions { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-2); }
/* Десктоп: действия всегда справа от заголовка, и при длинном названии (оно переносится,
   кнопки не уходят вниз). На телефоне — ниже во всю ширину, как было. */
@media (min-width: 768px) {
  .page-header-row { flex-wrap: nowrap; }
  .page-header-titles { flex: 1 1 auto; }
  .page-header-actions { flex: none; flex-wrap: nowrap; }
}
/* Телефон: хвост заголовка (titleTail) и строка сведений без metaPhone скрыты — заголовок в две строки,
   первая карточка ленты в пределах первого экрана. */
@media (max-width: 767px) {
  .page-header-title-tail,
  .page-header-meta--desktop { display: none; }
}
/* Ход сбора — белая карточка с полосой. */
.run-progress { padding: var(--space-4) var(--space-6); border-radius: var(--radius-xl); background: var(--color-surface); }

/* События сбора (RunEvents) — белая карточка: вкладки по исходу и выбор
   источника, ниже списки по источникам серыми строками. */
.run-events {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-6);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
}
.run-events-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.run-events .tabs { flex-wrap: wrap; }
.run-events-toolbar .dropdown-trigger { min-width: 240px; }
.run-events-group { display: flex; flex-direction: column; gap: var(--space-2); }
.run-events-source {
  margin: 0;
  padding-left: var(--space-3);
  font-family: var(--font-alt);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  line-height: 24px;
  color: var(--color-ink);
}
.run-events-list { display: flex; flex-direction: column; }
.run-events .show-more-container { padding: 0; }

/* Событие сбора: дата колонкой слева — как день в календаре, — дальше
   название и место, справа причина отказа и ссылка на источник. */
.run-event {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 52px;
  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);
  border-radius: var(--radius-md);
  transition: background-color var(--duration-base) var(--ease-out);
}
.run-event:hover { background: var(--color-hover); }
.run-event-when {
  flex: 0 0 120px;
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink);
}
.run-event-time { font-weight: var(--weight-regular); font-size: var(--text-xs); line-height: 16px; color: var(--color-ink-secondary); }
.run-event-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.run-event-title {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink);
  overflow-wrap: anywhere;
}
.run-event-title a { color: inherit; text-decoration: none; }
.run-event-title a:hover { color: var(--color-brand); }
.run-event-meta,
.run-event-note { font-family: var(--font-body); font-size: var(--text-xs); line-height: 16px; color: var(--color-ink-secondary); overflow-wrap: anywhere; }
.run-event-note { color: var(--color-ink); }
.run-event-note.is-error { color: var(--color-danger); }
.run-event-links { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-1); }
.run-event .btn { border-color: transparent; color: var(--color-ink-secondary); }
@media (max-width: 720px) {
  .run-event { flex-wrap: wrap; }
  .run-event-when { flex-basis: 100%; flex-direction: row; gap: var(--space-2); }
  .run-events-toolbar .dropdown { flex-basis: 100%; }
}

/* ---------- Мобильная версия (≤ 767px): выпадающий список ----------
   Как выбор месяца в календаре: шторка снизу поверх затемнения. */
@media (max-width: 767px) {
  .dropdown-panel {
    position: fixed;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    max-width: none;
    max-height: 70vh;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    /* Текст пунктов — по полю страницы (8 + 12 = 20) и в 32 от верха, как
       раньше; плашки — в 8 от краёв экрана. */
    padding: var(--space-6) var(--space-2) calc(var(--space-4) + env(safe-area-inset-bottom));
    z-index: 1000;
    /* Шторка: выезд снизу и уход вниз; затемнение — тень, её цвет проявляется вместе. */
    opacity: 1;
    transform: translateY(100%);
    box-shadow: 0 0 0 100vmax transparent;
    transition: transform var(--duration-base) var(--ease-in), box-shadow var(--duration-base) var(--ease-in),
      display var(--duration-base) allow-discrete;
  }
  .dropdown.open .dropdown-panel {
    transform: none;
    box-shadow: 0 0 0 100vmax var(--color-overlay-24);
    transition: transform var(--duration-slow) var(--ease-out), box-shadow var(--duration-slow) var(--ease-out),
      display var(--duration-slow) allow-discrete;
  }
  @starting-style {
    .dropdown.open .dropdown-panel, .dropdown.is-up.open .dropdown-panel { opacity: 1; transform: translateY(100%); box-shadow: 0 0 0 100vmax transparent; }
  }
  .dropdown.is-up .dropdown-panel { transform: translateY(100%); }
  .dropdown.is-up.open .dropdown-panel { transform: none; }
  /* Прозрачная подложка на весь экран: затемнение — тень, сквозь неё страница
     ловила бы наведение и клики. Клик по ней закрывает список (initDropdowns). */
  .dropdown-panel::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
  }
  .dropdown-panel::before {
    content: '';
    position: absolute;
    top: var(--space-2);
    left: 50%;
    width: 40px;
    height: 4px;
    margin-left: -20px;
    border-radius: var(--radius-pill);
    background: var(--color-border);
  }
  .dropdown.is-right .dropdown-panel { left: 0; right: 0; }
  .modal .dropdown-panel { max-height: 70vh; }
  .dropdown.is-up .dropdown-panel { top: auto; bottom: 0; }
  .dropdown-trigger { width: 100%; }
  /* Ряд TypePick: списки друг под другом во всю ширину — в ряд на 335px
     подписи («Все подкатегории») обрезались бы; «Сбросить» — своей строкой,
     по своей ширине. */
  .type-pick { flex-direction: column; align-items: stretch; }
  .type-pick > [data-action="reset"],
  .type-pick > [data-lead] { align-self: flex-start; }
  /* Пилюли категорий листаются до края экрана, как ряд дат (filters.css): строка
     ряда не шире колонки, иначе она растягивает страницу вбок. */
  .type-pick > .filters { max-width: calc(100% + var(--space-mobile)); }
  /* Два ряда: от пилюль категорий до списков второго ряда — 16 (8 ряда и 8 сверху). */
  .type-pick--rows > .filters:not([data-filter-group="pick-quick"]) + * { margin-top: var(--space-2); }
  /* Ряд с порядком (rows): корень не рамка, как на десктопе. Категории — первой строкой
     (листаются), «Расширенные фильтры» (иконка + число) и порядок — второй, в одну строку. */
  .type-pick--rows { display: contents; }
  .type-pick--rows > .filters { flex: 0 0 calc(100% + var(--space-mobile)); min-width: 0; }
  .type-pick--rows > .filters + * { margin-top: 0; }
}

/* ---------- Выбор города (CityPicker) — в шапке, когда городов больше одного ----------
   Кнопка — само название города (вид .city: Montserrat 14 жирный), без стрелки; наведение
   и фокус — синий, как у ссылки-понятия (.concept-tag:hover). Область нажатия 44: поля со
   встречным отрицательным отступом, раскладка на месте (как у логотипа на телефоне).
   Панель — как выбор месяца календаря (.calendar-month-picker): белая, радиус 24, тень
   --shadow-panel, пункты — плашки 8/12 с радиусом 12, наведение и фокус — фон --color-hover
   и синий, выбранный приглушён. Заголовка и линии нет: сетка поднята на 8 — текст пунктов в
   24 от верха и боков, снизу 12 + 8 = 20, как у месяца. Три колонки, названия в одну строку;
   длинные раздвигают панель шире --city-picker-width. Левый край панели — у разделителя
   шапки (корень стоит в 16 от него, header.css). Поведение — Iwent.initCityPicker. */
.city-picker {
  position: relative;
  display: flex;
  align-items: center;
}

.city-picker-trigger {
  padding: var(--space-3) 0;
  margin: calc(-1 * var(--space-3)) 0;
  border: 0;
  background: transparent;
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--duration-base) var(--ease-out);
}

.city-picker-trigger:hover,
.city-picker-trigger.is-hover,
.city-picker-trigger:focus-visible { color: var(--color-brand); }
.city-picker-trigger:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }

.city-picker-panel {
  display: none;
  position: absolute;
  top: calc(100% + var(--space-2));
  left: calc(-1 * var(--space-4));
  z-index: 100;
  width: max-content;
  min-width: var(--city-picker-width);
  padding: var(--space-6) var(--space-6) var(--space-3);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-panel);
}

.city-picker.open .city-picker-panel { display: block; }

.city-picker-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(max-content, 1fr));
  gap: var(--space-2) 0;
  margin: calc(-1 * var(--space-2)) calc(-1 * var(--space-3)) 0;
}

.city-picker-item {
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  text-align: left;
  white-space: nowrap;
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink);
  cursor: pointer;
  transition: color var(--duration-base) var(--ease-out), background-color var(--duration-base) var(--ease-out);
}

.city-picker-item:hover,
.city-picker-item:focus-visible { background: var(--color-hover); outline: none; }
.city-picker-item:not(.active):hover,
.city-picker-item:focus-visible { color: var(--color-brand); }
/* Выбранный — приглушён, как открытый месяц (там opacity 0.24 у текста — тот же цвет). */
.city-picker-item.active { color: var(--color-ink-disabled); cursor: default; pointer-events: none; }

/* Телефон: шторка снизу поверх затемнения, как выбор месяца; две колонки, длинное
   название переносится. Текст — в 24 от верха, по полю страницы сбоку (20 − 12 + 12),
   в 24 от низа (16 + 8). Клик по затемнению — target = панель, закрывает Iwent.initCityPicker. */
@media (max-width: 767px) {
  .city-picker { min-width: 0; }
  .city-picker-trigger {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .city-picker-panel {
    position: fixed;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    min-width: 0;
    max-height: 85vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    padding: var(--space-6) var(--space-mobile) calc(var(--space-4) + env(safe-area-inset-bottom));
    box-shadow: 0 0 0 100vmax var(--color-overlay-24);
    z-index: 1000;
  }
  .city-picker-panel::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
  }
  .city-picker-panel::before {
    content: '';
    position: absolute;
    top: var(--space-2);
    left: 50%;
    width: calc(var(--space-8) + var(--space-2));
    height: var(--space-1);
    transform: translateX(-50%);
    border-radius: var(--radius-pill);
    background: var(--color-border);
  }
  .city-picker-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .city-picker-item { white-space: normal; }
}

/* Полка «Ещё про …» (ConceptShelf) — слайдер «Похожих событий» со счётчиком
   и ссылкой «Все» на страницу понятия. Сам слайдер — стили similar-events. */
/* «Все» (у полки и у «Похожих событий») стоит в ряду стрелок с тем же
   шагом, что между ними (gap 8px у .similar-events-nav) — своего отступа
   у неё нет. */
.similar-events-nav:has(> .btn) { align-items: center; }
/* На телефоне стрелок слайдера нет (листается пальцем), а «Все» нужна —
   иначе со страницы события дальше не попасть. */
@media (max-width: 767px) {
  .similar-events-nav:has(> .btn) { display: flex; }
  .similar-events-nav:has(> .btn) .similar-events-btn { display: none; }
}

/* Счётчик «• 16» (Count) — после подписи чипа, вкладки, заголовка полки.
   Один вид везде: Montserrat 14 жирный, серый; цвет не меняется ни при
   наведении на кнопку, ни у выбранной вкладки — число лишь подсказывает.
   Точка — TagDot, отступы по 8px, как между тегами; цвета числа. */
.count {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-ink-secondary);
  white-space: nowrap;
}

/* TagDot внутри строки текста (счётчик, итог и настройки источника):
   по 8px с боков, как между тегами, цвета текста строки. */
/* На синей главной кнопке серый не читается — счётчик цвета подписи. */
.btn-primary .count { color: inherit; }

.count .event-tag-dot,
.source-status-text .event-tag-dot,
.source-row-config .event-tag-dot {
  vertical-align: middle;
  margin: 0 var(--space-2);
  background: currentColor;
}

/* Название в карточке — ссылка на событие (CardTitle с href, ui.eventHref):
   для поисковика это настоящая <a href>, на вид — то же название. Цвет и
   наведение задают правила карточек (.event-title в events.css и
   event-detail.css): наведение на название — это наведение на карточку,
   поэтому в их :has(a:hover) название исключено. :where — без специфичности:
   цвет из правил карточки сильнее, а стиль ссылки браузера слабее любого нашего. */
:where(a.event-title, a.recommended-title, a.calendar-day-ad-title) {
  color: inherit;
  text-decoration: none;
}
:is(a.event-title, a.recommended-title, a.calendar-day-ad-title):focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
}

/* Ссылки внутри карточек событий (TagList и DatePlace с href, Iwent.cardLinks):
   тег — на понятие, дата — на свой день, площадка — на её страницу. В покое
   выглядят как обычные тег и плашка — без подчёркивания и синевы ссылки.
   Наведение — как у кнопки: рамка пропадает; на светлой карточке фон
   --color-hover и синий текст (.btn:hover), на цветной панели и фото
   (filled, priority, main) — заливка цветом рамки, как у плашек героя.
   Только внутри карточек (:where — без прибавки специфичности): без этого
   color: inherit перебивал белую плашку места в герое страницы события, и
   место-ссылка там чернело. */
:where(.event-card-standard, .similar-event-card) :is(a.event-tag, a.event-date, a.event-location, .event-date-part) {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out), color var(--duration-base) var(--ease-out), opacity var(--duration-base) var(--ease-out);
}

/* Плашки даты и места у RecommendedEventCard (одинарная карточка активности, рекомендация под героем,
   «Ближайшее из подписок») — ссылки со своим цветом плашки, без подчёркивания; наведение — как у плашек
   карточек ниже: на светлой — --color-hover и синий текст, на залитой (filled) — заливка цветом рамки. */
:where(.event-card-standard, .recommended-event-card) :is(a.recommended-location, a.recommended-datetime, .recommended-datetime .event-date-part) {
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out), color var(--duration-base) var(--ease-out);
}

:is(.event-card-standard, .similar-event-card, .recommended-event-card) :is(a.event-date, a.event-location, a.recommended-location, a.recommended-datetime, .event-date-part):is(:hover, :focus-visible) {
  background: var(--color-hover);
  border-color: transparent;
  color: var(--color-brand);
}

/* Плашка из частей (диапазон, серия «· ещё N дат»): при наведении на часть общая рамка
   пропадает, как у плашки места; заливается наведённая часть. */
:is(.event-card-standard, .similar-event-card, .recommended-event-card) :is(.event-date, .recommended-datetime).is-split:has(.event-date-part:is(:hover, :focus-visible)) {
  border-color: transparent;
}

:is(.event-card-standard, .similar-event-card) a.event-tag:is(:hover, :focus-visible) {
  color: var(--color-brand);
}

/* Наведение на цветной подложке — одно для плашек и кнопок с обводкой (.btn-hero-outline): белый 24%. */
:is(.event-card-standard.event-card-filled, .recommended-event-card--filled) :is(a.event-date, a.event-location, a.recommended-location, a.recommended-datetime, .event-date-part):is(:hover, :focus-visible) {
  background: var(--color-on-dark-24);
  border-color: transparent;
  color: var(--color-surface);
}

:is(.event-card-standard.event-card-filled, .recommended-event-card--filled) :is(.event-date, .recommended-datetime).is-split:has(.event-date-part:is(:hover, :focus-visible)) {
  border-color: transparent;
}

.event-card-standard.event-card-filled a.event-tag:is(:hover, :focus-visible) {
  color: var(--color-surface);
}

/* Тег-ссылка в герое события («Сериал», EventHero с serialHref): вид тега героя
   (--color-on-dark-80), без подчёркивания; при наведении — белый 100%, как тег в цветной карточке. */
:where(.event-hero) a.event-tag { text-decoration: none; transition: color var(--duration-base) var(--ease-out); }
:where(.event-hero) a.event-tag:is(:hover, :focus-visible) { color: var(--color-surface); }

:where(.event-card-standard, .similar-event-card, .recommended-event-card) :is(a.event-tag, a.event-date, a.event-location, a.recommended-location, a.recommended-datetime, .event-date-part):focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
}

/* Телефон: область нажатия ссылок карточки — не меньше 44 (--control-height), вид прежний.
   Теги — поля со встречным отрицательным отступом (раскладка на месте). Плашки даты и места
   обрезают содержимое (многоточие), область за их краем не нажимается — тут вид прежний. */
@media (max-width: 767px) {
  :where(.event-card-standard, .event-card-priority, .event-card-priority-vertical, .event-card-main, .similar-event-card) a.event-tag {
    padding-block: var(--space-3);
    margin-block: calc(-1 * var(--space-3));
  }
  /* Ряд тегов обрезает только по ширине (одна строка): по высоте поля тегов — их область нажатия. */
  :is(.event-card-standard, .event-card-priority, .event-card-priority-vertical, .event-card-main, .similar-event-card) .event-tags {
    overflow-x: clip;
    overflow-y: visible;
  }
}

/* ---------- Список событий: EventGrid layout: 'list' + EventCard layout: 'row' ----------
   Строка — та же простая карточка (standard / filled / bordered): фон, рамка и
   цвета от неё (events.css). Размеры на всех ширинах — как у мобильной
   карточки (мобильный блок events.css): поля --space-mobile, аватарка 64px
   (бейдж — как у всех карточек, -4px от края, events.css), 16px до заголовка, заголовок без верхнего отступа и в две
   строки, теги одной строкой. Снимков в строке нет — забирали внимание. Здесь только
   раскладка строки во всю ширину: аватарка, заголовок с тегами, дата и место. */
.events.events--list {
  grid-template-columns: 1fr;
  grid-template-rows: none;
  grid-auto-rows: auto;
  gap: var(--space-4);
}

/* Заголовок месяца в архиве («Прошедшие», feed.js) — DetailTitle между строками.
   Внешнее больше внутреннего: от строк до заголовка 32 (gap 16 + 16), от
   заголовка до его строк — только gap 16; своё поле снизу у DetailTitle снято. */
.events--list > .event-detail-title { margin: var(--space-4) 0 0; }
.events--list > .event-detail-title:first-child { margin-top: 0; }

/* Заглушки списка — строки: высота строки с аватаркой 64px и полями 20px. */
.events.events--list > .show-skeleton {
  height: calc(64px + 2 * var(--space-mobile));
  border-radius: var(--radius-lg);
}

.event-card-standard.event-card-row {
  height: auto;
  /* Скругление — как у карточек «Похожих событий» (24px), а не 32px ленты. */
  border-radius: var(--radius-lg);
  padding: var(--space-mobile);
  display: flex;
  align-items: center;
  /* Между аватаркой, текстом, плашками и снимком — столько же, сколько поле карточки. */
  gap: var(--space-mobile);
}

.event-card-row .event-avatar { width: 64px; height: 64px; flex-shrink: 0; }
.event-row-main { flex: 1; min-width: 0; }
.event-card-row .event-title { margin-top: 0; -webkit-line-clamp: 2; }
.event-card-row .event-tags { margin-bottom: 0; }
/* Описание строки (EventCard text — дайджест в Telegram): текст карточки, второстепенным цветом, до 4 строк. */
.event-row-text {
  margin: var(--space-2) 0 0;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1.43;
  color: var(--color-ink-secondary);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.event-card-filled .event-row-text { color: var(--color-on-dark-80); }
/* EventCard avatar: 'large' — круглая аватарка вдвое крупнее (--row-avatar-lg) для строки с описанием (дайджест в Telegram). */
.event-card-row--avatar-lg .event-avatar { width: var(--row-avatar-lg); height: var(--row-avatar-lg); }
/* Дата и место — справа от заголовка, перед снимком, всегда друг под другом
   и по правому краю. Им не больше 40% строки — главное в строке заголовок:
   длинное место обрезается многоточием (Iwent.clampLocation), дата остаётся целой. */
.event-card-row .event-place {
  flex: 0 1 auto;
  max-width: 40%;
  flex-direction: column;
  align-items: flex-end;
}
/* В столбике плашка не сжимается сама: без предела длинное место вылезало
   за край карточки. Не шире колонки — дальше многоточие. */
.event-card-row .event-place > * { max-width: 100%; }

/* Телефон: аватарка и заголовок, ниже — дата и место. */
@media (max-width: 767px) {
  /* Аватарка — у заголовка, как в мобильной карточке, а не по центру колонки с плашками. */
  .event-card-standard.event-card-row { flex-wrap: wrap; align-items: flex-start; }

  .event-card-row .event-row-main { flex-basis: calc(100% - 64px - var(--space-mobile)); }
  .event-card-row--avatar-lg .event-row-main { flex-basis: calc(100% - var(--row-avatar-lg) - var(--space-mobile)); }
  /* Вторая строка: дата и место слева, в одну линию; не влезают — место переносится под дату. */
  .event-card-row .event-place {
    flex: 1 1 0;
    flex-direction: row;
    flex-wrap: wrap;
    max-width: none;
    align-items: flex-start;
    margin-top: 0; /* до первой строки — gap строки, а не отступ мобильной карточки */
  }

}

/* ---------- «Как добраться» (VenueAddress) ----------
   Заголовок, адрес и ссылка — DetailTitle, EventExtraInfo и Button со своим
   видом; здесь только отступы внутри блока. Внешнее больше внутреннего
   (docs/design-system.md): между блоками страницы 32, внутри — 16, как у
   «Событий»: заголовок → адрес (поле DetailTitle, своё 24 у EventExtraInfo
   снято — оно для правой колонки события), адрес → кнопка. */
.venue-address .event-extra-info {
  margin-top: 0;
}

/* Второй ряд пар («Цена», «Возраст» у события) — через 24, как пары между собой
   и ряды «Дата» → «Жанр» в правой колонке события. */
.venue-address .event-extra-info + .event-extra-info {
  margin-top: var(--space-6);
}

.venue-address-actions {
  margin-top: var(--space-4);
}

/* ---------- Аватарка человека (UserAvatar) и он в шапке (HeaderAccount) ----------
   Круг в кольце цвета человека — категории (--event-type-color от data-type, как у
   аватарки события; UserAvatar color), без неё — бренд; буква имени — тот же слой
   .event-avatar-letter, что у событий, того же цвета. Фото лежит над буквой. */
.user-avatar:not([data-type]),
.user-avatar-level:not([data-type]) { --event-type-color: var(--color-brand); }
.user-avatar {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
  width: var(--user-avatar-size, 40px);
  height: var(--user-avatar-size, 40px);
  border-radius: 50%;
  border: 3px solid var(--event-type-color); /* как у аватарки события (.event-avatar) */
  background: var(--color-surface);
  box-sizing: border-box;
  overflow: hidden;
  isolation: isolate; /* z-index фото — внутри круга: иначе фото ложится поверх кружка уровня (.user-avatar-level) */
}
.user-avatar-image {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: 50%;
  background-size: cover;
  background-position: center;
}
/* shape 'square' — тема в шапке записи ленты (ActivityCard source): квадрат со скруглением, остальное — как у круга. */
.user-avatar--square, .user-avatar-link--square { border-radius: var(--radius-md); }
/* Слои внутри квадрата — внутренний радиус (радиус минус обводка 3px): иначе на залитой карточке, где буква
   на цветной подложке, внутренний угол круглее, чем на белой. */
.user-avatar--square .user-avatar-image, .user-avatar--square .event-avatar-letter { border-radius: calc(var(--radius-md) - 3px); }
/* icon — значок действия вместо буквы (UserAvatar icon, «Оцените событие» — звезда): круг как у буквы — белый с цветным
   значком цвета категории; на залитой карточке круг тоже белый (обводка белая), значок цветной. Значок — половина диаметра, залитый. */
.user-avatar-icon .material-symbols-rounded { --icon-size: calc(var(--user-avatar-size, 40px) / 2); --icon-weight: var(--icon-weight-state); }
/* Значок (UserAvatar icon) — заливкой: на белой и с рамкой круг цвета категории с белым значком; на залитой —
   наоборот, белый круг с цветным значком. */
.user-avatar:has(> .user-avatar-icon) { background: var(--event-type-color, var(--color-brand)); }
.event-avatar-letter.user-avatar-icon { background: var(--event-type-color, var(--color-brand)); color: var(--color-surface); }
.activity-card.event-card-filled .user-avatar:has(> .user-avatar-icon) { background: var(--color-surface); border-color: var(--color-surface); }
.activity-card.event-card-filled .event-avatar-letter.user-avatar-icon { background: var(--color-surface); color: var(--event-type-color, var(--color-brand)); }

.header-user {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--color-ink);
}
.header-user-text { display: flex; flex-direction: column; min-width: 0; }
.header-user-name {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
  transition: color var(--duration-base) var(--ease-out);
}
.header-user-sub {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: 16px;
  color: var(--color-ink-secondary);
}
.header-user:hover .header-user-name,
.header-user:focus-visible .header-user-name { color: var(--color-brand); }

/* «Создать событие» в шапке вошедшего — слева от аватарки, отступ 24
   (12 — gap шапки, 12 — свой): кнопка и аватарка — разные действия. */
.header-create { margin-right: var(--space-3); }

/* Телефон: в шапке только аватарка; создать событие — из профиля. */
@media (max-width: 767px) {
  .header-user-text { display: none; }
  .header-create { display: none; }
}

/* Стопка аватарок людей (UserAvatarStack): внахлёст, как аватарки событий в
   ячейке календаря; «+N» — кружок того же размера. */
/* Стопка — как аватарки событий в ячейке календаря (.calendar-day-events):
   у каждой обводка 3px цветом подложки (--stack-bg), следующая заходит на
   предыдущую на треть (буква в аватарке без фото остаётся видна); «+N» — кружок того же размера, залитый цветом
   подложки, тёмные цифры Montserrat 12 (как .event-counter календаря). */
.user-avatar-stack { --stack-bg: var(--color-surface); display: inline-flex; align-items: center; flex-shrink: 0; }
.user-avatar-stack > .user-avatar,
.user-avatar-stack > .user-avatar-link > .user-avatar { box-shadow: 0 0 0 3px var(--stack-bg); }
.user-avatar-stack > :is(.user-avatar, .user-avatar-link):not(:first-child) { margin-left: calc(var(--user-avatar-size) / -3); }
/* spread — рядом без наложения и выреза, через 8. */
.user-avatar-stack--spread { gap: var(--space-2); }
.user-avatar-stack--spread > :is(.user-avatar, .user-avatar-link):not(:first-child) { margin-left: 0; }
/* Подпись рядом с аватаркой (UserAvatarStack note: оценка человека группы) — жирное число 14/20 через 8, цветом текста;
   между людьми с подписью — 16 (внешнее больше внутреннего). Кружок на аватарке — только уровень. */
.user-avatar-stack--spread:has(> .user-avatar-noted) { gap: var(--space-4); }
.user-avatar-noted { display: inline-flex; align-items: center; gap: var(--space-2); }
.user-avatar-note { font-family: var(--font-body); font-size: var(--text-sm); line-height: 20px; font-weight: var(--weight-bold); color: var(--color-ink); }
.activity-card.event-card-filled .user-avatar-note { color: var(--color-surface); }
/* «Идут из ваших подписок» на карточке события (EventGoing): стопка 32 и подпись серым 14/20 через 8; в карточке —
   16 под датой и местом (в строке списка — 8 под тегами). На залитой и стеклянной панели — подпись --color-on-dark-80,
   обводка аватарок и «+N» — цветом категории (подложка карточки). */
.event-going { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.event-going-text { min-width: 0; font-family: var(--font-body); font-size: var(--text-sm); line-height: 20px; color: var(--color-ink-secondary); }
.event-card-standard > .event-going,
.priority-panel > .event-going { margin-top: var(--space-4); }
.event-row-main > .event-going { margin-top: var(--space-2); }
.event-card-filled .event-going-text { color: var(--color-on-dark-80); }
.event-card-filled .event-going .user-avatar-stack { --stack-bg: var(--event-type-color, var(--color-brand)); }
.event-card-variant .event-going .user-avatar-stack { --stack-bg: transparent; }
/* Аватарка ссылкой на профиль (UserAvatar href): своего вида нет, фокус с клавиатуры — кольцо бренда по кругу. */
.user-avatar-link { display: inline-flex; flex-shrink: 0; border-radius: var(--radius-pill); }
.user-avatar-link:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }
.user-avatar-more {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: var(--user-avatar-size);
  padding: 0 var(--space-1);
  border-color: var(--stack-bg);
  border-radius: var(--radius-pill);
  background: var(--stack-bg);
  font-family: var(--font-alt);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 16px;
  color: var(--color-ink);
}

/* ---------- Кнопка-переключатель и главная кнопка героя ----------
   is-pressed — нажатая («Вы подписаны», «Вы следите»): тёмная (--color-ink) с белым,
   одна на всех — у события, человека и понятия, на светлой странице и на подложке героя.
   hero — главное действие на цветной подложке героя события («Подписаться»): на всю
   ширину (btn-full), белая с синим, без рамки — читается на любой из девяти
   подложек, в том числе светлых art и city. Наведение — как у кнопок ДС
   (.btn:hover, фон --color-hover и синий текст): у белой кнопки это непрозрачный
   --color-bg, иначе сквозь кнопку проступила бы подложка. Нажатая («Вы подписаны»)
   — тёмная с белым: отличается от «Подписаться» с первого взгляда. Как любая нажатая,
   на наведение не меняется. */
.btn.is-pressed,
.btn.is-pressed:hover:not(:disabled) {
  background: var(--color-ink);
  border-color: transparent;
  color: var(--color-surface);
}
/* Две подписи переключателя (Button labelPressed): в одной ячейке сетки, видна одна —
   ширина по длинной, при нажатии не прыгает; смена — проявлением. Скрытая —
   visibility: hidden, чтец её не читает. */
.btn-swap { display: inline-grid; justify-items: center; }
.btn-swap > * {
  grid-area: 1 / 1;
  transition: opacity var(--duration-base) var(--ease-out), visibility var(--duration-base);
}
.btn:not([aria-pressed="true"]) .btn-swap-on,
.btn[aria-pressed="true"] .btn-swap-off { opacity: 0; visibility: hidden; }

/* Ответ сервера на нажатие (Button state, Iwent.buttonAction). busy — на месте
   иконки крутится progress_activity (подпись и ширина те же, aria-busy, не disabled);
   done — итоговая иконка «щёлкает» пружиной; error — кнопка коротко вздрагивает,
   итог говорит Toast. При «меньше движения» — без вращения, пружины и тряски:
   на месте иконки статичные песочные часы (hourglass_empty, ставит buttonAction). */
.btn[data-state="busy"] { cursor: progress; }
.btn[data-state="busy"] > .material-symbols-rounded {
  animation: iwent-fade-in var(--duration-fast) var(--ease-out), iwent-spin var(--duration-spin) linear infinite;
}
.btn[data-state="done"] > .material-symbols-rounded { animation: iwent-pop var(--duration-slow) var(--ease-spring); }
.btn[data-state="error"] { animation: iwent-shake var(--duration-slow) var(--ease-in-out); }
@keyframes iwent-fade-in { from { opacity: 0; } }
@keyframes iwent-spin { to { transform: rotate(1turn); } }
@keyframes iwent-pop { from { opacity: 0; transform: scale(0.5); } }
@keyframes iwent-shake {
  20%, 60% { transform: translateX(calc(var(--space-1) * -1)); }
  40%, 80% { transform: translateX(var(--space-1)); }
}
@media (prefers-reduced-motion: reduce) {
  .btn[data-state] > .material-symbols-rounded,
  .btn[data-state="error"] { animation: none; }
}
.motion-reduce .btn[data-state] > .material-symbols-rounded,
.motion-reduce .btn[data-state="error"] { animation: none; }

.btn-hero {
  background: var(--color-surface);
  border-color: transparent;
  color: var(--color-brand);
}
.btn-hero:hover:not(:disabled):not([aria-disabled="true"]):not(.is-pressed),
.btn-hero.is-hover {
  background: var(--color-bg);
  border-color: transparent;
  color: var(--color-brand);
}

/* Второе действие героя (Button 'hero-outline', «Купить билет» и др.): прозрачная, белый
   текст и тонкая рамка --color-on-dark-32, как плашки даты и «Прошло» на подложке.
   Наведение — подложка --color-on-dark-24 (как у плашек даты и места на цветной), рамка уходит. */
.btn-hero-outline {
  background: transparent;
  border-color: var(--color-on-dark-32);
  color: var(--color-surface);
}
.btn-hero-outline:hover:not(:disabled):not([aria-disabled="true"]),
.btn-hero-outline.is-hover {
  background: var(--color-on-dark-24);
  border-color: transparent;
  color: var(--color-surface);
}
/* Выключенная на подложке героя («Прошло» на месте «Купить билет»): вид disabled ДС —
   приглушённый текст и бледная рамка, — только в светлых тонах тёмной подложки. */
.btn-hero-outline:disabled,
.btn-hero-outline[aria-disabled="true"] {
  border-color: var(--color-on-dark-12);
  color: var(--color-on-dark-32);
}
/* «Прошло» (EventActions у прошедшего события) — текст и значок на 50% ярче обычной выключенной:
   на белом --color-ink-past (36%), на цветной подложке --color-on-dark-48. */
.btn-past:is(:disabled, [aria-disabled="true"]),
.btn-past:is(:disabled, [aria-disabled="true"]) .material-symbols-rounded { color: var(--color-ink-past); }
.btn-hero-outline.btn-past:is(:disabled, [aria-disabled="true"]),
.btn-hero-outline.btn-past:is(:disabled, [aria-disabled="true"]) .material-symbols-rounded { color: var(--color-on-dark-48); }

/* «Подписаться» в герое события (EventWait): только кнопка, 24 от плашек даты и места.
   Кто подписан — счётчики в теле события (StatList layout 'spread'). */
.event-wait {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: var(--space-6);
}

/* Действия героя (EventActions): 24 от плашек даты и места (DateTimeLocation). «Подписаться» —
   во всю ширину, «Добавить в календарь» — квадрат hero-outline 46×46, как «Поделиться»,
   третьим во втором ряду (12 + иконка 20 + 12 + рамка), через 8. Одна кнопка
   календаря (публичная версия) — во всю ширину. Обёртка .calendar-add (кнопка и
   её окно) своего блока не даёт: кнопка встаёт прямо в ряд. */
.event-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-6);
}
.event-actions > .event-wait { flex: 1; min-width: 0; margin-top: 0; }
/* «Прошло» под тегами в герое (EventHero, event.past) — до действий, как они. */
.calendar-add { display: contents; }
.event-actions .calendar-add .btn-icon { padding: var(--space-3); }
/* Ряд «Купить билет» + «Поделиться» (EventActions): во всю ширину героя, через 8.
   «Поделиться» (EventShare) — квадрат hero-outline той же высоты (46), «Купить
   билет» тянется на остальную ширину; без неё — квадрат один. */
.event-actions-row { display: flex; gap: var(--space-2); width: 100%; }
.event-actions-row > .btn-hero-outline.btn-icon,
.event-actions-row > .calendar-add > .btn-hero-outline.btn-icon { width: auto; flex: none; padding: var(--space-3); }
.event-actions-row > .btn-hero-outline:not(.btn-icon) { flex: 1 1 auto; width: auto; min-width: 0; }
/* «Позвать» (EventShare invite, «Пойдём вместе») — справа от «Подписаться» в той же строке, через 8,
   по ширине подписи; «Подписаться» тянется на остальное. */
.event-actions > .btn-hero-outline.event-invite { flex: none; width: auto; }
.calendar-add-options > [hidden] { display: none; }

/* Оценка прошедшего события (RatingPick): десять ячеек-цифр в одной рамке той же формы и высоты,
   что hero-outline (1 + 12 + 20 + 12 + 1 = 46). Наведение подсвечивает ячейки от первой до
   наведённой (дальше — без подсветки), выбранная — залита (белая, синяя цифра), до неё —
   подсвечены. is-hover — то же наведение для каталога. В герое — вариант prominent (ниже).
   Средняя у не подписанного (RatingSummary) — строкой тегов над рядом: 8 + 8 = 16 до него. */
.event-actions > .event-rating-summary { width: 100%; margin-bottom: var(--space-2); }
.event-rating-summary > .event-tags { margin: 0; }
.event-actions-row > .rating-pick { flex: 1 1 auto; min-width: 0; }
.rating-pick {
  display: flex;
  border: 1px solid var(--color-on-dark-32);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.rating-pick-item {
  flex: 1 1 0;
  min-width: 0;
  padding: var(--space-3) 0;
  border: 0;
  background: transparent;
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: 20px;
  color: var(--color-surface);
  cursor: pointer;
  transition: var(--transition-colors);
}
.rating-pick-item:focus-visible { outline: 2px solid var(--color-surface); outline-offset: -2px; }
.rating-pick:has(.rating-pick-item:hover) .rating-pick-item,
.rating-pick-item.is-in,
.rating-pick-item.is-hover { background: var(--color-on-dark-24); }
.rating-pick:has(.rating-pick-item:hover) .rating-pick-item:hover ~ .rating-pick-item:not(.is-pressed),
.rating-pick:has(.is-hover) .rating-pick-item:not(.is-hover):not(.is-pressed) { background: transparent; }
.rating-pick .rating-pick-item.is-pressed[aria-pressed] { background: var(--color-surface); color: var(--color-brand); }
.rating-pick .rating-pick-item:is(:hover, .is-hover):not(.is-pressed) { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
/* На светлой подложке — вид ДС по умолчанию: рамка --color-border, подсветка --color-hover,
   выбранная — --color-ink с белой цифрой, как нажатая кнопка. */
.rating-pick--light { border-color: var(--color-border); }
.rating-pick--light .rating-pick-item { color: var(--color-ink); }
.rating-pick--light .rating-pick-item:focus-visible { outline-color: var(--color-brand); }
.rating-pick--light:has(.rating-pick-item:hover) .rating-pick-item,
.rating-pick--light .rating-pick-item.is-in,
.rating-pick--light .rating-pick-item.is-hover { background: var(--color-hover); }
.rating-pick--light:has(.rating-pick-item:hover) .rating-pick-item:hover ~ .rating-pick-item:not(.is-pressed),
.rating-pick--light:has(.is-hover) .rating-pick-item:not(.is-hover):not(.is-pressed) { background: transparent; }
.rating-pick--light .rating-pick-item.is-pressed[aria-pressed] { background: var(--color-ink); color: var(--color-surface); }
/* Вариант героя (RatingPick prominent): отдельный блок под рядом «Прошло» + «Поделиться» —
   8 (gap ряда) + 16 = 24 от него, во всю ширину; подпись (RatingSummary) над шкалой через 16.
   Шкала — на белой подложке, как «Подписаться» (btn-hero): цифры цветом категории, подсветка до
   наведённой — он же 12%, выбранная — залита им с белой цифрой. Рамки нет нигде. */
.event-actions > .rating-pick-block { width: 100%; margin-top: var(--space-4); }
.rating-pick-block { display: flex; flex-direction: column; gap: var(--space-4); }
.rating-pick--prominent { background: var(--color-surface); border-color: transparent; }
/* Без рамки (как «Подписаться» на цветном герое): белая подложка; где фон сам белый (обычная карточка ленты,
   светлый герой не в карточке с рамкой) — подложка цвета фона страницы. */
.rating-pick--prominent.rating-pick--light { border-color: transparent; }
.activity-card:not(.event-card-bordered, .event-card-filled) .rating-pick--prominent,
.event-hero[data-tone="light"]:not(.activity-card.event-card-bordered .event-hero) .rating-pick--prominent { background: var(--color-bg); }
.rating-pick--prominent .rating-pick-item { color: var(--event-type-color, var(--color-brand)); }
.rating-pick--prominent .rating-pick-item:focus-visible { outline-color: var(--event-type-color, var(--color-brand)); }
.rating-pick--prominent:has(.rating-pick-item:hover) .rating-pick-item,
.rating-pick--prominent .rating-pick-item.is-in,
.rating-pick--prominent .rating-pick-item.is-hover { background: color-mix(in srgb, var(--event-type-color, var(--color-brand)) 12%, transparent); }
.rating-pick--prominent:has(.rating-pick-item:hover) .rating-pick-item:hover ~ .rating-pick-item:not(.is-pressed),
.rating-pick--prominent:has(.is-hover) .rating-pick-item:not(.is-hover):not(.is-pressed) { background: transparent; }
.rating-pick--prominent .rating-pick-item.is-pressed[aria-pressed] { background: var(--event-type-color, var(--color-brand)); color: var(--color-surface); }
/* Выбранная ячейка — скруглённой плашкой (--radius-sm, на 4 меньше рамки шкалы), а не прямоугольником во всю высоту:
   плашка — слой ::before, под её левой половиной — подсветка оценок ниже (is-in): на стыке с ней нет белых уголков,
   а справа, где оценки выше не подсвечены, уголки — цвета шкалы.
   У подсветки до наведённой — скруглён правый край (ниже). */
.rating-pick.rating-pick .rating-pick-item.is-pressed[aria-pressed] { position: relative; z-index: 0; background: transparent; }
.rating-pick .rating-pick-item.is-pressed[aria-pressed]::before { content: ''; position: absolute; inset: 0; z-index: -1; border-radius: var(--radius-sm); background: var(--color-surface); }
.rating-pick--prominent .rating-pick-item.is-pressed[aria-pressed]::before { background: var(--event-type-color, var(--color-brand)); }
.rating-pick.rating-pick .rating-pick-item.is-in + .rating-pick-item.is-pressed[aria-pressed] { background: linear-gradient(to right, var(--color-on-dark-24) 50%, transparent 50%); }
.rating-pick.rating-pick--prominent .rating-pick-item.is-in + .rating-pick-item.is-pressed[aria-pressed] { background: linear-gradient(to right, color-mix(in srgb, var(--event-type-color, var(--color-brand)) 12%, transparent) 50%, transparent 50%); }
/* Ответ на нажатие (Iwent.buttonAction на ячейке): ждём — цифра мерцает, готово — «щелчок»
   пружиной, ошибка — тряска (итог говорит Toast); при «меньше движения» — без анимации. */
.rating-pick-item[data-state="busy"] { cursor: progress; animation: iwent-fade-in var(--duration-slow) var(--ease-in-out) infinite alternate; }
.rating-pick-item[data-state="done"] { animation: iwent-pop var(--duration-slow) var(--ease-spring); }
.rating-pick-item[data-state="error"] { animation: iwent-shake var(--duration-slow) var(--ease-in-out); }
@media (prefers-reduced-motion: reduce) {
  .rating-pick-item[data-state] { animation: none; }
}
.motion-reduce .rating-pick-item[data-state] { animation: none; }

/* «Поделиться» (EventShare): знаки сервисов — один ряд во всю ширину окна, кнопки делят её поровну через 8. */
.share-services { display: flex; gap: var(--space-2); }
.share-services > .btn { flex: 1 1 0; width: auto; min-width: 0; padding: var(--space-3); } /* высота 46 — как у «Скопировать ссылку» */

/* «Добавить в календарь» в окне (CalendarAdd): варианты — кнопки во всю
   ширину через 8; под последней — поле окна. */
.calendar-add-options { display: flex; flex-direction: column; gap: var(--space-2); }
/* У серии над вариантами — выбор показа (чипсы в ChoiceGroup или Dropdown inline), до них 16. */
.calendar-add .modal-body > :is(.dropdown, .settings-group) + .calendar-add-options { margin-top: var(--space-4); }
/* «Добавить в список» (Iwent.initUserLists): флажки списков → «Новый список» и флажок «Открыт по
   ссылке» → «Создать список» — 16 (группы), внутри групп — 8, как варианты окна. */
.calendar-add-options > [data-part="lists"]:not([hidden]),
.calendar-add-options > .checkbox-field:has(+ .btn) { margin-bottom: var(--space-2); }
/* Чипсы показов переносятся строками и на телефоне (обычно ряд фильтров там листается лентой). */
@media (max-width: 767px) {
  .calendar-add .modal-body > .settings-group > .filters { flex-wrap: wrap; overflow: visible; margin-right: 0; padding-right: 0; }
}

/* Все даты серии в окне (SeriesDates): список текстом — не ссылки и не кнопки,
   в две колонки (на телефоне — в одну), строки 24 через 8, колонки через 24;
   прошедшие — серым. Длинный список прокручивается сам, шапка окна стоит. */
.series-dates {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2) var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: min(52vh, 440px);
  overflow-y: auto;
}
.series-date {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 24px;
  color: var(--color-ink);
}
.series-date.is-past { color: var(--color-muted); }
@media (max-width: 767px) {
  .series-dates { grid-template-columns: minmax(0, 1fr); max-height: 52vh; }
}

/* Ссылка «ещё» (MoreLink): «Узнать больше» у описания, «ещё 7 дат» у даты серии.
   Синий текст Onest 16/24, без подчёркивания и в покое, и при наведении; у кнопки
   (открывает окно) — без рамки и фона. Где стоит — решает место (display не задан). */
.more-link {
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 24px;
  color: var(--color-brand);
  text-decoration: none;
  text-align: left;
  cursor: pointer;
}
.more-link:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }

/* ---------- Модальное окно (Modal, нативный <dialog>) ----------
   Белая панель как у Dropdown: радиус --radius-xl, поле 24, тень панелей;
   затемнение — ::backdrop. Ширина — --modal-width (узкое — --modal-width-sm),
   не шире экрана без 16 с каждой стороны. Сброс base.css обнуляет margin, а
   модальный dialog центрируется именно через margin: auto. Шапка: заголовок
   (Unbounded 18) и крестик в одну линию; сведения и тело — ниже. На телефоне — шторка снизу, как у Dropdown: во всю ширину,
   скруглена сверху, поле снизу 24 над safe-area. */
.modal {
  margin: auto;
  width: min(var(--modal-width), calc(100vw - 2 * var(--space-4)));
  max-height: calc(100vh - 2 * var(--space-4));
  border: 0;
  border-radius: var(--radius-xl);
  /* Воздух: поля и отступы внутри — в полтора раза больше обычных (36 / 24 / 36). */
  padding: calc(var(--space-6) * 1.5);
  background: var(--color-surface);
  color: var(--color-ink);
  box-shadow: var(--shadow-panel);
}
.modal--small { width: min(var(--modal-width-sm), calc(100vw - 2 * var(--space-4))); }
/* Появление и уход: окно проявляется с подъёмом и лёгким масштабом (slow, out), затемнение —
   только opacity; закрытие — быстрее и обратно (base, in). Закрытое состояние — без [open],
   display и overlay (верхний слой) переходят вместе (allow-discrete): окно не исчезает рывком.
   Окно «в потоке» (Modal open в каталоге, не :modal) не анимируется. */
.modal:not([open]) {
  opacity: 0;
  transform: translateY(var(--space-3)) scale(0.98);
}
.modal {
  transition: opacity var(--duration-base) var(--ease-in), transform var(--duration-base) var(--ease-in),
    overlay var(--duration-base) allow-discrete, display var(--duration-base) allow-discrete;
}
.modal[open] {
  opacity: 1;
  transform: none;
  transition: opacity var(--duration-slow) var(--ease-out), transform var(--duration-slow) var(--ease-out),
    overlay var(--duration-slow) allow-discrete, display var(--duration-slow) allow-discrete;
}
@starting-style {
  .modal[open]:modal { opacity: 0; transform: translateY(var(--space-3)) scale(0.98); }
}
.modal::backdrop {
  background: var(--color-backdrop);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-in), overlay var(--duration-base) allow-discrete,
    display var(--duration-base) allow-discrete;
}
.modal[open]::backdrop {
  opacity: 1;
  transition: opacity var(--duration-slow) var(--ease-out), overlay var(--duration-slow) allow-discrete,
    display var(--duration-slow) allow-discrete;
}
@starting-style {
  .modal[open]:modal::backdrop { opacity: 0; }
}
/* Открыто не поверх страницы, а в потоке (каталог, Modal({ open: true })). */
.modal[open]:not(:modal) { position: static; margin: 0; }
.modal-head { display: flex; align-items: center; gap: var(--space-3); }
/* Крестик (46) выше строки заголовка (24): без поправки он раздувал шапку, и
   сведения вставали в 27 от текста, а не в 16. Отрицательные поля по 12 сверху
   и снизу — крестик по центру строки и не выше её. */
.modal-head > .btn-icon { margin-block: calc(-1 * var(--space-3)); }
.modal-title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  line-height: 24px;
  color: var(--color-ink);
}
.modal-meta:empty { display: none; }
/* Сведения под шапкой (lead и meta): через 16 от заголовка, между собой 8.
   lead — главное тёмным, как значение в EventExtraInfo (Onest 16/24); строки
   meta с иконкой — серые Onest 14/20, иконка 20 стоит по первой строке текста. */
.modal-info { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-6); }
.modal-lead { font-family: var(--font-body); font-size: var(--text-base); line-height: 24px; color: var(--color-ink); overflow-wrap: anywhere; }
.modal-meta-row { display: flex; align-items: flex-start; gap: var(--space-2); font-family: var(--font-body); font-size: var(--text-sm); line-height: 20px; color: var(--color-ink-secondary); }
.modal-meta-row > .material-symbols-rounded { flex-shrink: 0; }
/* Длинное без пробелов (ссылка-приглашение в окне «Позвать с собой») переносится в любом месте. */
.modal-meta-row > span { min-width: 0; overflow-wrap: anywhere; }
.modal-body { margin-top: calc(var(--space-6) * 1.5); }
@media (max-width: 767px) {
  .modal,
  .modal--small {
    margin: auto 0 0;
    width: 100%;
    max-width: 100%;
    max-height: 85vh;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    padding: var(--space-6) var(--space-mobile) calc(var(--space-6) + env(safe-area-inset-bottom));
  }
  /* Шторка прокручивается сама, не страница под ней (Iwent.initScrollLock). */
  .modal,
  .dropdown-panel,
  .calendar-month-picker,
  .gallery { overscroll-behavior: contain; }
  .modal { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  /* Шторка: выезжает снизу и уходит вниз (затемнение проявляется отдельно). */
  .modal:not([open]) { opacity: 1; transform: translateY(100%); }
  @starting-style {
    .modal[open]:modal { opacity: 1; transform: translateY(100%); }
  }
  html.is-scroll-locked,
  html.is-scroll-locked body { overflow: hidden; }
  /* На телефоне — прежние отступы: экран узкий. */
  .modal-info { margin-top: var(--space-4); }
  .modal-body { margin-top: var(--space-6); }
}

/* ---------- Строка списка (ListRow): люди, лента, заявки на события ----------
   Вид — как у строки события в списке (.event-card-row): белая, радиус 24,
   поля и промежутки 20. Список строк — EventGrid layout 'list' (шаг 16). */
.list-row {
  display: flex;
  align-items: center;
  gap: var(--space-mobile);
  padding: var(--space-mobile);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  min-width: 0;
}
.list-row-lead { flex-shrink: 0; display: flex; }
.list-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.list-row-aside { flex-shrink: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--space-2); }
.list-row-title {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 24px;
  color: var(--color-ink);
  overflow-wrap: anywhere;
}
.list-row-title :is(a, strong) {
  font-weight: var(--weight-bold);
  color: var(--color-ink);
  text-decoration: none;
  transition: color var(--duration-base) var(--ease-out);
}
.list-row-title a:is(:hover, :focus-visible) { color: var(--color-brand); }
.list-row-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 20px;
  color: var(--color-ink-secondary);
}
.list-row-meta .event-tag-dot { background: var(--color-ink); } /* точка сплошная, как у тегов карточки события */
.list-row-note { font-family: var(--font-body); font-size: var(--text-sm); line-height: 20px; color: var(--color-danger); }
/* Аватарка категории у заявки — как у строки события, 64px. */
.list-row .event-avatar { width: 64px; height: 64px; }

/* ---------- Аватарка с уровнем (UserAvatar level) ----------
   Уровень — кружок на краю аватарки, как бейдж категории у события, без обводки. */
.user-avatar-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
/* Размер — от диаметра аватарки (--user-avatar-size на обёртке, UserAvatar): половина, но не больше 32 (--space-8):
   у 64 — 32, как бейдж категории у аватарки события; у 48 — 24; у 96 и 128 — 32. Кегль (12 = --text-xs при 32),
   поля (8) и вылет за край (4) — в той же доле. */
.user-avatar-level {
  --level-size: min(calc(var(--user-avatar-size, 64px) / 2), var(--space-8));
  --level-out: calc(var(--level-size) / 8);
  position: absolute;
  right: calc(var(--level-out) * -1);
  bottom: calc(var(--level-out) * -1);
  min-width: var(--level-size);
  height: var(--level-size);
  padding: 0 calc(var(--level-size) / 4);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  border-radius: var(--radius-pill);
  background: var(--event-type-color); /* цвет человека, как кольцо (UserAvatar color) */
  color: var(--color-surface);
  font-family: var(--font-alt);
  font-size: calc(var(--level-size) * 3 / 8);
  font-weight: var(--weight-bold);
}

/* ---------- Счётчики профиля (StatList) ---------- */
.stat-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-8);
  margin: 0;
}
.stat { display: flex; flex-direction: column-reverse; gap: var(--space-1); }
.stat-value {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  line-height: 32px;
  color: var(--color-ink);
}
.stat-label { font-family: var(--font-body); font-size: var(--text-sm); line-height: 20px; color: var(--color-ink-secondary); }
/* layout 'spread' — счётчики в теле события: белая плашка, как плитка
   достижения (поле 20, радиус 24), колонки поровну, текст по центру. */
.stat-list--spread {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-mobile);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}
.stat-list--spread .stat { align-items: center; text-align: center; min-width: 0; }
/* Пункты по верху: числа в одну линию, подпись в две строки уходит вниз (column-reverse: flex-end — верх). */
.stat-list--spread .stat:not(:has(> .stat-people)) { justify-content: flex-end; }
/* Кто подписан (StatList item.people) — стопка в одной строке с числом, справа от него (32 — высота строки
   числа), подпись под ними; разметка та же (dt, dd число, dd стопка) — раскладка сеткой. */
.stat-people { display: flex; margin: 0; }
.stat:has(> .stat-people) {
  display: grid;
  grid-template-columns: auto auto;
  grid-template-areas: "value people" "label label";
  align-items: center;
  align-content: start;
  justify-content: start;
  column-gap: var(--space-2);
  row-gap: var(--space-1);
}
.stat:has(> .stat-people) > .stat-value { grid-area: value; }
.stat:has(> .stat-people) > .stat-people { grid-area: people; }
.stat:has(> .stat-people) > .stat-label { grid-area: label; }
.stat-list--spread .stat:has(> .stat-people) { justify-content: center; }
/* Призыв вместо нуля (item.action) — маленькая кнопка (32px) на месте числа. */
.stat-value--action { display: flex; align-items: center; min-height: 32px; }
/* Пункт-ссылка (item.href): число и стопка — одна ссылка, стопка справа через 8 (как в сетке выше);
   наведение — как у ссылок ДС: число брендом. Подпись ссылкой не становится. */
.stat-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-sm);
}
.stat-number { transition: color var(--duration-base) var(--ease-out); }
.stat-link:is(:hover, :focus-visible, .is-hover) .stat-number { color: var(--color-brand); }
.stat-link:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }

/* ---------- Уровень и опыт (ProfileLevel) ---------- */
.profile-level { display: flex; flex-direction: column; gap: var(--space-2); }
/* Со счётчиками (stats) — одна белая плашка: поле и радиус как у других плашек,
   Divider между полосой и счётчиками (16 сверху и снизу), у StatList своей плашки нет. */
.profile-level--card { gap: 0; padding: var(--space-mobile); border-radius: var(--radius-lg); background: var(--color-surface); }
.profile-level--card .list-row-meta { margin-top: var(--space-2); }
.profile-level--card .event-detail-divider { margin: var(--space-4) 0; }
.profile-level--card .stat-list--spread { padding: 0; border-radius: 0; background: none; }
.profile-level .progress-label {
  font-family: var(--font-alt);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--color-ink);
}

/* Достижение (AchievementBadge) — карточка новостей: белая, залитая или с обводкой по колоде
   новостей, цвет — тип достижения (заливка и обводка — его цвет, как категория у события). Медаль на месте аватарки: круг цвета типа (--event-type-color от [data-type],
   общие — бренд) с белой иконкой и тонким кольцом того же цвета через белый зазор — как значок
   категории у аватарки, только крупно. Внизу — плашки DatePlace («Получено …», редкость).
   Карточка не ссылка — без наведения. */
/* Цвет без типа — бренд, «не ссылка» и заливка/обводка цветом — общие с лентой активности (ActivityCard ниже). */
:is(.achievement, .activity-card) { --achievement-color: var(--event-type-color, var(--color-brand)); cursor: default; }
.event-card-standard:is(.achievement, .activity-card):hover { box-shadow: none; }
/* Курсор — обычный и у вариантов: .event-card-standard.event-card-filled (рука карточки ленты) специфичнее :is() выше.
   Рука — только у кликабельной: со стикером ([data-sticker-card] ниже), новость (data-kind="news"). */
.event-card-standard:is(.achievement, .activity-card) { cursor: default; }
/* Карточка не ссылка — общее наведение карточек ленты (тень, название бледнеет/синеет) не срабатывает и у залитой;
   наведение — только у ссылок внутри (свои правила). */
.event-card-standard.event-card-filled:is(.achievement, .activity-card):hover { box-shadow: none; }
.event-card-standard:is(.achievement, .activity-card):hover :is(.news-body, .activity-card-body) > .event-title:not(a) { color: var(--color-ink); }
.event-card-standard.event-card-filled:is(.achievement, .activity-card):hover :is(.news-body, .activity-card-body) > .event-title:not(a) { color: var(--color-surface); }
.event-card-standard:is(.achievement, .activity-card):hover .activity-card-body > a.event-title:not(:hover, :focus-visible) { color: var(--color-ink); }
.event-card-standard.event-card-filled:is(.achievement, .activity-card):hover .activity-card-body > a.event-title:not(:hover, :focus-visible) { color: var(--color-surface); }
.event-card-standard:is(.achievement, .activity-card).event-card-filled { background: var(--achievement-color); }
.event-card-standard:is(.achievement, .activity-card).event-card-bordered { border-color: var(--achievement-color); }
.event-card-standard.event-card-filled:is(.achievement, .activity-card) :is(.event-title, .news-lead) { color: var(--color-surface); }
.achievement-medal {
  --medal: var(--space-16);
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--medal);
  height: var(--medal);
  margin: var(--space-1);
  border-radius: 50%;
  background: var(--achievement-color);
  box-shadow: 0 0 0 var(--avatar-cut) var(--color-surface), 0 0 0 calc(var(--avatar-cut) * 2) var(--achievement-color);
  color: var(--color-surface);
}
/* На залитой карточке медаль белая с иконкой цвета типа, кольцо — белое через зазор цвета карточки. */
.event-card-filled .achievement-medal { background: var(--color-surface); color: var(--achievement-color); box-shadow: 0 0 0 var(--avatar-cut) var(--achievement-color), 0 0 0 calc(var(--avatar-cut) * 2) var(--color-surface); }
.achievement-medal .material-symbols-rounded { --icon-size: calc(var(--medal) / 2); --icon-weight: var(--icon-weight-state); }
/* Широкая — той же высоты, что обычная: медаль как у аватарки события (80); вертикальная — крупная. */
.news-card--wide .achievement-medal { --medal: calc(var(--space-16) + var(--space-4)); }
.news-card--tall .achievement-medal { --medal: var(--icon-hero-lg); }
/* Стикер (Sticker): высота 96, ширина по форме — во flex не сжимается и не растягивается. */
.sticker { flex: none; display: block; align-self: flex-start; width: auto; height: var(--sticker-height); max-width: 100%; object-fit: contain; object-position: left center; }
/* Наклон за мышью (Iwent.stickerTilt): наклоняемый стикер (open, large) — обёртка span.sticker--tilt
   с картинкой; углы — --tilt-x / --tilt-y от скрипта; пока мышь двигается — быстро вслед (fast),
   на уходе — плавно в ноль (slow). «Меньше движения» и сенсорные — без поворота и блика
   (скрипт не ставит углы, здесь — страховка). */
.sticker--tilt {
  position: relative;
  isolation: isolate;
  transform: perspective(var(--sticker-perspective)) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  scale: var(--sticker-scale, 1);
  transition: transform var(--duration-slow) var(--ease-out), scale var(--duration-slow) var(--ease-out);
}
.sticker--tilt > img { display: block; width: auto; height: inherit; max-width: 100%; object-fit: contain; }
/* Подъём в карточке (мышь на карточке — .sticker--tilting, не в окне): крупнее на --sticker-lift-scale и
   мягкая тень по форме стикера. Тень — копия картинки под ней: белый контур --sticker-lift-outline (цепочка
   drop-shadow в 4 стороны — по форме), от него drop-shadow (--sticker-lift-shadow); появляется прозрачностью:
   анимируются только transform и opacity. */
.sticker--tilt::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: -1;
  background: var(--sticker-mask, none) center / contain no-repeat;
  filter:
    drop-shadow(var(--sticker-lift-outline) 0 0 var(--color-surface))
    drop-shadow(calc(-1 * var(--sticker-lift-outline)) 0 0 var(--color-surface))
    drop-shadow(0 var(--sticker-lift-outline) 0 var(--color-surface))
    drop-shadow(0 calc(-1 * var(--sticker-lift-outline)) 0 var(--color-surface))
    drop-shadow(var(--sticker-lift-shadow));
  opacity: 0;
  transition: opacity var(--duration-slow) var(--ease-out);
}
.sticker--tilting:not(.sticker--large) { --sticker-scale: var(--sticker-lift-scale); }
.sticker--tilting:not(.sticker--large)::before { opacity: 1; }
/* Блик: слой по форме стикера (маска — сама картинка, --sticker-mask), в нём мягкое световое пятно
   (screen — только светлит, цвета не грязнит). Пятно смещается против наклона (--glare-x / -y,
   −1…1 → до половины стикера), сила — от угла (--glare 0…1) × --sticker-glare (в окне — -xl);
   в покое 0. Двигаются только transform и opacity, темп — как у поворота. */
.sticker-glare {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  mix-blend-mode: screen;
  -webkit-mask: var(--sticker-mask, none) center / contain no-repeat;
  mask: var(--sticker-mask, none) center / contain no-repeat;
  opacity: calc(var(--glare, 0) * var(--sticker-glare));
  transition: opacity var(--duration-slow) var(--ease-out);
}
.sticker-glare::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(closest-side, var(--sticker-glare-color), transparent);
  transform: translate(calc(var(--glare-x, 0) * 50%), calc(var(--glare-y, 0) * 50%)) scale(var(--sticker-glare-size));
  transition: transform var(--duration-slow) var(--ease-out);
}
.sticker--large .sticker-glare { opacity: calc(var(--glare, 0) * var(--sticker-glare-xl)); }
.sticker--tilting .sticker-glare, .sticker--tilting .sticker-glare::before { transition-duration: var(--duration-fast); }
/* Вслед за мышью — быстро (fast); подъём (масштаб, тень) — плавно, за base. */
.sticker--tilting { transition: transform var(--duration-fast) var(--ease-out), scale var(--duration-base) var(--ease-out); }
.sticker--tilting::before { transition-duration: var(--duration-base); }
@media (prefers-reduced-motion: reduce), (hover: none) {
  .sticker--tilt { transform: none; scale: none; }
  .sticker-glare, .sticker--tilt::before { display: none; }
}
:root.motion-reduce .sticker--tilt { transform: none; scale: none; }
:root.motion-reduce .sticker-glare, :root.motion-reduce .sticker--tilt::before { display: none; }
/* Стикер, открывающий окно (Sticker open) и карточка с ним: курсор — рука; фокус — синяя обводка. */
.sticker[data-action="sticker-open"], [data-sticker-card], .event-card-standard[data-sticker-card] { cursor: pointer; }
.sticker[data-action="sticker-open"]:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; border-radius: var(--radius-sm); }
/* Окно стикера (StickerModal): стикер крупно по центру, под ним через 24 — за что, по центру;
   тема ссылкой — как причина стикера в карточке ленты активности (жирная, цвет текста, наведение — бренд). */
.sticker--large { align-self: center; height: var(--sticker-height-xl); object-position: center; }
.sticker-modal { display: flex; flex-direction: column; align-items: center; gap: var(--space-6); text-align: center; }
/* Текст не обрезается посреди строки: название — до двух строк, «за что» — до двух. */
.achievement .news-body { flex: none; }
.achievement .event-title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.achievement .news-lead { -webkit-line-clamp: 2; }
/* Обычная (квадрат) достижения и активности — второстепенный текст мельче: 14/20, как теги карточки события. */
:is(.achievement, .activity-card):not(.news-card--wide, .news-card--tall) .news-lead { font-size: var(--text-sm); line-height: 20px; }
.achievement .event-place { margin-top: auto; }
/* Квадратная карточка достижения: с названием, «за что» или полосой ступени 96 не помещается (на 1280 и уже) — стикер 64, как в ленте. */
.achievement:not(.news-card--wide, .news-card--tall) .sticker { height: var(--sticker-height-mobile); }
/* Узкий десктоп (768–1439): ряд ниже — в квадрате «за что» одной строкой, в широкой стикер 64. */
@media (min-width: 768px) and (max-width: 1439px) {
  .achievement:not(.news-card--wide, .news-card--tall) .news-lead { -webkit-line-clamp: 1; }
  .achievement.news-card--wide .sticker { height: var(--sticker-height-mobile); }
}
/* Ступень категории: медаль и плашка «3 из 4» — одним рядом (плашка справа, по верху);
   полоса до следующей — внизу, цвета типа; на залитой — белая по полупрозрачной белой
   дорожке, подписи белые. */
.achievement-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-2); }
.achievement .achievement-head .event-place { margin-top: 0; }
.achievement .progress { --progress-color: var(--achievement-color); margin-top: auto; }
.event-card-filled.achievement .progress { --progress-color: var(--color-surface); }
.event-card-filled.achievement .progress-track { background: var(--color-on-dark-32); }
/* С обводкой карточка цвета страницы — дорожка белая, иначе её не видно. */
.event-card-bordered.achievement .progress-track { background: var(--color-surface); }
/* Квадратная карточка на компьютере: медаль, название и полоса — «за что» не помещается
   (число есть в счёте полосы). В широкой, вертикальной и на телефоне (высота по содержимому) — есть. */
.achievement:not(.news-card--wide, .news-card--tall):has(.progress) .news-lead { display: none; }
.event-card-filled.achievement :is(.progress-label, .progress-count) { color: var(--color-surface); }

/* ---------- Лента активности (ActivityCard, ActivityList) ----------
   Действие человека в профиле — карточка той же системы, что новости и достижения: вид,
   размер, сетка, цвет без типа (бренд) и «не ссылка» — правила выше. Здесь только своё:
   шапка — строка списка (ListRow) без своей плашки: аватарка 40, текст действия 14/20 до
   четырёх строк и время; ниже — что получено, по центру оставшейся высоты. Карточка события
   (RecommendedEventCard) и человек (PersonRow) — на белой карточке серой подложкой (как в
   светлом герое), на залитой и с рамкой — белые. Двойная горизонтальная — шапка слева, что
   получено — справа. */
.activity-card { justify-content: flex-start; }
/* Уровень на аватарке человека — как бейдж категории у аватарки события в той же карточке:
   тот же размер и вылет (бейдж события считает от внутреннего края кольца — на толщину кольца ближе). */
.activity-card .user-avatar-level { right: calc(3px - var(--level-out)); bottom: calc(3px - var(--level-out)); }
.activity-card > .list-row { flex: none; align-items: flex-start; gap: var(--space-3); padding: 0; border-radius: 0; background: none; }
.activity-card > .list-row .list-row-main { gap: 0; }
.activity-card > .list-row .list-row-title { font-size: var(--text-sm); line-height: 20px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; overflow: hidden; }
.activity-card-body { flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: var(--space-2); text-align: left; }
.activity-card-body > :is(.recommended-event-card, .list-row) { align-self: stretch; text-align: left; }
/* Человек — поля и промежуток карточки события (16 и 12), чтобы вместе с шапкой влез в квадрат. */
/* Человек (подписка, «добавил в друзья») — как событие в карточке (RecommendedEventCard): без своей подложки,
   аватарка 64 с кружком уровня, 12 до текста; имя — как название события (Unbounded 12/16 жирный), строка
   «титул • Друзья» — как теги (Onest 12/16, --color-ink-secondary, точка сплошная; на залитой — --color-on-dark-80, точка белая). */
.activity-card-body > .list-row { gap: var(--space-3); padding: 0; background: none; border-radius: 0; }
.activity-card-body > .list-row .list-row-title,
.activity-card-body > .list-row .list-row-title a { font-family: var(--font-display); font-size: var(--text-xs); line-height: var(--space-4); font-weight: var(--weight-bold); }
.activity-card-body > .list-row .list-row-title { margin-bottom: var(--space-1); }
.activity-card-body > .list-row .list-row-meta { font-size: var(--text-xs); line-height: var(--space-4); }
.activity-card.event-card-filled .activity-card-body > .list-row :is(.list-row-title, .list-row-title a) { color: var(--color-surface); }
.activity-card.event-card-filled .activity-card-body > .list-row .list-row-meta { color: var(--color-on-dark-80); }
.activity-card.event-card-filled .activity-card-body > .list-row .list-row-meta .event-tag-dot { background: var(--color-surface); }
/* Обводка аватарки человека на залитой — белая: в строке (PersonRow) и в карточке ленты широкой (EventCard avatar). */
.activity-card.event-card-filled .activity-card-body > :is(.list-row, .event-card-standard) .user-avatar { border-color: var(--color-surface); }
/* В обычной (квадрат) — сразу под разделителем, как событие. */
.activity-card:not(.news-card--wide, .news-card--tall) .activity-card-body:has(> .list-row) { justify-content: flex-start; }
/* Событие внутри карточки ленты — без своей подложки: фон общий с карточкой. На залитой карточке
   текст и обводка аватарки белые, как у самой карточки. */
.activity-card .activity-card-body > .recommended-event-card { background: none; }
.activity-card .activity-card-body > .recommended-event-card:hover { box-shadow: none; }
/* Событие внутри записи ленты — не ссылка целиком (ссылки — название, дата, место): курсор обычный,
   наведения карточки нет (event-detail.css: :not(.activity-card *)), название синеет только само. */
.activity-card .recommended-event-card { cursor: default; }
/* Дата и место — одной строкой: сначала сжимается место (многоточие), пока не дойдёт до 64px; дальше —
   дата (тоже многоточие): вес сжатия места в 1000 раз больше, после его минимума сжимается одна дата
   (доля 1 — с долей меньше единицы flex раздаёт лишь часть нехватки). */
.activity-card .recommended-datetime-location { flex-wrap: wrap; max-width: 100%; } /* не шире карточки; не влезает в строку — место переносится, на своей строке сжимается */
.activity-card :is(.recommended-datetime-location--line, .event-place--line) { flex-wrap: nowrap; } /* перенос переполнил бы карточку (clampLocation) */
/* То же у события-карточки ленты (EventCard) внутри активности: дата и место, сжатие — как выше. */
.activity-card .event-place { max-width: 100%; min-width: 0; }
.activity-card .event-place .event-date { flex-shrink: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.activity-card .event-place .event-location { flex-shrink: 1000; min-width: var(--space-16); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.activity-card .recommended-datetime { flex-shrink: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.activity-card .recommended-datetime:not(.is-split) > span { display: block; overflow: hidden; text-overflow: ellipsis; }
.activity-card .recommended-location { flex-shrink: 1000; min-width: var(--space-16); }
.activity-card.event-card-filled .recommended-event-card .recommended-title { color: var(--color-surface); }
/* Название-ссылка события на залитой — наведение белый 64%, как у остальных ссылок на залитом. */
.activity-card.event-card-filled .recommended-event-card a.recommended-title:is(:hover, :focus-visible) { color: var(--color-on-dark-64); }
.activity-card.event-card-filled .recommended-event-card .recommended-tags span { color: var(--color-on-dark-80); }
.activity-card.event-card-filled .recommended-event-card .recommended-tag-dot { background-color: var(--color-surface) !important; }
.activity-card.event-card-filled .recommended-event-card :is(.recommended-datetime, .recommended-location) { color: var(--color-surface); border-color: var(--color-on-dark-32); }
.activity-card.event-card-filled .recommended-event-card .recommended-avatar { border-color: var(--color-surface); }
/* На залитой кружок у аватарки — в цвет её обводки (белый); значок — цветом карточки, как у медали, цифра уровня — цветом заливки аватарки. */
.activity-card.event-card-filled .recommended-type-badge { background: var(--color-surface) !important; }
.activity-card.event-card-filled .recommended-type-badge .material-symbols-rounded { color: var(--achievement-color); }
.activity-card.event-card-filled .user-avatar-level { background: var(--color-surface); color: var(--event-type-color); }
.activity-card-body .event-tags { align-self: stretch; justify-content: flex-start; }
.activity-card-body .news-body { align-items: flex-start; }
.activity-card-body > .sticker { align-self: flex-start; }
/* Событие внутри карточки ленты — как карточка события в ячейке календаря: второй блок того же
   вида, что основной (радиус карточки, поля карточки), прижат к низу и краям без внутреннего отступа.
   В широкой — правая половина во всю высоту, прижата к правому краю. */
.activity-card-body > .recommended-event-card { margin: auto calc(-1 * var(--space-6)) calc(-1 * var(--space-6)); padding: var(--space-6); border-radius: var(--radius-xl); }
/* Обычная (квадрат): событие сразу под разделителем (не прижато к низу) — место под перенос даты и места. */
.activity-card:not(.news-card--wide, .news-card--tall) .activity-card-body:has(> .recommended-event-card) { justify-content: flex-start; }
.activity-card:not(.news-card--wide, .news-card--tall) .activity-card-body > .recommended-event-card { margin-top: 0; padding-top: 0; }
.activity-card.news-card--wide .activity-card-body:has(> .recommended-event-card) { margin: calc(-1 * var(--space-6)); }
/* Новость в записи ленты: заголовок без верхнего поля заголовка карточки (16 у .event-card-standard .event-title) —
   в широкой вровень с текстом шапки слева, в обычной — тот же шаг от разделителя, что у остальных записей. */
.activity-card .activity-card-body .news-body > .event-title:first-child { margin-top: 0; }
.activity-card.news-card--wide .activity-card-body > .recommended-event-card { margin: 0; flex: 1; display: flex; flex-direction: column; justify-content: center; }
/* Событие в двойной — одинарная карточка ленты событий (EventCard того же вида) в своей части: в широкой справа,
   в вертикальной под разделителем; сверху, как в ленте. Подложку, рамку и поля даёт карточка ленты — у вложенной
   их нет, наведения тоже (карточка ленты — не ссылка). Под датой и местом через 16 — «Подписаться» / «Прошло»
   (EventActions), не 24, как в герое. */
.activity-card-body:has(> .event-card-standard) { justify-content: flex-start; }
.activity-card .activity-card-body > .event-card-standard { align-self: stretch; height: auto; padding: 0; background: none; border: 0; border-radius: 0; cursor: default; }
.activity-card .activity-card-body > .event-card-standard:hover { box-shadow: none; }
/* Действия под датой и местом (EventCard action): в ленте активности и в «Первых событиях» (welcome.html) — через 16. */
.event-card-standard > .event-actions { margin-top: var(--space-4); }
/* Сетка карточек с действиями (рекомендации профиля — «Не интересно», «Первые события» — «Подписаться»):
   кнопка добавляет высоту — ряд не уже 352 и растёт по самой высокой карточке, кнопка не вылезает за карточку. */
.events:has(> .event-card-standard > .event-actions) { grid-template-rows: none; grid-auto-rows: minmax(352px, auto); }
.events > .event-card-standard:has(> .event-actions) { height: auto; }
@media (max-width: 767px) { .events:has(> .event-card-standard > .event-actions) { grid-auto-rows: auto; } }
/* Просьба оценить ('rate_ask'): шкала (RatingPick prominent) — на месте кнопки события, во всю его ширину:
   в широкой — 16 под датой и местом (как EventActions), в вертикальной — 24 под плашками героя, в обычной —
   16 под событием (8 gap тела + 8). */
.activity-card .event-card-standard > .rating-pick { margin-top: var(--space-4); }
.activity-card-body > .event-hero > .rating-pick { align-self: stretch; margin-top: var(--space-6); }
.activity-card-body > .rating-pick { align-self: stretch; }
.activity-card-body > .recommended-event-card + .rating-pick { margin-top: var(--space-2); }
/* Событие в вертикальной — герой страницы события (EventHero card): аватарка 128 с бейджем, название 24/32,
   теги, дата и место, кнопка — по центру по горизонтали, блок — по центру области под разделителем (от линии
   до низа — по полю карточки сверху и снизу). Подложку даёт карточка; правила карточки события
   (.event-card-standard: кегль названия, поля) героя не задевают — вид и отступы героя (event-detail.css). */
.activity-card-body > .event-hero { flex: 1; align-self: stretch; min-height: 0; margin: 0; padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.activity-card-body > .event-hero .event-avatar-wrap { margin-top: 0; }
.activity-card-body > .event-hero .event-title { font-size: var(--text-2xl); line-height: var(--space-8); }
.activity-card-body > .event-hero .event-tags { align-self: stretch; justify-content: center; }
.activity-card-body > .event-hero .event-datetime-location { justify-content: center; }
.activity-card-body > .event-hero .event-actions { align-self: stretch; }
/* Человек в вертикальной — герой человека (PersonHero card) по тем же правилам: «Подписаться» (FollowButton в .event-wait)
   во всю ширину, 24 от тегов — как действия героя события от плашек (у человека плашек нет, своё поле тегов 16 снято). */
.activity-card-body > .event-hero .event-wait { align-self: stretch; align-items: stretch; }
.activity-card-body > .event-hero .event-tags:has(+ .event-wait) { margin-bottom: 0; }
/* Диапазон дат в герое-карточке — как в карточке ленты (эталон плашек): при наведении на часть общая рамка
   пропадает, заливается наведённая часть (на странице события рамка остаётся контуром второй половины). */
.activity-card-body > .event-hero .event-datetime.is-split:has(.event-datetime-part:is(:hover, :focus-visible)) { border-color: transparent; }
/* Подложка аватарки светлого героя — цвета карточки (--avatar-bg: у карточки с рамкой — фон страницы), не белый круг на сером. */
.activity-card-body > .event-hero[data-tone="light"] :is(.event-avatar-large, .event-avatar-letter) { background: var(--avatar-bg, var(--color-surface)); }
/* В квадратной карточке на компьютере 96 с названием не помещается — стикер 64 (в двойных и на телефоне — полный). */
.activity-card:not(.news-card--wide, .news-card--tall) .sticker { height: var(--sticker-height-mobile); }
/* Стикер — всё содержимое карточки (достижение, получен стикер): крупно и по центру своей области (у двойных — части под/за разделителем). */
.activity-card .activity-card-body > .sticker:only-child { align-self: center; height: var(--sticker-height-lg); object-position: center; }
/* Стикер ниже своей высоты, если иначе залез бы в нижнее поле карточки (длинная шапка): сжимается по высоте области. */
.activity-card .activity-card-body > .sticker { flex-shrink: 1; min-height: 0; }
/* Достижение в двойной: стикер (или медаль) крупно по центру, под ним по центру название и «за что». */
.activity-card:is(.news-card--wide, .news-card--tall)[data-kind="achievement"] .activity-card-body { align-items: center; text-align: center; }
.activity-card:is(.news-card--wide, .news-card--tall)[data-kind="achievement"] .activity-card-body > :is(.sticker, .achievement-medal) { align-self: center; }
.activity-card:is(.news-card--wide, .news-card--tall)[data-kind="achievement"] .activity-card-body > .sticker { height: var(--sticker-height-lg); object-position: center; }
.activity-card:is(.news-card--wide, .news-card--tall)[data-kind="achievement"] .activity-card-body .news-body { align-items: center; }
/* Получен стикер: стикер по центру, под ним причина («за подписку на тему «Х»»); у двойных стикер крупно. */
.activity-card[data-kind="sticker"] .activity-card-body { align-items: center; text-align: center; }
.activity-card[data-kind="sticker"] .activity-card-body > .sticker { align-self: center; object-position: center; }
.activity-card[data-kind="sticker"] .activity-card-body .news-body { align-items: center; }
/* Причина — второстепенно, как теги карточки события (14/20, --color-ink-secondary), от стикера — 24; тема — ссылкой. */
.activity-card[data-kind="sticker"] .activity-card-body { gap: var(--space-6); }
.activity-card[data-kind="sticker"] .activity-card-body .news-lead { font-size: var(--text-sm); line-height: 20px; }
/* Второстепенный цвет — только у текста причины: ссылка — основным цветом (наведение — бренд). */
.activity-card[data-kind="sticker"] .activity-card-body .news-lead > span { color: var(--color-ink-secondary); }
.activity-card.event-card-filled[data-kind="sticker"] .activity-card-body .news-lead > span { color: var(--color-on-dark-80); }
/* Тема в причине — ссылка, как ссылки в тексте шапки (.list-row-title a): жирная, без подчёркивания, наведение — бренд (на залитой — белый 64%). */
.activity-card[data-kind="sticker"] .news-lead a, .achievement .news-lead a, .sticker-modal .modal-lead a { font-weight: var(--weight-bold); color: inherit; text-decoration: none; transition: color var(--duration-base) var(--ease-out); }
.activity-card[data-kind="sticker"] .news-lead a:is(:hover, :focus-visible), .achievement .news-lead a:is(:hover, :focus-visible), .sticker-modal .modal-lead a:is(:hover, :focus-visible) { color: var(--color-brand); }
.activity-card.event-card-filled[data-kind="sticker"] .news-lead a:is(:hover, :focus-visible), .achievement.event-card-filled .news-lead a:is(:hover, :focus-visible) { color: var(--color-on-dark-64); }
/* Название-ссылка в теле карточки (тема, событие) — наведение как у ссылок шапки: бренд, на залитой — белый 64%. */
.activity-card .activity-card-body :is(a.event-title, a.recommended-title) { transition: color var(--duration-base) var(--ease-out); }
.activity-card .activity-card-body :is(a.event-title, a.recommended-title):is(:hover, :focus-visible) { color: var(--color-brand); }
.activity-card.event-card-filled .activity-card-body :is(a.event-title, a.recommended-title):is(:hover, :focus-visible) { color: var(--color-on-dark-64); }
.activity-card:is(.news-card--wide, .news-card--tall)[data-kind="sticker"] .activity-card-body > .sticker { height: var(--sticker-height-lg); }
/* Название темы в квадратной карточке — целым числом строк с многоточием (не режется посреди строки). */
.activity-card:not(.news-card--wide, .news-card--tall) .activity-card-body .event-title { -webkit-line-clamp: 3; }
/* Записи не от людей (ActivityCard source). Новые медиа события — ряд плиток (EventPhotos strip) во всю ширину
   и оставшуюся высоту, между плитками 8; события под ними нет — оно в шапке. */
.activity-card-body > .event-photos--strip { flex: 1; align-self: stretch; min-height: 0; display: flex; gap: var(--space-2); }
.event-photos--strip > * { flex: 1; min-width: 0; height: auto; }
.activity-card[data-kind="media"] .activity-card-body { justify-content: center; gap: var(--space-4); }
/* Обычная карточка медиа: область под шапкой — по центру (песня — пластинка с подписями, под шапкой разделитель, как у всех). Видео и фото
   (data-cover) — на весь фон карточки от края до края (скруглением карточки обрезаются), шапка поверх на стеклянной
   подложке — как панель карточки ленты (.priority-panel.event-card-variant: --color-overlay-32 и --blur-panel, текст как
   на залитой), низ подложки скруглён на месте разделителя, самого разделителя нет (вид 'full'; второй вид — 'below',
   ниже). Значок play — по центру области
   под шапкой, не всей карточки: --cover-head — высота шапки (Iwent.fitActivityCard); шапка — над затемнением плитки
   (z-index 2: у .event-image-play свой 1). */
.activity-card[data-kind="media"][data-cover] > .list-row::after { content: none; }
.activity-card[data-kind="media"]:not(.news-card--wide, .news-card--tall) .activity-card-body { align-items: center; justify-content: center; }
.activity-card[data-cover="full"] .event-image-play { padding-top: var(--cover-head, 0px); box-sizing: border-box; }
.activity-card[data-cover] { position: relative; --cover-radius: var(--radius-xl); }
/* Скругление карточки обрезают сами медиа и шапка, а не карточка (overflow у неё открыт: слои стопки
   .activity-card-pile выходят за её низ). --cover-radius — угол медиа у края карточки: с рамкой — внутри неё (2 px). */
.activity-card.event-card-bordered[data-cover] { --cover-radius: calc(var(--radius-xl) - 2px); }
.activity-card[data-cover="full"] > .list-row { position: relative; z-index: 2; margin: calc(-1 * var(--activity-pad)) calc(-1 * var(--activity-pad)) 0; padding: var(--activity-pad); border-radius: var(--radius-xl); background: var(--color-overlay-32); -webkit-backdrop-filter: var(--blur-panel); backdrop-filter: var(--blur-panel); }
.activity-card[data-cover="full"] .activity-card-body { margin: 0; }
.activity-card[data-cover="full"] .activity-card-body > .event-photos--strip { position: absolute; inset: 0; gap: 0; aspect-ratio: auto; border-radius: var(--cover-radius); overflow: hidden; }
/* 'below': шапка как у всех записей (на белой, с рамкой, залитой), под ней —
   медиа во всю ширину карточки и до её низа (от шапки — её нижнее поле, место разделителя); скругление — у медиа сверху (низ обрезает карточка), разделителя нет. */
.activity-card[data-kind="media"][data-cover="below"] .activity-card-body { position: relative; align-self: stretch; margin: 0 calc(-1 * var(--activity-pad)) calc(-1 * var(--activity-pad)); }
.activity-card[data-cover="below"] .activity-card-body > .event-photos--strip { position: absolute; inset: 0; gap: 0; aspect-ratio: auto; border-radius: var(--radius-xl) var(--radius-xl) var(--cover-radius) var(--cover-radius); overflow: hidden; }
/* От шапки до медиа — столько же, сколько от шапки до разделителя у обычной записи (поле карточки). */
.activity-card[data-cover="below"] { row-gap: var(--activity-pad); }
/* 'side' — вид широкой: шапка слева, медиа — вся правая половина до верхнего, правого и нижнего краёв, вплотную к шапке,
   без вертикального разделителя; скругление у медиа — слева (внешние углы обрезает карточка). На телефоне широкая —
   колонкой, и вид тот же, что 'below' (правила ниже, в мобильном блоке). */
.activity-card.news-card--wide[data-cover="side"] { column-gap: 0; }
.activity-card.news-card--wide[data-cover="side"]::after { content: none; }
.activity-card.news-card--wide[data-cover="side"] > .list-row { padding-right: var(--activity-pad); } /* текст шапки — не вплотную к медиа */
.activity-card.news-card--wide[data-kind="media"][data-cover="side"] .activity-card-body { position: relative; align-self: stretch; margin: calc(-1 * var(--activity-pad)) calc(-1 * var(--activity-pad)) calc(-1 * var(--activity-pad)) 0; }
.activity-card[data-cover="side"] .activity-card-body > .event-photos--strip { position: absolute; inset: 0; gap: 0; aspect-ratio: auto; border-radius: var(--radius-xl) var(--cover-radius) var(--cover-radius) var(--radius-xl); overflow: hidden; }
.activity-card[data-cover] .event-photos--strip > * { border-radius: 0; }
.activity-card[data-cover="full"] > .list-row :is(.list-row-title, .list-row-title :is(a, strong)) { color: var(--color-surface); }
.activity-card[data-cover="full"] > .list-row .list-row-title a:is(:hover, :focus-visible) { color: var(--color-on-dark-64); }
.activity-card[data-cover="full"] > .list-row .list-row-meta { color: var(--color-on-dark-80); }
.activity-card[data-cover="full"] > .list-row .list-row-meta .event-tag-dot { background: var(--color-surface); }
.activity-card[data-cover="full"] > .list-row .event-avatar { border: 3px solid var(--color-surface); background: transparent; }
.activity-card[data-cover="full"] > .list-row .event-type-badge { background: var(--color-surface); }
.activity-card[data-cover="full"] > .list-row .event-type-badge .material-symbols-rounded { color: var(--event-type-color, var(--color-brand)); }
/* Песня в карточке записи — без своей плашки и высоты карточки: пластинка (меньше, --music-cover-compact) с подписями по центру области. */
.activity-card .event-photos--strip[data-music] { flex: none; align-self: stretch; }
/* Название песни в обычной карточке записи — одной строкой с многоточием (в двойных и вне записи — до двух строк, .music-title). */
.activity-card:not(.news-card--wide, .news-card--tall) .music-card .music-title { display: block; max-width: 100%; white-space: nowrap; text-overflow: ellipsis; }
.activity-card .event-photos--strip > .music-card { --music-cover: var(--music-cover-compact); height: auto; padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
/* Размер пластинки — как аватарки событий в карточке того же размера: обычная и широкая — 80, вертикальная — 128 (как герой). */
.activity-card.news-card--tall .event-photos--strip > .music-card { --music-cover: var(--music-cover-large); }
.activity-card.event-card-filled .music-card .news-source { color: var(--color-surface); }
.activity-card.event-card-filled .music-card .music-ring-track { stroke: var(--color-on-dark-32); }
.activity-card.event-card-filled .music-card .music-ring-bar { stroke: var(--color-surface); }
.activity-card.event-card-filled .music-card[data-state="playing"] .music-time { color: var(--color-surface); }
.activity-card.news-card--wide[data-kind="media"] .activity-card-body { margin: 0; }
/* «N новых событий в теме»: событие (как в карточке ленты), под ним через 16 — стопка остальных, «+N» и «Все N событий»
   одной строкой (CalendarAvatarStack link): ссылка — через 12 после «+N», не переносится. В обычной — стопка 32
   (обычный размер), на телефоне — тоже рядом, а не колонкой ячейки календаря. */
.activity-card[data-kind="concept_events"] .activity-card-body { justify-content: flex-start; gap: var(--space-4); }
.activity-card .calendar-day-events { margin-top: 0; flex-direction: row; gap: 0; }
.activity-card .calendar-day-events { max-width: 100%; min-width: 0; }
.calendar-day-events > .more-link { margin-left: var(--space-3); white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; } /* узко — многоточие, не за карточку */
/* Не помещается в карточку и после даты и места одной строкой (Iwent.fitActivityCard ставит data-fold) — стопки нет:
   на страницу всех событий ведёт число в шапке. */
.activity-card .calendar-day-events[data-fold] { display: none; }
/* За последней аватаркой сразу ссылка (без «+N») — выреза нет: вырез нужен только под следующее место стопки. */
.calendar-day-events > .event-avatar-wrapper:has(+ .more-link) .event-avatar { -webkit-mask: none; mask: none; }
.activity-card .event-card-standard > .calendar-day-events,
.activity-card-body > .event-hero > .calendar-day-events { margin-top: var(--space-4); }
.activity-card-body > .event-hero > .calendar-day-events { align-self: center; }
.activity-card[data-kind="concept_events"]:not(.news-card--wide, .news-card--tall) .activity-card-body > .recommended-event-card { flex: none; margin-bottom: 0; padding-bottom: 0; }
.activity-card.event-card-filled .calendar-day-events > .more-link { color: var(--color-surface); }
.activity-card.event-card-filled .calendar-day-events .event-avatar { border-color: var(--color-surface); }
.activity-card.event-card-filled .calendar-day-events .event-counter { color: var(--color-surface); }
/* Стопка-ссылка (CalendarAvatarStack link): без подчёркивания, наведение — «+N» брендом (на залитой — белый 64%). */
.calendar-day-events--link { text-decoration: none; color: inherit; width: fit-content; }
.calendar-day-events--link .event-counter { transition: color var(--duration-base) var(--ease-out); }
.calendar-day-events--link:is(:hover, :focus-visible) .event-counter { color: var(--color-brand); }
.activity-card.event-card-filled .calendar-day-events--link:is(:hover, :focus-visible) .event-counter { color: var(--color-on-dark-64); }
/* Новость в теле — карточка новости без своей подложки и полей (как вложенная карточка события), во всю высоту области. */
.activity-card[data-kind="news"] .activity-card-body > .news-card { flex: 1; }
/* Вся карточка новости ведёт на источник (Iwent.initActivityNews), как карточка на странице новостей: курсор, при
   наведении — тень карточки и название брендом (на залитой — белый 60%); наведение на ссылки шапки — без них. */
.activity-card[data-kind="news"], .activity-card[data-kind="news"] .activity-card-body > .news-card { cursor: pointer; }
.event-card-standard.activity-card[data-kind="news"]:hover:not(:has(> .list-row a:hover, .activity-card-body :where(a:not(.event-title, .news-card), button, .event-tag):hover)) { box-shadow: 0 0 32px 0 var(--color-overlay-8); }
.event-card-standard.activity-card[data-kind="news"]:hover:not(:has(> .list-row a:hover, .activity-card-body :where(a:not(.event-title, .news-card), button, .event-tag):hover)) .news-card .event-title { color: var(--color-brand); }
.event-card-standard.activity-card.event-card-filled[data-kind="news"]:hover:not(:has(> .list-row a:hover, .activity-card-body :where(a:not(.event-title, .news-card), button, .event-tag):hover)) .news-card .event-title { color: var(--color-on-dark-64); }
.activity-card[data-kind="news"] .news-card .event-title { transition: color var(--duration-base) var(--ease-out); }
/* Тема в двойной — название по центру, кегль как у названия в герое события (Unbounded 24/32). Так же — тема в
   рекомендации темы (ui.recommendCard, data-target="concept"): тело то же, что у подписки на тему. */
.activity-card:is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body { align-items: center; text-align: center; } /* по центру во всех размерах */
.activity-card:is(.news-card--wide, .news-card--tall):is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body .event-title { font-size: var(--text-2xl); line-height: var(--space-8); }
/* «Следить» / «Вы следите» под названием темы в двойной (FollowButton) — через 16 (у названия своё поле 4 снизу), во всю ширину области. */
.activity-card:is(.news-card--wide, .news-card--tall):is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body { gap: calc(var(--space-4) - var(--space-1)); }
/* Числа темы в двойной: название → «66 событий • 12 впереди» (TagList) → кто следит (StatList people) → «Следить» —
   по 16; своих полей у названия и строки тегов здесь нет (промежуток даёт gap). Строка — по центру; кто следит — как
   «Следят» у события: стопка над числом, подпись — второстепенно, как у уровня (--color-ink 64%), число 24/32. */
.activity-card:is(.news-card--wide, .news-card--tall):is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body:has(> :is(.event-tags, .stat-list)) { gap: var(--space-4); }
.activity-card:is(.news-card--wide, .news-card--tall):is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body:has(> :is(.event-tags, .stat-list)) > :is(.event-title, .event-tags) { margin: 0; }
.activity-card:is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body > .event-tags { justify-content: center; }
.activity-card:is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body .stat { align-items: center; }
.activity-card:is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body .stat:has(> .stat-people) { justify-content: center; text-align: center; }
.activity-card:is([data-kind="follow_concept"], [data-target="concept"]) .activity-card-body .stat-value { font-size: var(--text-2xl); line-height: var(--space-8); }
/* Рекомендация темы в обычной — под названием «Следить» во всю ширину, через 16, как в двойной (у названия поле 4 снизу). */
.activity-card[data-target="concept"]:not(.news-card--wide, .news-card--tall) .activity-card-body { gap: calc(var(--space-4) - var(--space-1)); }
/* Обводка-вырез стопки — цвета карточки: у залитой — её цвет («+N» белым), у карточки с рамкой — фон страницы. */
.activity-card .user-avatar-stack { --stack-bg: var(--avatar-bg, var(--color-surface)); }
.activity-card.event-card-filled .user-avatar-stack { --stack-bg: var(--achievement-color); }
.activity-card.event-card-filled .user-avatar-more { color: var(--color-surface); }
/* Обводка аватарок стопки на залитой — белая, как у аватарки в шапке (иначе кольцо цвета карточки не видно). */
.activity-card.event-card-filled .activity-card-body .user-avatar-stack > .user-avatar:not(.user-avatar-more) { border-color: var(--color-surface); }
/* Разделитель между шапкой и содержимым в двойных — линия ДС (.divider: 1px, --color-border — как над
   категориями: на белой светлее, на сером фоне темнее сама), залитая — белая 32%. Шириной (высотой) с
   содержимое, не до краёв. От линии до содержимого — поле карточки (--activity-pad): у широкой — вертикальная
   между колонками; у остальных (и у широкой на телефоне) — горизонтальная, на поле ниже шапки (::after шапки). */
.activity-card { --activity-divider: var(--color-border); --activity-pad: var(--space-6); }
.activity-card.event-card-filled { --activity-divider: var(--color-on-dark-24); } /* как .event-divider в герое события */
.activity-card:is(.news-card--wide, .news-card--tall) { position: relative; }
.activity-card:not(.news-card--wide) > .list-row { position: relative; overflow: visible; }
.activity-card:not(.news-card--wide) > .list-row::after { content: ''; position: absolute; left: 0; right: 0; top: calc(100% + var(--activity-pad)); height: 1px; background: var(--activity-divider); pointer-events: none; }
.activity-card:not(.news-card--wide) .activity-card-body { margin-top: calc(2 * var(--activity-pad) - var(--space-4)); }
.activity-card.news-card--wide::after { content: ''; position: absolute; top: var(--activity-pad); bottom: var(--activity-pad); left: 50%; width: 1px; transform: translateX(-0.5px); background: var(--activity-divider); pointer-events: none; }
.activity-card-body .stat { align-items: flex-start; }
.activity-card-body .stat-value { font-size: var(--text-4xl); line-height: 48px; }
/* Уровень — по центру, число крупно. */
.activity-card:is([data-kind="level"], [data-kind="rated"]:not(.news-card--wide, .news-card--tall)) .activity-card-body { align-items: center; text-align: center; }
.activity-card:is([data-kind="level"], [data-kind="rated"]:not(.news-card--wide, .news-card--tall)) .activity-card-body .stat { align-items: center; }
.activity-card:is([data-kind="level"], [data-kind="rated"]:not(.news-card--wide, .news-card--tall)) .activity-card-body .stat-value { font-size: var(--text-display); line-height: 1; }
/* Подписи у достижения, стикера, уровня, оценки и темы — одного вида: второстепенный текст 14/20,
   --color-ink-secondary (на залитой — --color-on-dark-80; подпись StatList — сама, правило залитой ниже), от картинки/числа до текста — 24. */
.activity-card:is([data-kind="achievement"], [data-kind="level"]) .activity-card-body { gap: var(--space-6); }
.activity-card[data-kind="achievement"] .activity-card-body .news-lead { font-size: var(--text-sm); line-height: 20px; color: var(--color-ink-secondary); }
.activity-card.event-card-filled[data-kind="achievement"] .activity-card-body .news-lead { color: var(--color-on-dark-80); }
.activity-card:is([data-kind="level"], [data-kind="rated"]:not(.news-card--wide, .news-card--tall)) .activity-card-body .stat { gap: var(--space-6); }
/* Оценка события ('rated'): число крупно на месте кнопки события — в широкой под карточкой через 16 (как
   EventActions), в вертикальной под героем через 24 (как действия героя, по центру). В обычной (квадрат)
   событие с числом не помещаются: число — как уровень (правила выше), событие —
   ссылкой в тексте шапки. Подпись — как у уровня: --color-ink-secondary (на залитой — --color-on-dark-80). */
.activity-card .event-card-standard > .stat-list { margin-top: var(--space-4); }
/* В широкой событие и число делят высоту ряда: число — 24/32, как числа темы в двойной (follow_concept), подпись — сразу
   под строкой числа, иначе «Оценка из 10» заходит в нижнее поле карточки (с рамкой — на 18). */
.activity-card.news-card--wide[data-kind="rated"] .event-card-standard > .stat-list .stat-value { font-size: var(--text-2xl); line-height: var(--space-8); }
.activity-card.news-card--wide[data-kind="rated"] .event-card-standard > .stat-list .stat { gap: 0; } /* у строки 32 свой воздух над подписью */
.activity-card-body > .event-hero > .stat-list { margin-top: var(--space-6); }
.activity-card-body > .event-hero .stat { align-items: center; }
/* Части широкой — как содержимое обычных карточек под ними: обе колонки шириной с содержимое карточки сетки,
   между ними — промежуток сетки и два поля; линия — ровно по центру (::after left: 50%). */
.activity-card.news-card--wide { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: calc(var(--grid-gap) + 2 * var(--activity-pad)); }
/* Строка «титул • время» в шапке — как теги карточки события (.event-card-standard .event-tag): текст
   --color-ink-secondary, точка сплошная (так у ListRow везде); на залитой — --color-on-dark-80, точка белая (ниже). */
/* «Титул • время» — одной строкой: титул сжимается с многоточием, время целиком (как дата и место в карточке). */
.activity-card > .list-row .list-row-meta { flex-wrap: nowrap; min-width: 0; }
.activity-card > .list-row .list-row-meta > span:not(.event-tag-dot) { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.activity-card > .list-row .list-row-meta > span:last-child { flex-shrink: 0; }
/* Одна часть (причина рекомендации, без времени) — сжимается с многоточием сама. */
.activity-card > .list-row .list-row-meta > span:only-child { flex-shrink: 1; }
/* Причина рекомендации — не время, переносится до двух строк, а не обрезается в одну. */
.activity-card[data-kind="recommend"] > .list-row .list-row-meta > span:only-child { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.activity-card.event-card-filled > .list-row :is(.list-row-title, .list-row-title :is(a, strong)),
.activity-card.event-card-filled .activity-card-body .stat-value { color: var(--color-surface); }
.activity-card.event-card-filled > .list-row .list-row-meta,
.activity-card.event-card-filled .activity-card-body .stat-label { color: var(--color-on-dark-80); }
.activity-card.event-card-filled > .list-row .list-row-meta .event-tag-dot { background: var(--color-surface); }
/* На залитой — число-ссылка белое (выше), наведение — --color-on-dark-64, как у названия. */
.activity-card.event-card-filled .activity-card-body .stat-link:is(:hover, :focus-visible, .is-hover) .stat-number { color: var(--color-on-dark-64); }
.activity-card.event-card-filled .activity-card-body .stat-link:focus-visible { outline-color: var(--color-surface); }
.activity-card.event-card-filled > .list-row .list-row-title a:is(:hover, :focus-visible) { color: var(--color-on-dark-64); }
/* Кроме «+N» стопки (свёрнутое действие ленты подписок): его кружок — цветом подложки, как в содержимом. */
.activity-card.event-card-filled > .list-row .user-avatar:not(.user-avatar-more) { border-color: var(--color-surface); }

/* Многострочное поле (TextField multiline). */
.field-textarea { resize: vertical; min-height: 120px; font-family: var(--font-body); font-weight: var(--weight-regular); }

/* ---------- Мобильная версия (≤ 767px): строки списка, шапка профиля, достижения ---------- */
@media (max-width: 767px) {
  /* Кнопки и статус строки — второй строкой во всю ширину под текстом. */
  .list-row { flex-wrap: wrap; align-items: flex-start; }
  .list-row-main { flex-basis: calc(100% - 64px - var(--space-mobile)); }
  .list-row-aside { flex-basis: 100%; justify-content: flex-start; }
  .stat-list { gap: var(--space-4) var(--space-6); }
  /* Счётчики события — по два в ряд; нечётный последний — во всю ширину по центру. */
  .stat-list--spread { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
  .stat-list--spread > .stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* Достижения — колонкой, как новости; двойные на телефоне обычные — иллюстрация обычного размера. */
  .news-card--wide .achievement-medal, .news-card--tall .achievement-medal { --medal: var(--space-16); }
  .sticker { height: var(--sticker-height-mobile); }
  .sticker--large { height: var(--sticker-height-xl-mobile); }
  .activity-card .activity-card-body > .sticker:only-child { height: var(--sticker-height); }
  .activity-card:is(.news-card--wide, .news-card--tall)[data-kind="achievement"] .activity-card-body > .sticker { height: var(--sticker-height); }
  .activity-card:is(.news-card--wide, .news-card--tall)[data-kind="sticker"] .activity-card-body > .sticker { height: var(--sticker-height); }
  .activity-card:is([data-kind="level"], [data-kind="rated"]:not(.news-card--wide, .news-card--tall)) .activity-card-body .stat-value { font-size: var(--text-display-mobile); }
  /* Лента активности — колонкой, как новости: двойная горизонтальная — шапка над содержимым. */
  .activity-card.news-card--wide { display: flex; }
  /* Широкая с видео и фото — как 'below': медиа под шапкой во всю ширину и до низа, скругление сверху. */
  .activity-card.news-card--wide[data-kind="media"][data-cover="side"] { row-gap: var(--activity-pad); }
  .activity-card.news-card--wide[data-cover="side"] > .list-row { padding-right: 0; }
  .activity-card.news-card--wide[data-kind="media"][data-cover="side"] .activity-card-body { margin: 0 calc(-1 * var(--activity-pad)) calc(-1 * var(--activity-pad)); }
  .activity-card[data-cover="side"] .activity-card-body > .event-photos--strip { border-radius: var(--radius-xl) var(--radius-xl) var(--cover-radius) var(--cover-radius); }
  /* Одна колонка — разделитель горизонтальный, как у вертикальной. */
  .activity-card.news-card--wide::after { display: none; }
  .activity-card { --activity-pad: var(--space-mobile); }
  .activity-card.news-card--wide > .list-row { position: relative; overflow: visible; }
  .activity-card.news-card--wide > .list-row::after { content: ''; position: absolute; left: 0; right: 0; top: calc(100% + var(--activity-pad)); height: 1px; background: var(--activity-divider); pointer-events: none; }
  .activity-card.news-card--wide .activity-card-body { margin-top: 0; }
  .activity-card:is(.news-card--wide, .news-card--tall) .activity-card-body > .recommended-event-card { padding-top: 0; }
  .activity-card-body > .recommended-event-card,
  .activity-card.news-card--wide .activity-card-body > .recommended-event-card { margin: auto calc(-1 * var(--space-mobile)) calc(-1 * var(--space-mobile)); padding: 0 var(--space-mobile) var(--space-mobile); }
  .activity-card.news-card--wide .activity-card-body:has(> .recommended-event-card) { margin: 0; }
  /* Высота по содержимому — «за что» у ступени с полосой снова видно. */
  .achievement:not(.news-card--wide, .news-card--tall):has(.progress) .news-lead { display: -webkit-box; }
  /* Превью медиа (EventPhotos strip): высота карточки — по содержимому, ряд плиток — 16:9, как медиаблок на телефоне. */
  .activity-card-body > .event-photos--strip { flex: none; aspect-ratio: 16 / 9; }
  .activity-card .event-photos--strip[data-music] { aspect-ratio: auto; }
  .activity-card[data-cover] { aspect-ratio: 1; }
}

/* Выбор кнопками внутри поля (FieldGroup): от подписи — gap поля (8), своё поле ряда снято. */
.field > .filters { margin-top: 0; }

/* ---------- Строка поиска в шапке (SearchField, SearchSuggest) ----------
   Поле — .field-input (тот же вид, что у TextField), подписи над ним нет: слева
   лупа, справа крестик очистки — FilterButton без рамки, только когда есть
   текст. Панель подсказок — .dropdown-panel (вид Dropdown) во всю ширину поля;
   пункты — .dropdown-item: событие — аватарка категории (Avatar small),
   название и строка сведений (.list-row-meta), тема — иконка вида и счётчик. */
.search-toggle { display: none; }
.search-form {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}
.search-form > [data-action="search-close"] { display: none; }
.search-box {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
}
/* Текст — после лупы: поле 16 + лупа 20 + 8; справа — место под крестик 44 и 4. */
.search-input {
  width: 100%;
  min-width: 0;
  padding-left: calc(var(--space-4) + var(--space-6) + var(--space-1));
  padding-right: var(--space-12);
  appearance: none;
}
/* Вне фокуса поле прозрачное, на фоне шапки; в фокусе (и в каталоге — is-focus) белое. */
.search-input {
  background-color: transparent;
  transition: border-color var(--duration-base) var(--ease-out), background-color var(--duration-base) var(--ease-out);
}
.search-input:focus,
.search-input:focus-visible,
.search-input.is-focus { background-color: var(--color-surface); }
.search-input::-webkit-search-cancel-button,
.search-input::-webkit-search-decoration { appearance: none; }
.search-icon {
  position: absolute;
  top: 50%;
  left: var(--space-4);
  transform: translateY(-50%);
  color: var(--color-muted);
  pointer-events: none;
}
/* Крестик — квадрат 44 внутри поля 46: по 1 от рамки, без своей рамки. */
.search-box > [data-action="search-clear"] {
  position: absolute;
  top: 1px;
  right: 1px;
  border-color: transparent;
}
.search-field:not(.has-value) [data-action="search-clear"] { display: none; }

.search-panel {
  top: calc(100% + var(--space-2));
  left: 0;
  right: 0;
  width: auto;
  min-width: 0;
  max-width: none;
  max-height: calc(100vh - var(--header-height) - var(--space-6));
}
/* Раскрытие — как у Dropdown (проявление со сдвигом вниз, fast), но открыта панель не по .dropdown.open, а по
   .search-field.is-open: без этого правила она оставалась прозрачной (opacity 0 у .dropdown-panel). Свои
   opacity/transform и на телефоне: там панель не шторка снизу (translateY(100%) у .dropdown-panel), а под шапкой. */
.search-panel {
  opacity: 0;
  transform: translateY(calc(var(--space-1) * -1));
  transition: opacity var(--duration-fast) var(--ease-in), transform var(--duration-fast) var(--ease-in),
    display var(--duration-fast) allow-discrete;
}
.search-field.is-open .search-panel {
  display: flex;
  opacity: 1;
  transform: none;
  transition: opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out),
    display var(--duration-fast) allow-discrete;
}
@starting-style {
  .search-field.is-open .search-panel { opacity: 0; transform: translateY(calc(var(--space-1) * -1)); }
}
.search-option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  text-decoration: none;
}
.search-option-text { display: flex; flex-direction: column; min-width: 0; }
.search-option-title,
.search-option .list-row-meta > :last-child {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.search-option .list-row-meta { flex-wrap: nowrap; font-weight: var(--weight-regular); }
.search-option .list-row-meta > * { flex-shrink: 0; }
.search-option .list-row-meta > :last-child { flex-shrink: 1; }
/* «Ничего не найдено» — вид строки сведений (.list-row-meta), поля — как у пункта:
   панель 12 + 8 сверху и снизу, текст 20 — пустая панель 60px. */
.search-note { margin: 0; padding: var(--space-2) var(--space-3); }
/* Ответ ещё идёт (SearchSuggest loading): строки-заглушки размером со строку события —
   аватарка 40px и две строки Skeleton, поля как у пункта. */
.search-skeleton-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
}
.search-skeleton-row > .skeleton-line { flex-shrink: 0; }
.search-skeleton-row > .skeleton-text { flex: 1; }

/* Аватарка события 40px без бейджа (Avatar small): категорию даёт обводка. */
.event-avatar--small {
  flex-shrink: 0;
  width: calc(var(--space-8) + var(--space-2));
  height: calc(var(--space-8) + var(--space-2));
  border-width: 2px;
}

/* ---------- Мобильная версия (≤ 767px): строка поиска ----------
   В шапке — кнопка-лупа 44×44. Открыли — поле закрывает шапку во всю ширину
   (слева «назад» закрывает), подсказки — под шапкой во всю ширину, страница
   под ними затемнена тенью панели, как под шторкой Dropdown. */
@media (max-width: 767px) {
  .search-toggle { display: inline-flex; flex-shrink: 0; }
  .search-form { display: none; }
  .search-field.is-expanded .search-form {
    display: flex;
    position: absolute;
    inset: 0;
    z-index: 950; /* над нижней панелью меню (900), под уведомлениями */
    padding: 0 var(--space-mobile);
    background: var(--color-bg);
  }
  .search-form > [data-action="search-close"] {
    display: inline-flex;
    flex-shrink: 0;
    border-color: transparent;
  }
  .search-panel {
    position: fixed;
    top: var(--header-height-mobile);
    right: 0;
    bottom: auto;
    left: 0;
    max-height: calc(100dvh - var(--header-height-mobile));
    border-radius: 0 0 var(--radius-xl) var(--radius-xl);
    padding: var(--space-2) var(--space-2) var(--space-4);
    /* Тень — только вниз от панели: шапку с полем она не затемняет. */
    box-shadow: 0 100vmax 0 100vmax var(--color-overlay-24);
  }
  .search-panel::before { content: none; }
  .search-panel::after { top: var(--header-height-mobile); }
}


/* ---------- Видео и музыка в галерее (EventPhotos, MediaTile, MediaPlayer) ----------
   Плитки видео — те же, что у фото (.event-image из event-detail.css), поверх —
   значок «играть», без подписи; наведение — общее с фото (event-detail.css). Плеер — слайд Gallery,
   16:9, радиус как у снимка. */
.event-image--media {
  position: relative;
  overflow: hidden;
  background-color: var(--color-ink);
}
.event-image-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-surface);
  background: var(--color-overlay-24);
}
/* Значок play — на белой круглой плашке 48 (тёмный значок): виден на любом кадре. */
.event-image-play > .material-symbols-rounded { display: flex; align-items: center; justify-content: center; width: var(--space-12); height: var(--space-12); border-radius: 50%; background: var(--color-surface); color: var(--color-ink); }
/* ---------- Карточка песни (MusicCard) ----------
   Плитка медиаблока: event-card-standard / news-card (фон, радиус, поля, наведение — как у
   новости, обычный размер — квадрат сетки). Название и время — .news-source; по центру круглая
   обложка с кольцом прогресса (SVG, pathLength 1: --progress, 0…1, ставит Iwent.initMusicPlayers). */
.music-card { align-items: center; text-align: center; cursor: pointer; --music-cover: calc(var(--space-4) * 8); --music-ring: 3px; --music-disc: calc(var(--music-cover) + var(--music-ring) * 4); gap: var(--space-2); }
.music-card .news-source { line-height: 1.2; }
.music-card:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }
.music-title { flex: none; align-self: stretch; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.music-disc { position: relative; flex: none; width: var(--music-disc); height: var(--music-disc); }
.music-seek { position: absolute; inset: 0; border-radius: 50%; cursor: grab; touch-action: none; }
.music-seek:hover { background: var(--color-hover); }
.music-seek:active { cursor: grabbing; }
/* Кольцо по краю диска толщиной --music-ring (3): svg отступает на полтолщины (r = 50 в viewBox), обложка — на две толщины,
   поэтому от обложки до кольца всегда 3 (диск = обложка + 4 толщины) при любом размере пластинки. */
.music-ring { pointer-events: none; position: absolute; inset: calc(var(--music-ring) / 2); width: calc(100% - var(--music-ring)); height: calc(100% - var(--music-ring)); overflow: visible; transform: rotate(-90deg); }
/* Толщина кольца — 3px на экране, как обводки аватаров: рисунок 100 единиц растянут на диск 144px (128 + 16). */
/* Кольцо — 3 px при любом размере пластинки (не масштабируется с viewBox). */
.music-ring circle { fill: none; stroke-width: var(--music-ring); vector-effect: non-scaling-stroke; }
.music-ring-track { stroke: var(--color-border); }
.music-ring-bar { stroke: var(--color-brand); stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: calc(1 - var(--progress, 0)); }
.music-cover { position: absolute; inset: calc(var(--music-ring) * 2); border-radius: 50%; overflow: hidden; background: var(--color-bg); }
.music-cover-image { position: absolute; inset: 0; z-index: 1; background-size: cover; background-position: center; }
.music-play { position: absolute; inset: var(--space-2); z-index: 2; display: flex; align-items: center; justify-content: center; border-radius: 50%; color: var(--color-surface); background: var(--color-overlay-24); }
.music-disc:not(:has(.music-cover-image)) .music-play { color: var(--color-ink); background: none; }
.music-time { font-variant-numeric: tabular-nums; }
.music-card[data-state="playing"] .music-time { color: var(--color-brand); }

.media-player { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-lg); overflow: hidden; background: var(--color-ink); }
.media-player iframe, .media-player video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.media-player--audio { aspect-ratio: auto; background: none; overflow: visible; }
/* Вертикальный клип (VK) — 9:16: ролик во весь плеер, а не узкой полосой посередине 16:9. */
.media-player--vertical { aspect-ratio: 9 / 16; }
.media-player audio { display: block; width: 100%; }
/* Слайд галереи: плеер вписан в окно по высоте (16:9, вертикальный — 9:16), у песни — полоса по ширине. */
.gallery { --gallery-stage-h: calc(100vh - 240px); }
.gallery--inline { --gallery-stage-h: 300px; }
.gallery-frame .media-player { width: min(100%, calc(var(--gallery-stage-h) * 16 / 9)); }
.gallery-frame .media-player--vertical { width: min(100%, calc(var(--gallery-stage-h) * 9 / 16)); }
.gallery-frame .media-player--audio { width: min(100%, 480px); }
.gallery-thumb--media { position: relative; display: flex; align-items: center; justify-content: center; }
.gallery-thumb--media .material-symbols-rounded { color: var(--color-surface); }

/* ---------- Подсказка при наведении (Tooltip, Iwent.initTooltips) ----------
   Имя человека над аватаркой и полный текст обрезанного многоточием: тёмная плашка, белый текст 12/16, поля 4/8,
   не шире 320 (длинное переносится), тень всплывающих панелей. Одна на страницу,
   position: fixed (не обрезается карточкой); место — --tooltip-x / --tooltip-y от поведения. Появление — проявление
   со сдвигом на 4 вверх за fast (как Dropdown), уход — быстрее, без сдвига. Ниже уведомлений (Toast), над остальным. */
.tooltip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1050;
  max-width: min(calc(var(--space-16) * 5), calc(100vw - var(--space-4))); /* 320: длинное (обрезанный текст) — переносится */
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-xs);
  background: var(--color-ink);
  color: var(--color-surface);
  box-shadow: var(--shadow-panel);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: var(--space-4);
  font-weight: var(--weight-regular);
  width: max-content;
  overflow-wrap: anywhere;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translate(var(--tooltip-x, 0), calc(var(--tooltip-y, 0px) + var(--space-1)));
  transition: opacity var(--duration-fast) var(--ease-in), visibility 0s linear var(--duration-fast);
}
.tooltip.is-open {
  opacity: 1;
  visibility: visible;
  transform: translate(var(--tooltip-x, 0), var(--tooltip-y, 0));
  transition: opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out);
}
.tooltip--open { position: static; display: inline-block; opacity: 1; visibility: visible; transform: none; transition: none; } /* в потоке (каталог) */
@media (hover: none) { .tooltip:not(.tooltip--open) { display: none; } }

/* ---------- «Наверх» (ScrollTop) ----------
   Вид — Button с одной иконкой (кнопка-иконка 44×44 с рамкой, наведение — как у
   кнопок: рамка уходит, подложка --color-hover). Своего фона нет — вид как
   у кнопки-иконки в ДС. Здесь только место: левый нижний угол экрана, в 24
   от краёв (на телефоне — поле страницы), над нижней панелью меню версии с
   пользователями (--bottom-nav-offset); справа от бокового меню, когда оно есть. */
.scroll-top {
  position: fixed;
  left: var(--space-6);
  bottom: var(--space-6);
  z-index: 900;
}
.scroll-top[hidden] { display: none; }
body:has(.sidebar--rail) .scroll-top { left: calc(var(--sidebar-rail-width) + var(--space-6)); }
@media (max-width: 767px) {
  .scroll-top,
  body:has(.sidebar--rail) .scroll-top {
    left: var(--space-mobile);
    bottom: calc(var(--bottom-nav-offset, 0px) + var(--space-mobile) + env(safe-area-inset-bottom, 0px));
  }
}


/* ---------- Новости (NewsList) ----------
   Карточка — стандартная карточка ленты (вид и цвет — по data-type), без аватара и тегов:
   заголовок до 4 строк, внизу дата слева и источник справа. Двойные (Iwent.newsLayout):
   --wide — две колонки, --tall — два ряда (высота — от сетки: два ряда и промежуток),
   у них под заголовком вводный текст. Сетка — .events, ряды по её высоте. */
.news-card { display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-4); color: inherit; text-decoration: none; min-width: 0; height: auto; }
/* Обычная карточка — квадрат: ряд равен ширине колонки (3 колонки, 2 промежутка); ширина — от обёртки сетки. */
:has(> .events > :is(.news-card, .event-image, .achievement)) { container-type: inline-size; }
.events:has(> :is(.news-card, .event-image, .achievement)) { grid-template-rows: none; grid-auto-rows: calc((100cqw - 2 * var(--grid-gap)) / 3); }
/* У понятия новости — 4 колонки (у событий 3), высота ряда — как у карточек событий (352). */
.page-concept .events:has(> .news-card) { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 352px; }
/* Лента активности — высота ряда как у ленты событий (352, .events), не квадрат по ширине колонки. */
.events:has(> .activity-card) { grid-auto-rows: 352px; }
/* Заголовок и дата — отступы карточки события (4 под заголовком, 16 под датой). */
/* Не задевает событие внутри двойной карточки ленты активности (EventCard в ActivityCard) — у него отступы карточки ленты. */
.news-card .event-title:not(:where(.event-card-standard .event-card-standard .event-title)) { margin-top: 0; -webkit-line-clamp: 4; }
.news-body { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.news-card--wide { grid-column: span 2; }
.news-card--tall { grid-row: span 2; }
/* Сетка медиаблока без заголовка: от проигрывателя и «Все» — 32, как между блоками. */
.event-photos > .events { margin-top: var(--space-8); }
.event-photos > .show-more-container { padding-bottom: 0; }
.news-lead { font-family: var(--font-body); font-size: var(--text-base); line-height: var(--space-6); color: var(--color-ink); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
.news-card.event-card-filled .news-lead { color: #fff; }
.news-source { font-family: var(--font-alt); font-size: var(--text-sm); font-weight: var(--weight-bold); line-height: 20px; color: var(--color-ink); }
.news-card.event-card-filled .news-source { color: #fff; }
/* «Все» — последнее в разделе: снизу отступ даёт раскладка страницы (линия события, 64 у понятия), не кнопка. */
.news-list > .show-more-container { padding-bottom: 0; }

/* Новости на телефоне: ряды по содержимому, как карточки ленты (height: auto у .event-card-standard). */
@media (max-width: 767px) {
  .events:has(> :is(.news-card, .event-image, .achievement)), .page-concept .events:has(> :is(.news-card, .event-image, .achievement)) { grid-auto-rows: auto; }
  .page-concept .events:has(> .news-card) { grid-template-columns: 1fr; }
}

/* ---------- Подборки (CollectionRow, CollectionCard) ----------
   Ряд в ленте под фильтрами (feed.js): карточки равной ширины, от ряда управления 24 —
   как сетка событий; до сетки — 32 от нижней подложки (поле 32 схлопывается с 24 у .events). Не
   влезли — ряд листается, полосы прокрутки нет. Карточка — белая (как карточки ленты),
   внутри название и под ним аватарки (CalendarAvatarStack large, «+N» цвета карточки);
   снизу стопка из трёх слоёв, у всех одинаковая (макет Figma 661:65, ниже). Место под них
   держит поле снизу 16 у всех — тела карточек в ряду одной высоты. */
.collection-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - 3 * var(--grid-gap)) / 4);
  gap: var(--grid-gap);
  margin-top: var(--space-6);
  margin-bottom: var(--space-8);
}
/* Прокрутка ряда — только на телефоне: на десктопе до 4 карточек влезают, а overflow
   обрезал бы тень наведения по краям. */
.collection-row::-webkit-scrollbar { display: none; }
.collection-card {
  position: relative;
  isolation: isolate;
  display: flex;
  min-width: 0;
  /* Место под стопку — ровно её глубина: от нижнего слоя до сетки событий 32. */
  --stack-depth: 13px;
  padding-bottom: var(--stack-depth);
  color: var(--color-ink);
  text-decoration: none;
}
/* Стопка — три слоя под карточкой, у всех подборок одинаковая (макет Figma 661:74):
   ниже карточки на 5 / 9 / 13 (макет 3 / 7 / 11 + 2 — пользователь), уже с каждого бока на 12 / 24 / 36, скругление 16, без обводки;
   ближний слой — темнее и поверх. Карточка — поверх всех. */
.collection-card::before,
.collection-card::after,
.collection-card-stack {
  content: '';
  position: absolute;
  top: var(--space-6);
  border-radius: var(--radius-md);
  pointer-events: none;
}
.collection-card::before { z-index: 1; left: var(--space-3); right: var(--space-3); bottom: calc(var(--stack-depth) - 5px); background: var(--color-stack-1); }
.collection-card::after { z-index: 0; left: var(--space-6); right: var(--space-6); bottom: calc(var(--stack-depth) - 9px); background: var(--color-stack-2); }
.collection-card-stack { z-index: -1; left: calc(var(--space-6) + var(--space-3)); right: calc(var(--space-6) + var(--space-3)); bottom: calc(var(--stack-depth) - 13px); background: var(--color-stack-3); }
.collection-card-body {
  position: relative;
  z-index: 2;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Макет Figma 661:74: от названия до аватарок 12, скругление 24; поля — 24 (пользователь). */
  gap: var(--space-3);
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  transition: box-shadow var(--duration-base) var(--ease-out);
}
.collection-card:hover .collection-card-body { box-shadow: 0 0 var(--space-8) 0 var(--color-overlay-8); }
.collection-card:focus-visible { outline: none; }
.collection-card:focus-visible .collection-card-body { outline: 2px solid var(--color-brand); outline-offset: 2px; }
.collection-card-title {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  line-height: var(--space-6);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  transition: color var(--duration-base) var(--ease-out);
}
.collection-card:hover .collection-card-title { color: var(--color-brand); }
/* Стопка событий — внизу карточки: у карточек ряда с названием в 2 и 3 строки аватарки стоят вровень. */
.collection-card-body > .collection-card-title + * { margin-top: auto; }

/* Подборки на телефоне: ряд листается от края до края экрана, карточки 256 с шагом 16,
   прилипают к полю страницы; внутри карточки поля --space-mobile. */
@media (max-width: 767px) {
  .collection-row {
    overflow-x: auto;
    scrollbar-width: none;
    grid-auto-columns: calc(var(--space-16) * 4);
    gap: var(--space-4);
    margin: var(--space-mobile) calc(-1 * var(--space-mobile)) var(--space-8);
    padding-inline: var(--space-mobile);
    scroll-padding-inline: var(--space-mobile);
    scroll-snap-type: x mandatory;
  }
  .collection-card { scroll-snap-align: start; }
}

/* Длинный текст документа (Prose, legal.html): как описание события — Onest 16/24,
   строка не шире --text-measure. Внутри шаг 16, перед заголовком раздела
   (DetailTitle) — 32, перед подразделом — 24; пункты списка — через 8. Таблица —
   мелким (14/20), шапка серым; не влезает — прокрутка вбок внутри себя. */
.prose {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: var(--text-measure);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 24px;
  color: var(--color-ink);
}
.prose p { margin: 0; }
.prose > .event-detail-title { margin: var(--space-4) 0 0; }
.prose > .event-detail-title:first-child { margin-top: 0; }
.prose-subtitle { margin: var(--space-2) 0 0; font-size: var(--text-base); font-weight: var(--weight-bold); line-height: 24px; }
.prose strong { font-weight: var(--weight-bold); }
.prose code { font: inherit; }
.prose-list { margin: 0; padding-left: var(--space-6); display: flex; flex-direction: column; gap: var(--space-2); }
.prose-link { color: var(--color-brand); text-decoration: none; }
.prose-link:hover { text-decoration: underline; }
.prose-link:focus-visible { outline: 2px solid var(--color-brand); outline-offset: 2px; }
.prose-table { overflow-x: auto; }
.prose-table table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); line-height: 20px; }
.prose-table th { text-align: left; vertical-align: bottom; font-weight: var(--weight-regular); color: var(--color-ink-secondary); padding: 0 var(--space-3) var(--space-2) 0; }
.prose-table td { vertical-align: top; padding: var(--space-2) var(--space-3) var(--space-2) 0; border-top: 1px solid var(--color-border-soft); }

/* Подвал страниц афиши (SiteFooter): линия (Divider), под ней ссылки на документы
   строкой через точку и имя сайта — мелким серым. Поля по бокам — как у .content-inner;
   снизу — место под «Наверх» (ScrollTop, 44 + отступ от края): в конце страницы кнопка
   не ложится на ссылки. */
.site-footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: calc(var(--space-8) - var(--space-6)); /* с полем .content-inner — 32 до линии */
  padding: 0 var(--space-6) calc(var(--control-height) + var(--space-6) * 2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 20px;
  color: var(--color-ink-secondary);
}
.site-footer > .divider { margin: 0 0 var(--space-4); }
.site-footer-links .event-tag-dot { background: currentColor; }
@media (max-width: 767px) {
  .site-footer {
    margin-top: calc(var(--space-8) - var(--space-mobile)); /* с полем .content-inner — 32 до линии */
    padding: 0 var(--space-mobile) calc(var(--control-height) + var(--space-mobile) * 2);
  }
  /* Ссылки документов — строки по 44 (область нажатия), точки между ними не нужны. */
  .site-footer-links { flex-direction: column; align-items: flex-start; gap: 0; }
  .site-footer-links > .event-tag-dot { display: none; }
  .site-footer-links > .concept-tag { display: flex; align-items: center; min-height: var(--control-height); }
}

/* ---------- Появление карточек после действия (Iwent.initReveal, event-utils.js) ----------
   «Показать ещё», смена фильтра или вкладки: проявление со сдвигом, лесенка --reveal-step
   (не больше 4 ступеней, ≈ 300 мс всего). Только opacity и transform — раскладка на месте.
   Класс ставит скрипт и снимает по окончании; первая отрисовка страницы не анимируется. */
@keyframes card-reveal { from { opacity: 0; transform: translateY(var(--reveal-shift)); } }
.events > .is-reveal {
  animation: card-reveal var(--duration-base) var(--ease-out) backwards;
  animation-delay: calc(var(--reveal-i, 0) * var(--reveal-step));
}

/* Лента активности: название (события, темы, достижения) меняет цвет только при наведении на само название —
   не от наведения на карточку активности или на карточку события внутри неё (правило карточек ленты). */
.event-card-standard.activity-card .event-title:not(:hover, :focus-visible) { color: var(--color-ink); }
.event-card-standard.activity-card.event-card-filled .event-title:not(:hover, :focus-visible) { color: var(--color-surface); }

/* Человек в широкой карточке активности (EventCard avatar) — аватарка того же размера, что у события в карточке
   ленты (.event-card-standard .event-avatar): 80, на телефоне 64. */
.activity-card .event-card-standard .user-avatar { width: calc(var(--space-16) + var(--space-4)); height: calc(var(--space-16) + var(--space-4)); }
@media (max-width: 767px) {
  .activity-card .event-card-standard .user-avatar { width: var(--space-16); height: var(--space-16); }
}

/* Группа в большой карточке ленты: второстепенные люди — рядом аватарок под текстом шапки, 12 от строки сведений. */
.activity-card > .list-row .list-row-main > .user-avatar-stack { margin-top: var(--space-3); }
/* Групповое действие (несколько людей) — карточка стопкой, как подборка (CollectionCard): три слоя снизу тенями —
   ниже на 5/9/13, уже на 6/11/16 с каждого бока (у тени скругление = радиус карточки 32 минус сужение: 26/21/16 —
   дальний как у слоёв подборки; сужение больше 32 срезало бы скругление в ноль). Цвета слоёв — локальные --stack-1…3: на белой и с рамкой — серые подборки
   (--color-stack-*), на залитой — цвет карточки, тающий к фону страницы (ближний насыщеннее, дальний бледнее),
   с рамкой — цвет рамки, мягче. */
.activity-card[data-group] { --stack-1: var(--color-stack-1); --stack-2: var(--color-stack-2); --stack-3: var(--color-stack-3); }
/* С рамкой — цвет рамки, мягче (карточка светлая): 40/26/14%. */
.activity-card.event-card-bordered[data-group] {
  --stack-1: color-mix(in srgb, var(--achievement-color) 40%, var(--color-bg));
  --stack-2: color-mix(in srgb, var(--achievement-color) 26%, var(--color-bg));
  --stack-3: color-mix(in srgb, var(--achievement-color) 14%, var(--color-bg));
}
.activity-card.event-card-filled[data-group] {
  --stack-1: color-mix(in srgb, var(--achievement-color) 56%, var(--color-bg));
  --stack-2: color-mix(in srgb, var(--achievement-color) 36%, var(--color-bg));
  --stack-3: color-mix(in srgb, var(--achievement-color) 20%, var(--color-bg));
}
.event-card-standard.activity-card[data-group],
.event-card-standard.activity-card[data-group]:hover,
.event-card-standard.event-card-filled.activity-card[data-group]:hover {
  box-shadow: 0 11px 0 -6px var(--stack-1), 0 20px 0 -11px var(--stack-2), 0 29px 0 -16px var(--stack-3);
}
/* Стопка карточки медиа (видео, фото) — в цвет изображения (ActivityCard: .activity-card-pile в поле медиа, с картинкой
   первой плитки фоном обёртки — слои её наследуют). Пиксели не читаются (картинки чужие, без CORS) — каждый слой та же картинка фоном, сильно
   размытая (--blur-panel), и поверх фон страницы 44/64/80% — ближний насыщеннее, дальний тает к фону, как у залитой.
   Геометрия — как у теней выше: ниже на 5/9/13, уже на 6/11/16 от внешнего края карточки (с рамкой — от края рамки),
   скругление 26/21/16; видно то, что не закрыто медиа: под карточкой и в углах у её скругления. Картинка слоя — поле медиа и под ним его зеркальная
   копия (на стыке размытие не тает), вместе растянуты вширь (по бокам тоже): цвет слоя — низа медиа, как продолжение. Широкая (side): под шапкой —
   тени цвета карточки, под медиа — эти слои от его левого края. Нет картинки — разметки нет, слои — тени. */
/* Слои — под медиа (z-index -1 в своей карточке, isolation), видны и под низом, и в углах у скругления карточки — как тени:
   срез сверху на радиус карточки выше её низа, внутри карточки их закрывает медиа. */
.activity-card[data-cover]:has(.activity-card-pile) { isolation: isolate; }
.activity-card-pile { position: absolute; inset: 0; z-index: -1; pointer-events: none; --pile-edge: 0px; background-size: 0 0; background-repeat: no-repeat; }
/* Картинка обёртки — только носитель для слоёв (сама не рисуется); загрузку ведёт Iwent.watchImages — скелетона у обёртки нет,
   пока снимок грузится или его нет, слой — цвет заглушки фото. */
.activity-card-pile[data-img] { background-color: transparent; box-shadow: none; animation: none; }
.activity-card.event-card-bordered .activity-card-pile { --pile-edge: 2px; }
.activity-card-pile > span {
  --pile-x: calc(var(--pile-in) - var(--pile-edge));
  --pile-y: calc(var(--pile-down) + var(--pile-edge));
  position: absolute; top: var(--pile-down); bottom: calc(-1 * var(--pile-y)); left: var(--pile-x); right: var(--pile-x);
  overflow: hidden; border-radius: var(--pile-r);
  clip-path: inset(calc(100% - var(--pile-down) - var(--radius-xl)) 0 0 0);
  background: var(--color-photo-bg); background-image: inherit; background-size: 0 0; background-repeat: no-repeat;
}
.activity-card-pile > span > span {
  position: absolute; top: calc(-1 * var(--pile-down)); bottom: var(--pile-y); left: calc(-1 * var(--pile-x)); right: calc(-1 * var(--pile-x));
  background-image: inherit; background-size: 0 0; background-repeat: no-repeat;
  transform: scaleX(1.5); filter: var(--blur-panel);
}
.activity-card-pile > span > span::before, .activity-card-pile > span > span::after {
  content: ''; position: absolute; left: 0; right: 0; height: 100%;
  background-image: inherit; background-position: center; background-size: cover; background-repeat: no-repeat;
}
.activity-card-pile > span > span::before { top: 0; }
.activity-card-pile > span > span::after { top: 100%; transform: scaleY(-1); }
.activity-card-pile > span::after { content: ''; position: absolute; inset: 0; background: var(--color-bg); opacity: var(--pile-fade); }
.activity-card-pile > :nth-child(1) { --pile-down: 5px; --pile-in: 6px; --pile-r: 26px; --pile-fade: 0.44; z-index: 3; }
.activity-card-pile > :nth-child(2) { --pile-down: 9px; --pile-in: 11px; --pile-r: 21px; --pile-fade: 0.64; z-index: 2; }
.activity-card-pile > :nth-child(3) { --pile-down: 13px; --pile-in: 16px; --pile-r: 16px; --pile-fade: 0.8; z-index: 1; }
/* Широкая: слои картинки под медиа — зеркально правому краю: от левого края медиа уже на 6/11/16 (ступеньки) со
   скруглением слоя, ближний слой огибает скруглённый угол медиа (как справа — угол карточки), левее — стопка цвета карточки;
   срез — как у остальных: на радиус выше низа карточки (внутри её закрывает медиа). */
.activity-card.news-card--wide[data-cover="side"] .activity-card-pile > span { left: var(--pile-x); border-bottom-left-radius: var(--pile-r); }
.activity-card.news-card--wide[data-cover="side"] .activity-card-pile > span > span { left: 0; }
/* Тени под слоями-картинками не нужны (по краю скругления проступали бы): у full и below их нет; у широкой — остаются под шапкой. */
/* С рамкой — стопка цвета рамки (как у групповых записей), не картинки. */
.activity-card.event-card-bordered .activity-card-pile { display: none; }
.activity-card[data-group]:not([data-cover="side"], .event-card-bordered):has(> .activity-card-body > .activity-card-pile) { --stack-1: transparent; --stack-2: transparent; --stack-3: transparent; }
/* Карточка ниже на глубину стопки — низ стопки вровень с низом соседних карточек ряда (на телефоне высота по содержимому — без сдвига). */
.events > .activity-card[data-group] { align-self: start; height: calc(100% - var(--stack-depth-activity)); }
@media (max-width: 767px) {
  .events > .activity-card[data-group] { height: auto; margin-bottom: var(--stack-depth-activity); }
  /* Широкая — колонкой, как below: слои-картинки под всей шириной медиа, теней под ними нет. */
  .activity-card.news-card--wide[data-cover="side"] .activity-card-pile > span { left: var(--pile-x); border-bottom-left-radius: var(--pile-r); }
  .activity-card.news-card--wide[data-cover="side"] .activity-card-pile > span > span { left: calc(-1 * var(--pile-x)); }
  .activity-card.news-card--wide[data-cover="side"][data-group]:not(.event-card-bordered):has(> .activity-card-body > .activity-card-pile) { --stack-1: transparent; --stack-2: transparent; --stack-3: transparent; }
}

/* Рекомендация в обычной карточке ленты: «Подписаться» под событием во всю ширину, через 16 (как шкала у «Оцените»). */
.activity-card[data-kind="recommend"]:not(.news-card--wide, .news-card--tall) .activity-card-body > .event-actions { align-self: stretch; margin-top: var(--space-2); }

/* Ссылка в строке сведений шапки карточки ленты (тема в причине рекомендации) — как тема в причине стикера
   (.news-lead a): жирная, основным цветом (второстепенный — только у текста), без подчёркивания; наведение — бренд,
   на залитой — белая, наведение — белый 64%. */
.activity-card > .list-row .list-row-meta a { color: var(--color-ink); font-weight: var(--weight-bold); text-decoration: none; transition: color var(--duration-base) var(--ease-out); }
.activity-card.event-card-filled > .list-row .list-row-meta a { color: var(--color-surface); }
.activity-card > .list-row .list-row-meta a:is(:hover, :focus-visible) { color: var(--color-brand); }
.activity-card.event-card-filled > .list-row .list-row-meta a:is(:hover, :focus-visible) { color: var(--color-on-dark-64); }


/* ---------------------------------------------------------------------------
 * PostSlide — картинка поста в Telegram-канал (ui.PostSlide, tg-post.html). Вид — ленты:
 * фото во весь кадр, панели — .priority-panel (стекло / заливка категории), их цвета и
 * текст берутся из events.css как есть; здесь только раскладка. Градиентов нет.
 * ------------------------------------------------------------------------- */
.post-slide {
  position: relative;
  box-sizing: border-box;
  width: var(--post-slide-width);
  height: var(--post-slide-height);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  background: var(--event-type-color, var(--color-brand)) center / cover no-repeat;
}
.post-slide.has-photo { background-color: var(--color-photo-bg); }
.post-slide .post-slide-panel {
  height: auto;
  min-height: 0;
  padding: var(--space-6);
  border-radius: var(--radius-lg);  /* как у строки дайджеста (EventCard row) — один радиус на всех плашках картинок */
  cursor: default;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
/* Событие: аватарка слева, название справа (как строка списка); описание и плашки ниже. */
.post-slide-head { display: flex; align-items: center; gap: var(--space-4); }
.post-slide-head .event-avatar { flex-shrink: 0; }
.post-slide .post-slide-head .event-title { flex: 1 1 0; min-width: 0; align-self: center; }  /* название — по центру аватарки по высоте (общее правило .post-slide .event-title растягивает) */
/* Аватарка на стеклянной панели поста — Avatar badge 'filled' (обводка и бейдж цвета категории, значок белый). */
/* Верх картинки: логотип и стрелка. */
.post-slide-bar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
/* Button 'glass' и контейнер логотипа поста — одно стекло: --color-overlay-32 и --blur-panel
   (как стеклянная панель крупной карточки), без рамки, белый знак. Высота — 44, как у кнопки. */
.btn-glass, .post-slide-logo {
  box-sizing: border-box;
  height: var(--control-height);
  background: var(--color-overlay-32);
  -webkit-backdrop-filter: var(--blur-panel);
  backdrop-filter: var(--blur-panel);
  border: 0;
  color: var(--color-surface);
}
.btn-glass:hover:not(:disabled), .btn-glass.is-hover { background: var(--color-overlay-32); color: var(--color-surface); }
/* Без подписи — квадрат 44×44: рамки нет, поэтому поле на её 1px больше, чем у .btn-icon (11 + 1). */
.btn-glass.btn-icon { padding: var(--space-3); }
.post-slide-logo {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
}
/* Дайджест: фон страницы сайта, сверху логотип и категория, ниже строки списка (EventGrid list) у нижнего края. */
.post-slide.post-slide--digest, .post-slide.post-slide--wide {
  width: var(--post-slide-digest-width);
  height: var(--post-slide-digest-height);
  gap: var(--space-4);
}
.post-slide.post-slide--digest { background: var(--color-bg); justify-content: flex-start; }
/* Строки — в поле картинки, а не от края до края, как сетка ленты на телефоне. */
.post-slide--digest .events { margin: auto 0 0; }  /* строки — у нижнего края, пустота под шапкой */
.post-slide--digest .post-slide-bar { padding-left: var(--space-2); }
/* Категория слайда — выбранный фильтр сайта (белая плашка, FilterButton active), но текст тёмный, без синего (решение 27.10.2026). */
.post-slide--digest .post-slide-bar .filter-btn.active { color: var(--color-ink); }
.post-slide .post-slide-panel--cover { align-items: center; text-align: center; gap: var(--space-4); }
.post-slide--wide .post-slide-text { font-size: var(--text-sm); line-height: 1.43; }  /* строка дат обложки дайджеста — прежнего кегля */
.post-slide-bar--center { justify-content: center; }  /* обложка: логотип по центру, стрелок нет */
.post-slide .event-title { margin: 0; align-self: stretch; -webkit-line-clamp: 3; }
.post-slide .post-slide-panel--cover .event-title { text-align: center; }
.post-slide .post-slide-panel--cover .event-title { font-size: var(--text-2xl); line-height: 1.33; -webkit-line-clamp: 4; }
.post-slide .event-place { margin: 0; }
/* Возраст после названия (CardTitle age): тот же кегль, полупрозрачный; на белой панели — второстепенный цвет. */
.event-title-age { color: var(--color-on-dark-32); }  /* возраст в названии — 32%, как у KudaGo (решение 27.10.2026) */
.event-card-standard:not(.event-card-filled) .event-title-age { color: var(--color-ink-32); }
.post-slide-text {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: 1.33;
  color: var(--color-on-dark-80);
  display: -webkit-box;
  -webkit-line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Источники фото — одна строка серым под панелью (на фото) или строками (дайджест, светлый слайд). */
.post-slide-credit {
  flex-shrink: 0;
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  line-height: 1.33;
  color: var(--color-on-dark-80);
  text-shadow: 0 0 var(--space-2) var(--color-overlay-32), 0 0 var(--space-1) var(--color-overlay-32), 0 0 var(--space-1) var(--color-overlay-32), 0 0 var(--space-2) var(--color-overlay-32);  /* ореол: подпись читается на светлом низе фото */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.post-slide--digest .post-slide-credit { color: var(--color-ink-secondary); text-shadow: none; }
.post-slide .post-slide-panel { margin-top: auto; }
/* Полоса между шапкой и панелью: подпись источника в ней повёрнута (снизу вверх), у правого края, по центру полосы — зазоры до шапки и панели равны. */
.post-slide-side {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
.post-slide-side .post-slide-credit {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  max-height: 100%;
}
/* Плашки даты и места мельче обычных (DatePlace compact, картинка поста): кегль --text-2xs, отступы ужаты. */
.event-card-standard .event-place--compact { gap: var(--space-1); }
.event-card-standard .event-place--compact .event-date,
.event-card-standard .event-place--compact .event-location { padding: var(--space-1) var(--space-2); font-size: var(--text-2xs); line-height: 1.4; }
.post-slide-arrow { flex-shrink: 0; }
.post-slide-arrows { display: flex; gap: var(--space-2); flex-shrink: 0; }
/* Белая панель (PostSlide panel 'white': .event-card-standard без заливки): описание — второстепенным тёмным цветом. */
.post-slide .post-slide-panel:not(.event-card-filled) .post-slide-text { color: var(--color-ink-secondary); }
/* Логотип белым (Logo inverse — на фото и цветном): знак, слово и галочка над «й». */
.logo--inverse path[fill] { fill: var(--color-surface); }
.logo--inverse path[stroke] { stroke: var(--color-surface); }

/* ---------------------------------------------------------------------------
 * EventStories / EventStory — лента «Листать» (прототип, listat.html; docs/ui.md «Листать»):
 * события во весь экран, листаются вверх по одной (scroll-snap), снимки — вбок. Вид частей —
 * готовый: панель — стеклянная .priority-panel (events.css) в раскладке её телефонного вида
 * (аватарка 64 слева от названия и тегов, плашки ниже), кнопки — Button glass на фото (телефон) и
 * обычные Button / FilterButton на фоне страницы (компьютер; оба набора в разметке, виден один —
 * display по ширине), фильтры — Dropdown и TypePick в окне. Здесь только раскладка: вида кнопок
 * этот блок не меняет.
 * ------------------------------------------------------------------------- */
.event-stories {
  position: relative;
  width: 100%;
  /* Раздел внутри общей раскладки: остаток экрана под шапкой сайта (и над нижним меню на телефоне). */
  height: calc(100vh - var(--header-height) - var(--bottom-nav-offset, 0px));
  height: calc(100dvh - var(--header-height) - var(--bottom-nav-offset, 0px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--color-bg);
}
/* Кнопка настроек: на телефоне — Button glass в правом верхнем углу поверх фото, на компьютере —
   FilterButton вверху столбца справа от карточки (на фоне страницы). Второй из пары скрыт. */
.event-stories-tools {
  position: absolute;
  top: var(--space-4);
  right: var(--space-6);
  z-index: 2;
}
/* «Назад» (BackButton) — в левом верхнем углу раздела с отступом страницы (как .content-inner). */
.event-stories > .back-row { position: absolute; top: var(--space-6); left: var(--space-6); z-index: 2; margin-bottom: 0; }
/* «Предыдущее / Следующее» — столбиком у правого края раздела, по центру высоты. */
.event-stories-nav {
  position: absolute;
  top: 50%;
  right: var(--space-6);
  z-index: 2;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.event-stories-feed {
  flex: 1 1 0;
  width: 100%;
  min-height: 0;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.event-stories-feed::-webkit-scrollbar { display: none; }
.event-story {
  position: relative;
  height: 100%;
  overflow: hidden;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  background: var(--color-hero-bg);
}
/* Медиа — во всю карточку; слайды вбок по одному. */
.event-story-media {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.event-story-media::-webkit-scrollbar { display: none; }
.event-story-slide {
  position: relative;
  flex: 0 0 100%;
  height: 100%;
  display: grid;
  place-items: center;
  scroll-snap-align: start;
}
.event-story-play { position: absolute; inset: 0; display: grid; place-items: center; }
.event-story-slide > .media-player { border-radius: 0; }
/* Вертикальный клип — во всю карточку (она сама вертикальная; поля, если есть, — у плеера VK). */
.event-story-slide > .media-player--vertical { width: 100%; height: 100%; aspect-ratio: auto; }
/* Поверх медиа: столбик действий справа и панель события внизу; мимо них жесты — медиа (листание вбок). */
.event-story-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-4);
  padding: var(--space-4);
  pointer-events: none;
}
.event-story-actions {
  align-self: flex-end;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
  pointer-events: auto;
}
/* Панель — раскладка телефонной крупной карточки (events.css, .priority-panel ≤ 767px) на любой ширине:
   колонка ленты всегда шириной телефона. */
.event-story .event-story-panel {
  height: auto;
  min-height: 0;
  padding: var(--space-mobile);
  border-radius: var(--radius-lg);
  display: grid;
  grid-template-columns: calc(var(--row-avatar-lg) / 2) minmax(0, 1fr);
  grid-template-areas:
    "avatar title"
    "avatar tags"
    "place  place";
  column-gap: var(--space-4);
  align-items: center;
  cursor: default;
  pointer-events: auto;
}
.event-story .event-story-panel .event-avatar { grid-area: avatar; width: calc(var(--row-avatar-lg) / 2); height: calc(var(--row-avatar-lg) / 2); }
.event-story .event-story-panel .event-title { grid-area: title; align-self: end; margin: 0 0 var(--space-1); -webkit-line-clamp: 3; }
.event-story .event-story-panel .event-tags { grid-area: tags; align-self: start; margin: 0; }
.event-story .event-story-panel .event-place { grid-area: place; margin-top: var(--space-4); }
/* Панель целиком не кликабельна (ссылки — название, теги, дата, место): без тени наведения. */
.event-story .event-story-panel:hover { box-shadow: none; }
/* Загрузка — заглушка во всю карточку; пусто и ошибка — по центру на фоне страницы. */
.event-story--loading > .show-skeleton { position: absolute; inset: 0; height: auto; border-radius: 0; }
.event-story--state { display: grid; place-items: center; padding: var(--space-4); background: var(--color-bg); }
/* Окно «Подробнее»: описание и «Страница события» — через 24. */
.event-story-more { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-6); }

/* Компьютер: карточка — колонка шириной телефона по центру, скруглённая; лента во всю ширину раздела,
   поля по бокам карточки (--story-side, не уже --story-gutter) — под столбик действий справа (как у
   TikTok, прижат к низу карточки) и куски карусели снимков. */
@media (min-width: 768px) {
  .event-story {
    --story-side: max(var(--story-gutter), calc((100% - var(--story-width)) / 2));
    /* Сколько по высоте занимают кнопки столбца (до трёх 44 через 8 и отступ 16) — куски карусели их не задевают. */
    --story-reserve: calc(3 * var(--control-height) + 2 * var(--space-2) + var(--space-4));
    padding: var(--space-4) var(--story-side);
    background: transparent;
  }
  /* Кнопка настроек — первой в столбце справа от карточки, на уровне её верха (лента по центру области). */
  .event-stories-tools { left: calc(50% + var(--story-width) / 2 + var(--space-4)); right: auto; width: 64px; display: flex; justify-content: center; }
  /* Карусель-стопка (как .collection-card: из-под верхней торчит часть нижней): показанный слайд (data-pos 0) —
     во всю карточку и сверху; следующий (±1, половина ширины и высоты) заходит под него так, что видна четверть
     его ширины; ±2 (четверть размера) — из-под ±1 такой же четвертью своей ширины, меньшей полосой; ±3 прячутся
     под ±2. Выше места между кнопками столбца не растут. Смена показанного — перекрёстная прозрачность
     (Iwent.initStories, --duration-slow, --ease-in-out), места меняются сразу. */
  /* isolation: порядок слайдов (z-index ниже) — только внутри ленты снимков, панель события (.event-story-overlay) остаётся сверху. */
  .event-story-media { inset: var(--space-4) var(--story-side); display: block; overflow: visible; scroll-snap-type: none; border-radius: var(--radius-xl); isolation: isolate; }
  .event-story-slide {
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    height: 100%;
    transform: translate(var(--story-drag, 0px), -50%);
    border-radius: inherit;
    overflow: hidden;
    background: var(--color-hero-bg);
    cursor: pointer;
    transition: transform var(--duration-slow) var(--ease-in-out);
  }
  .event-story-slide[data-pos="0"] { z-index: 4; }
  .event-story-slide:is([data-pos="1"], [data-pos="-1"]) { z-index: 3; }
  .event-story-slide:is([data-pos="2"], [data-pos="-2"]) { z-index: 2; }
  .event-story-slide:is([data-pos="3"], [data-pos="-3"]) { z-index: 1; }
  .event-story-slide[data-pos="0"] { cursor: grab; }
  /* Перетаскивание мышью: снимки едут за курсором без перехода, текст не выделяется. */
  .event-story-media[data-dragging] { user-select: none; }
  .event-story-media[data-dragging] .event-story-slide { transition: none; cursor: grabbing; }
  .event-story-slide:is([data-pos="1"], [data-pos="-1"]) { width: 50%; height: min(50%, 100% - 2 * var(--story-reserve)); }
  .event-story-slide:is([data-pos="2"], [data-pos="-2"], [data-pos="3"], [data-pos="-3"]) { width: 25%; height: min(25%, 100% - 2 * var(--story-reserve)); }
  /* Края: ±1 торчит на 12.5% (четверть своих 50%) от края карточки, ±2 ещё на 6.25% (четверть своих 25%). */
  .event-story-slide[data-pos="1"] { left: 62.5%; }
  .event-story-slide[data-pos="2"] { left: 93.75%; }
  .event-story-slide[data-pos="3"] { left: 93.75%; }
  .event-story-slide[data-pos="-1"] { left: -12.5%; }
  .event-story-slide[data-pos="-2"] { left: -18.75%; }
  .event-story-slide[data-pos="-3"] { left: -18.75%; }
  .event-story-slide:is([data-pos="3"], [data-pos="-3"]) { opacity: 0; visibility: hidden; }
  /* На куске видео — только кадр. */
  .event-story-slide:not([data-pos="0"]) > .event-story-play { display: none; }
  .event-story-overlay { inset: var(--space-4) var(--story-side); }
  /* Справа от карточки — на фоне страницы: обычные Button (.event-story-side); стеклянный столбик на фото и стеклянная кнопка настроек скрыты. */
  .event-stories-tools > .btn-glass, .event-story-actions { display: none; }
  .event-story-side {
    position: absolute;
    left: calc(100% + var(--space-4));
    bottom: 0;
    width: max-content;
    min-width: 64px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    pointer-events: auto;
  }
  .event-story--loading > .show-skeleton { inset: var(--space-4) var(--story-side); border-radius: var(--radius-xl); }
}

/* Телефон: лента во весь экран под шапкой сайта, поля — --space-mobile, снизу ещё safe-area. Кнопка
   настроек — в правом верхнем углу поверх карточки. */
@media (max-width: 767px) {
  .event-stories { background: var(--color-hero-bg); }
  .event-stories-tools { right: var(--space-mobile); }
  /* На фото — стекло: столбик .event-story-actions и Button glass настроек; обычные (для фона страницы) скрыты. */
  .event-stories-tools > .filter-btn, .event-story-side, .event-stories-nav { display: none; }
  /* «Назад» — своей строкой над лентой на фоне страницы (как у внутренних страниц: поля 20), кнопка
     настроек — FilterButton в той же строке справа (стеклянная — только поверх фото). */
  .event-stories > .back-row { position: static; padding: var(--space-mobile); background: var(--color-bg); }
  .event-stories--back > .event-stories-tools { top: var(--space-mobile); }
  .event-stories--back > .event-stories-tools > .filter-btn { display: inline-flex; }
  .event-stories--back > .event-stories-tools > .btn-glass { display: none; }
  .event-story { background: var(--color-hero-bg); }
  .event-story-overlay { padding: var(--space-mobile); padding-bottom: calc(var(--space-mobile) + env(safe-area-inset-bottom)); }
  .event-story .event-story-panel { margin-top: 0; }
}

