/* ibm-plex-sans-cyrillic-ext-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(fonts/ibm-plex-sans-cyrillic-ext-300-normal.04106d05.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-ext-300-normal.88db5b37.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(fonts/ibm-plex-sans-cyrillic-300-normal.8e77bd22.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-300-normal.c8279f31.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(fonts/ibm-plex-sans-greek-300-normal.1a049a2f.woff2) format('woff2'), url(fonts/ibm-plex-sans-greek-300-normal.a732aa8f.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(fonts/ibm-plex-sans-vietnamese-300-normal.34051453.woff2) format('woff2'), url(fonts/ibm-plex-sans-vietnamese-300-normal.ca70af64.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-ext-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(fonts/ibm-plex-sans-latin-ext-300-normal.9da013bc.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-ext-300-normal.949e4f85.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-sans-latin-300-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 300;
  src: url(fonts/ibm-plex-sans-latin-300-normal.79408cce.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-300-normal.38334202.woff) format('woff');
  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;
}
/* ibm-plex-sans-cyrillic-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-sans-cyrillic-ext-400-normal.c7f19d67.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-ext-400-normal.5b7e59c2.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-sans-cyrillic-400-normal.f55992be.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-400-normal.c4aae3aa.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-sans-greek-400-normal.173a235d.woff2) format('woff2'), url(fonts/ibm-plex-sans-greek-400-normal.c71f9181.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-sans-vietnamese-400-normal.a9c0738f.woff2) format('woff2'), url(fonts/ibm-plex-sans-vietnamese-400-normal.c17b6e03.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-sans-latin-ext-400-normal.11781b13.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-ext-400-normal.24d83b52.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-sans-latin-400-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-sans-latin-400-normal.3160b5c6.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-400-normal.65b2eda7.woff) format('woff');
  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;
}
/* ibm-plex-sans-cyrillic-ext-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-sans-cyrillic-ext-500-normal.bf4ba768.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-ext-500-normal.502b7494.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-sans-cyrillic-500-normal.aa1edf9c.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-500-normal.d010060b.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-sans-greek-500-normal.b4df5194.woff2) format('woff2'), url(fonts/ibm-plex-sans-greek-500-normal.94671ea6.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-sans-vietnamese-500-normal.032cc11f.woff2) format('woff2'), url(fonts/ibm-plex-sans-vietnamese-500-normal.89666946.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-ext-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-sans-latin-ext-500-normal.d8f3e27f.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-ext-500-normal.7e8aef37.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-sans-latin-500-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-sans-latin-500-normal.fcd7b8c3.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-500-normal.4b130dfc.woff) format('woff');
  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;
}
/* ibm-plex-sans-cyrillic-ext-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-sans-cyrillic-ext-600-normal.0a51b2f3.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-ext-600-normal.6b943717.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-sans-cyrillic-600-normal.e07c188c.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-600-normal.2e3e0b0b.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-sans-greek-600-normal.1fb74172.woff2) format('woff2'), url(fonts/ibm-plex-sans-greek-600-normal.dfea56a1.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-sans-vietnamese-600-normal.1e7f665a.woff2) format('woff2'), url(fonts/ibm-plex-sans-vietnamese-600-normal.9a97e037.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-ext-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-sans-latin-ext-600-normal.57f2c00d.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-ext-600-normal.5051947b.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-sans-latin-600-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-sans-latin-600-normal.24bc59b4.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-600-normal.d73e2e25.woff) format('woff');
  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;
}
/* ibm-plex-sans-cyrillic-ext-700-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(fonts/ibm-plex-sans-cyrillic-ext-700-normal.8743554c.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-ext-700-normal.071a0292.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-sans-cyrillic-700-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(fonts/ibm-plex-sans-cyrillic-700-normal.4760ba1e.woff2) format('woff2'), url(fonts/ibm-plex-sans-cyrillic-700-normal.9402b432.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-sans-greek-700-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(fonts/ibm-plex-sans-greek-700-normal.9db89ac0.woff2) format('woff2'), url(fonts/ibm-plex-sans-greek-700-normal.8159b6ce.woff) format('woff');
  unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}

/* ibm-plex-sans-vietnamese-700-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(fonts/ibm-plex-sans-vietnamese-700-normal.6879ecb9.woff2) format('woff2'), url(fonts/ibm-plex-sans-vietnamese-700-normal.e9d51266.woff) format('woff');
  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;
}

/* ibm-plex-sans-latin-ext-700-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(fonts/ibm-plex-sans-latin-ext-700-normal.ee3a0d8f.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-ext-700-normal.030dbfa5.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-sans-latin-700-normal */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-display: swap;
  font-weight: 700;
  src: url(fonts/ibm-plex-sans-latin-700-normal.cc104bdc.woff2) format('woff2'), url(fonts/ibm-plex-sans-latin-700-normal.07479b39.woff) format('woff');
  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;
}
/* ibm-plex-mono-cyrillic-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-mono-cyrillic-ext-400-normal.c5a38b92.woff2) format('woff2'), url(fonts/ibm-plex-mono-cyrillic-ext-400-normal.cd5f0922.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-mono-cyrillic-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-mono-cyrillic-400-normal.c6f862a9.woff2) format('woff2'), url(fonts/ibm-plex-mono-cyrillic-400-normal.c45eb954.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-mono-vietnamese-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-mono-vietnamese-400-normal.fa074729.woff2) format('woff2'), url(fonts/ibm-plex-mono-vietnamese-400-normal.d4e725bc.woff) format('woff');
  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;
}

/* ibm-plex-mono-latin-ext-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-mono-latin-ext-400-normal.081b2e53.woff2) format('woff2'), url(fonts/ibm-plex-mono-latin-ext-400-normal.52bdf764.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-mono-latin-400-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url(fonts/ibm-plex-mono-latin-400-normal.2b13cc93.woff2) format('woff2'), url(fonts/ibm-plex-mono-latin-400-normal.12ede62e.woff) format('woff');
  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;
}
/* ibm-plex-mono-cyrillic-ext-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-mono-cyrillic-ext-500-normal.0cef6163.woff2) format('woff2'), url(fonts/ibm-plex-mono-cyrillic-ext-500-normal.32dc85f4.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-mono-cyrillic-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-mono-cyrillic-500-normal.93f9e007.woff2) format('woff2'), url(fonts/ibm-plex-mono-cyrillic-500-normal.15083dee.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-mono-vietnamese-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-mono-vietnamese-500-normal.acbf2964.woff2) format('woff2'), url(fonts/ibm-plex-mono-vietnamese-500-normal.6412cb41.woff) format('woff');
  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;
}

/* ibm-plex-mono-latin-ext-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-mono-latin-ext-500-normal.c28c19b5.woff2) format('woff2'), url(fonts/ibm-plex-mono-latin-ext-500-normal.0324453e.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-mono-latin-500-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 500;
  src: url(fonts/ibm-plex-mono-latin-500-normal.a1fc5384.woff2) format('woff2'), url(fonts/ibm-plex-mono-latin-500-normal.89a2903a.woff) format('woff');
  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;
}
/* ibm-plex-mono-cyrillic-ext-600-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-mono-cyrillic-ext-600-normal.93171184.woff2) format('woff2'), url(fonts/ibm-plex-mono-cyrillic-ext-600-normal.6d7baa81.woff) format('woff');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}

/* ibm-plex-mono-cyrillic-600-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-mono-cyrillic-600-normal.5c59bb54.woff2) format('woff2'), url(fonts/ibm-plex-mono-cyrillic-600-normal.5074d429.woff) format('woff');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}

/* ibm-plex-mono-vietnamese-600-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-mono-vietnamese-600-normal.31cd33e7.woff2) format('woff2'), url(fonts/ibm-plex-mono-vietnamese-600-normal.573a63fc.woff) format('woff');
  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;
}

/* ibm-plex-mono-latin-ext-600-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-mono-latin-ext-600-normal.5d11148c.woff2) format('woff2'), url(fonts/ibm-plex-mono-latin-ext-600-normal.a4add407.woff) format('woff');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ibm-plex-mono-latin-600-normal */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 600;
  src: url(fonts/ibm-plex-mono-latin-600-normal.45199eea.woff2) format('woff2'), url(fonts/ibm-plex-mono-latin-600-normal.cc9c246a.woff) format('woff');
  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;
}
/* Self-hosted IBM Plex (OFL-licensed) — vendored via @fontsource instead of
 * linking fonts.googleapis.com/fonts.gstatic.com, so visiting Cadence no
 * longer sends every visitor's IP/user-agent to Google on every load. Same
 * weights as the old Google Fonts link; each file below still declares one
 * @font-face per Unicode range (latin, latin-ext, cyrillic, …) with the
 * matching unicode-range, so the browser only fetches what the page text
 * actually needs — identical behaviour to the CDN version, just self-served. */

*, ::before, ::after{
  --tw-border-spacing-x: 0;
  --tw-border-spacing-y: 0;
  --tw-translate-x: 0;
  --tw-translate-y: 0;
  --tw-rotate: 0;
  --tw-skew-x: 0;
  --tw-skew-y: 0;
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  --tw-pan-x:  ;
  --tw-pan-y:  ;
  --tw-pinch-zoom:  ;
  --tw-scroll-snap-strictness: proximity;
  --tw-gradient-from-position:  ;
  --tw-gradient-via-position:  ;
  --tw-gradient-to-position:  ;
  --tw-ordinal:  ;
  --tw-slashed-zero:  ;
  --tw-numeric-figure:  ;
  --tw-numeric-spacing:  ;
  --tw-numeric-fraction:  ;
  --tw-ring-inset:  ;
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: rgb(59 130 246 / 0.5);
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  --tw-blur:  ;
  --tw-brightness:  ;
  --tw-contrast:  ;
  --tw-grayscale:  ;
  --tw-hue-rotate:  ;
  --tw-invert:  ;
  --tw-saturate:  ;
  --tw-sepia:  ;
  --tw-drop-shadow:  ;
  --tw-backdrop-blur:  ;
  --tw-backdrop-brightness:  ;
  --tw-backdrop-contrast:  ;
  --tw-backdrop-grayscale:  ;
  --tw-backdrop-hue-rotate:  ;
  --tw-backdrop-invert:  ;
  --tw-backdrop-opacity:  ;
  --tw-backdrop-saturate:  ;
  --tw-backdrop-sepia:  ;
  --tw-contain-size:  ;
  --tw-contain-layout:  ;
  --tw-contain-paint:  ;
  --tw-contain-style:  ;
}

::backdrop{
  --tw-border-spacing-x: 0;
  --tw-border-spacing-y: 0;
  --tw-translate-x: 0;
  --tw-translate-y: 0;
  --tw-rotate: 0;
  --tw-skew-x: 0;
  --tw-skew-y: 0;
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  --tw-pan-x:  ;
  --tw-pan-y:  ;
  --tw-pinch-zoom:  ;
  --tw-scroll-snap-strictness: proximity;
  --tw-gradient-from-position:  ;
  --tw-gradient-via-position:  ;
  --tw-gradient-to-position:  ;
  --tw-ordinal:  ;
  --tw-slashed-zero:  ;
  --tw-numeric-figure:  ;
  --tw-numeric-spacing:  ;
  --tw-numeric-fraction:  ;
  --tw-ring-inset:  ;
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: rgb(59 130 246 / 0.5);
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  --tw-blur:  ;
  --tw-brightness:  ;
  --tw-contrast:  ;
  --tw-grayscale:  ;
  --tw-hue-rotate:  ;
  --tw-invert:  ;
  --tw-saturate:  ;
  --tw-sepia:  ;
  --tw-drop-shadow:  ;
  --tw-backdrop-blur:  ;
  --tw-backdrop-brightness:  ;
  --tw-backdrop-contrast:  ;
  --tw-backdrop-grayscale:  ;
  --tw-backdrop-hue-rotate:  ;
  --tw-backdrop-invert:  ;
  --tw-backdrop-opacity:  ;
  --tw-backdrop-saturate:  ;
  --tw-backdrop-sepia:  ;
  --tw-contain-size:  ;
  --tw-contain-layout:  ;
  --tw-contain-paint:  ;
  --tw-contain-style:  ;
}

/* ! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com *//*
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
*/

*,
::before,
::after {
  box-sizing: border-box; /* 1 */
  border-width: 0; /* 2 */
  border-style: solid; /* 2 */
  border-color: #e5e7eb; /* 2 */
}

::before,
::after {
  --tw-content: '';
}

/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
3. Use a more readable tab size.
4. Use the user's configured `sans` font-family by default.
5. Use the user's configured `sans` font-feature-settings by default.
6. Use the user's configured `sans` font-variation-settings by default.
7. Disable tap highlights on iOS
*/

html,
:host {
  line-height: 1.5; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
  -moz-tab-size: 4; /* 3 */
  -o-tab-size: 4;
     tab-size: 4; /* 3 */
  font-family: IBM Plex Sans, system-ui, sans-serif; /* 4 */
  font-feature-settings: normal; /* 5 */
  font-variation-settings: normal; /* 6 */
  -webkit-tap-highlight-color: transparent; /* 7 */
}

/*
1. Remove the margin in all browsers.
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
*/

body {
  margin: 0; /* 1 */
  line-height: inherit; /* 2 */
}

/*
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
3. Ensure horizontal rules are visible by default.
*/

hr {
  height: 0; /* 1 */
  color: inherit; /* 2 */
  border-top-width: 1px; /* 3 */
}

/*
Add the correct text decoration in Chrome, Edge, and Safari.
*/

abbr:where([title]) {
  -webkit-text-decoration: underline dotted;
          text-decoration: underline dotted;
}

/*
Remove the default font size and weight for headings.
*/

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}

/*
Reset links to optimize for opt-in styling instead of opt-out.
*/

a {
  color: inherit;
  text-decoration: inherit;
}

/*
Add the correct font weight in Edge and Safari.
*/

b,
strong {
  font-weight: bolder;
}

/*
1. Use the user's configured `mono` font-family by default.
2. Use the user's configured `mono` font-feature-settings by default.
3. Use the user's configured `mono` font-variation-settings by default.
4. Correct the odd `em` font sizing in all browsers.
*/

code,
kbd,
samp,
pre {
  font-family: IBM Plex Mono, ui-monospace, monospace; /* 1 */
  font-feature-settings: normal; /* 2 */
  font-variation-settings: normal; /* 3 */
  font-size: 1em; /* 4 */
}

/*
Add the correct font size in all browsers.
*/

small {
  font-size: 80%;
}

/*
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
*/

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/*
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
3. Remove gaps between table borders by default.
*/

table {
  text-indent: 0; /* 1 */
  border-color: inherit; /* 2 */
  border-collapse: collapse; /* 3 */
}

/*
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
3. Remove default padding in all browsers.
*/

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-feature-settings: inherit; /* 1 */
  font-variation-settings: inherit; /* 1 */
  font-size: 100%; /* 1 */
  font-weight: inherit; /* 1 */
  line-height: inherit; /* 1 */
  letter-spacing: inherit; /* 1 */
  color: inherit; /* 1 */
  margin: 0; /* 2 */
  padding: 0; /* 3 */
}

/*
Remove the inheritance of text transform in Edge and Firefox.
*/

button,
select {
  text-transform: none;
}

/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Remove default button styles.
*/

button,
input:where([type='button']),
input:where([type='reset']),
input:where([type='submit']) {
  -webkit-appearance: button; /* 1 */
  background-color: transparent; /* 2 */
  background-image: none; /* 2 */
}

/*
Use the modern Firefox focus style for all focusable elements.
*/

:-moz-focusring {
  outline: auto;
}

/*
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
*/

:-moz-ui-invalid {
  box-shadow: none;
}

/*
Add the correct vertical alignment in Chrome and Firefox.
*/

progress {
  vertical-align: baseline;
}

/*
Correct the cursor style of increment and decrement buttons in Safari.
*/

::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
  height: auto;
}

/*
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/

[type='search'] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/*
Remove the inner padding in Chrome and Safari on macOS.
*/

::-webkit-search-decoration {
  -webkit-appearance: none;
}

/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to `inherit` in Safari.
*/

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/*
Add the correct display in Chrome and Safari.
*/

summary {
  display: list-item;
}

/*
Removes the default spacing and border for appropriate elements.
*/

blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
  margin: 0;
}

fieldset {
  margin: 0;
  padding: 0;
}

legend {
  padding: 0;
}

ol,
ul,
menu {
  list-style: none;
  margin: 0;
  padding: 0;
}

/*
Reset default styling for dialogs.
*/
dialog {
  padding: 0;
}

/*
Prevent resizing textareas horizontally by default.
*/

textarea {
  resize: vertical;
}

/*
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
2. Set the default placeholder color to the user's configured gray 400 color.
*/

input::-moz-placeholder, textarea::-moz-placeholder {
  opacity: 1; /* 1 */
  color: #9ca3af; /* 2 */
}

input::placeholder,
textarea::placeholder {
  opacity: 1; /* 1 */
  color: #9ca3af; /* 2 */
}

/*
Set the default cursor for buttons.
*/

button,
[role="button"] {
  cursor: pointer;
}

/*
Make sure disabled buttons don't get the pointer cursor.
*/
:disabled {
  cursor: default;
}

/*
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
   This can trigger a poorly considered lint error in some tools but is included by design.
*/

img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block; /* 1 */
  vertical-align: middle; /* 2 */
}

/*
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
*/

img,
video {
  max-width: 100%;
  height: auto;
}

/* Make elements with the HTML hidden attribute stay hidden by default */
[hidden]:where(:not([hidden="until-found"])) {
  display: none;
}
  * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
  /* Tracks the live visual viewport (dvh reacts natively to mobile browser chrome
     showing/hiding) instead of a JS snapshot of window.innerHeight — see zoomService.ts. */
  #app { height: calc(100dvh / var(--zoom-factor, 1)); padding-left: var(--safe-left); padding-right: var(--safe-right); }
  /* iOS (class set by index.html's bootstrap). The shell never scrolls, only
     panes inside it: without these, a pane pulled past its end hands the drag
     on to the page, which rubber-bands the whole app when installed and, in a
     Safari tab, can pull to refresh — a reload in the middle of a live. And no
     double-tap zoom on text either; pinching still zooms. */
  html.\!ios, html.\!ios body { overscroll-behavior: none !important; touch-action: manipulation !important; }
  html.ios, html.ios body { overscroll-behavior: none; touch-action: manipulation; }
  html.\!ios, html.\!ios body { overscroll-behavior: none !important; touch-action: manipulation !important; }
  html.\!ios .overflow-y-auto, html.\!ios .overflow-auto { overscroll-behavior-y: contain !important; }
  html.ios .overflow-y-auto, html.ios .overflow-auto { overscroll-behavior-y: contain; }
  html.\!ios .overflow-y-auto, html.\!ios .overflow-auto { overscroll-behavior-y: contain !important; }
  /* What a long press opens a menu on (longPress.ts): no word selected, no
     link preview, competing with it. */
  html.\!ios [data-long-press] { -webkit-touch-callout: none !important; -webkit-user-select: none !important; -moz-user-select: none !important; user-select: none !important; }
  html.ios [data-long-press] { -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; user-select: none; }
  /* A press held a moment on a button selected its label, with the magnifier
     and the blue handles (iOS simulator, 2026-10-15): a control is not text. */
  html.\!ios button, html.\!ios [role="button"] { -webkit-user-select: none !important; -moz-user-select: none !important; user-select: none !important; }
  html.ios button, html.ios [role="button"] { -webkit-user-select: none; -moz-user-select: none; user-select: none; }
  html.\!ios button, html.\!ios [role="button"] { -webkit-user-select: none !important; -moz-user-select: none !important; user-select: none !important; }
  /* Installed on an iPhone, the status bar is see-through with WHITE text
     (black-translucent, index.html): unreadable over a light header. A dark
     band the status bar's height goes under it, on every screen, above
     everything. Nothing at all where there is no status bar inset. */
  html.\!ios.standalone:not([data-theme="dark"]) body::before {
    content: '' !important; position: fixed !important; top: 0 !important; left: 0 !important; right: 0 !important; height: var(--safe-top) !important;
    background: #141414 !important; z-index: 2147483647 !important; pointer-events: none !important;
  }
  html.ios.standalone:not([data-theme="dark"]) body::before {
    content: ''; position: fixed; top: 0; left: 0; right: 0; height: var(--safe-top);
    background: #141414; z-index: 2147483647; pointer-events: none;
  }
  /* Installed, with that see-through status bar, WebKit's 100dvh wanders
     between the full screen (852 on an iPhone 16) and the screen minus the
     status bar (793 = svh): a white strip as tall as the status bar was seen
     at the bottom (iOS 18.6 and 26.5 simulators, 2026-10-15). No browser bars
     come and go in an installed app: the large viewport is the screen. */
  html.\!ios.standalone #app { height: calc(100lvh / var(--zoom-factor, 1)) !important; }
  html.ios.standalone #app { height: calc(100lvh / var(--zoom-factor, 1)); }
  /* Prevent double-tap zoom on interactive elements (major cause of keyboard flicker on Android) */
  button, input, select, textarea, a, label, [role="button"] { touch-action: manipulation; }
  input[type=number]::-webkit-inner-spin-button,
  input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
  input[type=number] { -moz-appearance: textfield; -webkit-appearance: textfield; appearance: textfield; }
  /* Date and time fields drawn in the theme's scheme. Without it Chromium
     draws them for a light page: a black calendar icon on our dark field,
     invisible — and on Chrome Android 155 (not 145, measured 2026-10-12) these
     fields became the desktop ones, where that icon is the only way to the
     picker. Only these fields: on the whole page, color-scheme would also
     change how embedded frames are backed. */
  input[type="date"], input[type="datetime-local"], input[type="time"], input[type="month"] {
    color-scheme: var(--native-scheme);
  }
  /* Prevent text selection on draggable elements. `data-touch-drag` too: the
     touch polyfill (utils.ts) turns `draggable` off for the length of a touch,
     and a long press would otherwise select the word under the finger. */
  [draggable="true"], [data-touch-drag] { -moz-user-select: none; user-select: none; -webkit-user-select: none; }
  ::-webkit-scrollbar { width: 6px; height: 6px; }
  ::-webkit-scrollbar-track { background: transparent; }
  ::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 3px; }
  ::-webkit-scrollbar-thumb:hover { background: var(--color-dim); }
.\!container{
  width: 100% !important;
}
.container{
  width: 100%;
}
@media (min-width: 640px){

  .\!container{
    max-width: 640px !important;
  }

  .container{
    max-width: 640px;
  }
}
@media (min-width: 768px){

  .\!container{
    max-width: 768px !important;
  }

  .container{
    max-width: 768px;
  }
}
@media (min-width: 1024px){

  .\!container{
    max-width: 1024px !important;
  }

  .container{
    max-width: 1024px;
  }
}
@media (min-width: 1280px){

  .\!container{
    max-width: 1280px !important;
  }

  .container{
    max-width: 1280px;
  }
}
@media (min-width: 1536px){

  .\!container{
    max-width: 1536px !important;
  }

  .container{
    max-width: 1536px;
  }
}
  /* ── The UI charter (review of 2026-11-11, decisions by the user) ──────────
     One drawing per concept, defined here so the vanilla-DOM code (fileViewer,
     the library export) wears the same classes as the Preact one. The rules
     these classes stand for:
     - every button, labelled or not, has a 6 px radius (rounded-md);
     - every pointer target is at least 32 px (min-h-8 / min-w-8), whatever
       the size of what is drawn inside it;
     - colours are tokens, and a status colour says a status, never decorates;
     - no text under 11 px (`text-2xs`, tailwind.config.js);
     - something easy to redo is removed at once, behind a NEUTRAL bin; what
       is costly to redo is confirmed, and confirmed in solid red. Never an
       undo afterwards. A red trigger (`icon-btn-danger`) is for an object's
       own header (a card, a deck, an analysis); a bin on a ROW of a list stays
       neutral, red under the pointer, and the confirmation carries the red.
     `npm run ui:check` (scripts/uiCheck.mjs) flags what drifts from them. */
  .btn{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-ghost{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn-ghost:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-ghost{
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .btn-ghost:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
    --tw-text-opacity: 1;
    color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
  }
}
  .btn-ghost:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  @media (hover: hover) and (pointer: fine){

  .btn-ghost:hover:disabled{
    background-color: transparent;
    --tw-text-opacity: 1;
    color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  }
}
  /* A secondary action that must still read as a button at rest: the ghost,
     framed. Was invented twice by hand before it had a name. */
  .btn-outline{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn-outline:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-outline{
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .btn-outline:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
    --tw-text-opacity: 1;
    color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
  }
}
  .btn-outline:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  @media (hover: hover) and (pointer: fine){

  .btn-outline:hover:disabled{
    background-color: transparent;
    --tw-text-opacity: 1;
    color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  }
}
  .btn-outline{
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
}
  .btn-soft{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn-soft:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-soft{
  background-color: var(--color-accent-dim);
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .btn-soft:hover{
    background-color: rgb(var(--color-accent-ch) / 0.25);
  }
}
  .btn-soft:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-primary{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn-primary:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-primary{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-accent-ch) / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .btn-primary:hover{
    background-color: var(--color-accent-hover);
  }
}
  /* A destructive TRIGGER (a Delete in a header, a Remove in a form): tinted,
     because what it opens is the question. */
  .btn-danger{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn-danger:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-danger{
  background-color: rgb(var(--color-danger-ch) / 0.1);
  --tw-text-opacity: 1;
  color: rgb(var(--color-danger-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .btn-danger:hover{
    background-color: rgb(var(--color-danger-ch) / 0.2);
  }
}
  /* The ANSWER to that question — the button that destroys. Solid, so the
     most consequential button of the dialog is not its palest. */
  .btn-danger-solid{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn-danger-solid:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-danger-solid{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-danger-ch) / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(var(--color-bg-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .btn-danger-solid:hover{
    background-color: rgb(var(--color-danger-ch) / 0.85);
  }
}
  /* The text is the page's background, not white: the dark theme's danger is
     a LIGHT red (#f87171), on which white reads at 2.8:1; the near-black bg
     reads at 7.6:1 there, and white bg on the light themes' #dc2626 at 4.8. */
  .btn-success{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn-success:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-success{
  background-color: rgb(var(--color-success-ch) / 0.1);
  --tw-text-opacity: 1;
  color: rgb(var(--color-success-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .btn-success:hover{
    background-color: rgb(var(--color-success-ch) / 0.2);
  }
}
  /* Study, the app's own action, keeps a green of its own (the user's call,
     2026-11-11) rather than the accent. Was hand-built three times. */
  .btn-study{
  cursor: pointer;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .btn-study:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .btn-study{
  background-color: rgb(var(--color-success-ch) / 0.8);
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .btn-study:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-success-ch) / var(--tw-bg-opacity, 1));
  }

  .btn-study:hover:disabled{
    background-color: rgb(var(--color-success-ch) / 0.8);
  }
}

  /* An icon control. The TARGET is the class (32 px at least, 36 and 44 for
     the larger sizes); what is drawn inside may be smaller — a 24 px disc in a
     32 px target is the incipit's pattern (incipit.tsx), and the way to keep a
     dense row's look while giving the finger its room. Hover goes on the
     button, so the ring around a smaller drawing is not a dead zone
     (add `group` beside it for a drawing that follows it — Tailwind cannot
     @apply `group`; the IconButton component sets it). */
  .icon-btn{
  display: inline-flex;
  flex-shrink: 0;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  border-radius: 0.375rem;
  --tw-text-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-text-opacity, 1));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  @media (hover: hover) and (pointer: fine){

  .icon-btn:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
    --tw-text-opacity: 1;
    color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
  }
}
  .icon-btn:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  @media (hover: hover) and (pointer: fine){

  .icon-btn:hover:disabled{
    background-color: transparent;
  }
}
  .icon-btn {
    min-width: 2rem;
    min-height: 2rem;
  }
  .icon-btn-md { min-width: 2.25rem; min-height: 2.25rem; }
  .icon-btn-lg { min-width: 2.75rem; min-height: 2.75rem; }
  /* Framed, for an icon control standing alone in a toolbar. */
  .icon-btn-outline{
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .icon-btn-outline:hover{
    border-color: rgb(var(--color-accent-ch) / 0.6);
  }
}
  /* On (a toggle that is set), or the one action a row offers. */
  .icon-btn-on{
  background-color: rgb(var(--color-accent-ch) / 0.1);
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .icon-btn-on:hover{
    background-color: rgb(var(--color-accent-ch) / 0.15);
    --tw-text-opacity: 1;
    color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
  }
}
  /* A destructive trigger on an object's header. A NEUTRAL bin is the plain
     .icon-btn with `hover:text-danger`. */
  .icon-btn-danger{
  background-color: rgb(var(--color-danger-ch) / 0.1);
  --tw-text-opacity: 1;
  color: rgb(var(--color-danger-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .icon-btn-danger:hover{
    background-color: rgb(var(--color-danger-ch) / 0.2);
    --tw-text-opacity: 1;
    color: rgb(var(--color-danger-ch) / var(--tw-text-opacity, 1));
  }
}
  /* The drawing inside a target smaller than it: the round pastille of the
     list rows (play, score, add to deck). */
  .icon-disc{
  display: inline-flex;
  height: 1.5rem;
  width: 1.5rem;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background-color: rgb(var(--color-accent-ch) / 0.1);
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  @media (hover: hover) and (pointer: fine){

  .group:hover .icon-disc{
    background-color: rgb(var(--color-accent-ch) / 0.2);
  }
}
  .icon-disc-on{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-accent-ch) / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .group:hover .icon-disc-on{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-accent-ch) / var(--tw-bg-opacity, 1));
  }
}

  /* A choice among a few, side by side: one rail, one button, one "on". */
  .seg{
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border-radius: 0.5rem;
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-bg-ch) / var(--tw-bg-opacity, 1));
  padding: 0.25rem;
}
  .seg-btn{
  display: inline-flex;
  min-height: 2rem;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  border-radius: 0.375rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  @media (hover: hover) and (pointer: fine){

  .seg-btn:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
    --tw-text-opacity: 1;
    color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
  }
}
  .seg-btn:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .seg-lg .seg-btn { min-height: 2.25rem; }
  .seg-btn-on, .seg-btn-on:hover{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-accent-ch) / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}

  /* Pills. Neutral, selected, and a toggle that is set. */
  .chip{
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border-radius: 9999px;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
  padding-left: 0.625rem;
  padding-right: 0.625rem;
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
  font-size: 0.75rem;
  line-height: 1rem;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .chip-on{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-accent-ch) / var(--tw-bg-opacity, 1));
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
  .chip-toggle-on{
  border-color: rgb(var(--color-accent-ch) / 0.6);
  background-color: rgb(var(--color-accent-ch) / 0.1);
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
}

  /* A deck a card belongs to, which opens it: the card view's header and the
     study view's, one class so they cannot drift apart again (2026-11-11 —
     the card view's had grown a border and padding the study view's lacked;
     the author preferred the study view's). Its row must be items-center: a
     32px button beside it would stretch it to its height. */
  .deck-pin{
  display: inline-flex;
  cursor: pointer;
  align-items: center;
  border-radius: 9999px;
  background-color: rgb(var(--color-accent-ch) / 0.1);
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
  font-size: 0.75rem;
  line-height: 1rem;
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  @media (hover: hover) and (pointer: fine){

  .deck-pin:hover{
    background-color: rgb(var(--color-accent-ch) / 0.2);
  }
}

  /* A count or a level, never clickable on its own. */
  .badge{
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  border-radius: 9999px;
  padding-left: 0.375rem;
  padding-right: 0.375rem;
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
  font-size: 11px;
  line-height: 1rem;
  font-weight: 500;
  --tw-numeric-spacing: tabular-nums;
  font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);
}

  /* One surface for every menu: the ⋮ one, a context menu, a select's list. */
  .menu-surface{
  border-radius: 0.5rem;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
  padding: 0.25rem;
  --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
  .menu-item{
  display: flex;
  min-height: 2.25rem;
  width: 100%;
  cursor: pointer;
  align-items: center;
  gap: 0.625rem;
  border-radius: 0.375rem;
  padding-left: 0.625rem;
  padding-right: 0.625rem;
  text-align: left;
  font-size: 0.875rem;
  line-height: 1.25rem;
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  @media (hover: hover) and (pointer: fine){

  .menu-item:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-surface-ch) / var(--tw-bg-opacity, 1));
  }
}
  .menu-item:disabled{
  cursor: not-allowed;
  opacity: 0.4;
}
  .menu-item-on{
  background-color: rgb(var(--color-accent-ch) / 0.1);
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
}
  .menu-item-danger{
  --tw-text-opacity: 1;
  color: rgb(var(--color-danger-ch) / var(--tw-text-opacity, 1));
}
  @media (hover: hover) and (pointer: fine){

  .menu-item-danger:hover{
    background-color: rgb(var(--color-danger-ch) / 0.1);
  }
}
  .menu-heading{
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  padding-left: 0.625rem;
  padding-right: 0.625rem;
  padding-top: 0.5rem;
  padding-bottom: 0.25rem;
}

  /* The rows of a dialog that offers a few ways on (Export, New card, Add a
     file). The description is always visible: a title tooltip does not exist
     under a finger. */
  .choice-card{
  display: flex;
  width: 100%;
  cursor: pointer;
  align-items: center;
  gap: 0.75rem;
  border-radius: 0.75rem;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-bg-ch) / var(--tw-bg-opacity, 1));
  padding-left: 1rem;
  padding-right: 1rem;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
  text-align: left;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  @media (hover: hover) and (pointer: fine){

  .choice-card:hover{
    border-color: rgb(var(--color-accent-ch) / 0.6);
    background-color: rgb(var(--color-accent-ch) / 0.05);
  }
}

  .empty-state{
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
  padding-left: 1rem;
  padding-right: 1rem;
  text-align: center;
  font-size: 0.875rem;
  line-height: 1.25rem;
  --tw-text-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-text-opacity, 1));
}
  .\!input{
  width: 100%;
  border-radius: 0.25rem;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-bg-ch) / var(--tw-bg-opacity, 1));
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
  .\!input::-moz-placeholder{
  --tw-placeholder-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-placeholder-opacity, 1));
}
  .\!input::placeholder{
  --tw-placeholder-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-placeholder-opacity, 1));
}
  .\!input{
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .\!input:focus{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
  outline: 2px solid transparent;
  outline-offset: 2px;
}
  .input{
  width: 100%;
  border-radius: 0.25rem;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-bg-ch) / var(--tw-bg-opacity, 1));
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
  .input::-moz-placeholder{
  --tw-placeholder-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-placeholder-opacity, 1));
}
  .input::placeholder{
  --tw-placeholder-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-placeholder-opacity, 1));
}
  .input{
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
  .input:focus{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
  outline: 2px solid transparent;
  outline-offset: 2px;
}
  /* A layer that covers the whole screen keeps its content off the system
     bars. The app is drawn behind them on Android 15+ and in an installed
     iPhone app, so what sat at the very top went under the clock (Android 16,
     the expanded audio player's header, 2026-10-12). Padding, not margin: the
     layer's own background still fills the bars' area. */
  .safe-area-pad { padding: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left); }
  .\!label{
  margin-bottom: 0.25rem;
  display: block;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
  .label{
  margin-bottom: 0.25rem;
  display: block;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
  .card-block{
  border-radius: 0.5rem;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
  padding: 1rem;
}
  .section-title{
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
  .view-enter { animation: fadeSlideIn 0.15s ease-out; }
  .knowledge-bar{
  height: 0.375rem;
  overflow: hidden;
  border-radius: 9999px;
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-border-ch) / var(--tw-bg-opacity, 1));
}
  .knowledge-fill{
  height: 100%;
  border-radius: 9999px;
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 500ms;
}
  /* An icon control sized as a TARGET rather than as a glyph — the top bar's
     buttons, and anything else small enough to be missed by a thumb.
     The header used to hand each one `px-2 py-1` around a 14 px icon — 30 × 22
     px, which is under the 24 × 24 floor of WCAG 2.2 AA (2.5.8) on one axis.
     A user reported it from the field before any of this was measured.

     ONE size for every pointer (the user's call, 2026-09-11). A coarse-pointer
     branch used to raise this to 48 px so a finger got the full 44 × 44 of
     WCAG 2.5.5 AAA / Apple's HIG, and it was removed: the header packs its
     buttons at fixed widths around an absolutely centred profile chip, so
     the wider targets pushed the row off the right edge of a phone. Between
     a header that overflows and targets that clear AA but not AAA, the
     second is the one nobody has complained about — and a phone-only branch
     is a second header to maintain for one form factor.

     `min-*` rather than fixed sizes, so a labelled control (the install pill,
     the profile chip) still sizes to its text and only gains the height.

     32 px is measured against the app's own zoom, which is NOT 100% by default
     (zoomService: 125% on desktop, 90% on a phone). What the finger meets is
     the zoomed size: 32 × 1,25 = 40 on desktop, 32 × 0,90 = 28,8 on a phone —
     both past the 24 px AA floor, the phone with less room than the desktop.
     If the touch complaint comes back, that number is why. */
  .tap-btn{
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: 0.375rem;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
    min-width: 2rem;
    min-height: 2rem;
}

  /* The header's own targets, bigger than `.tap-btn` since 2026-10-23: at 14 px
     icons in a 2.5 rem bar the header looked a size smaller than the page under
     it and than the bottom bar (a tester's remark). 40 px on a computer, 44 on
     a portrait phone — where the bar holds fewer items, the rest being in ⋮ —
     so the phone's header matches its 3.5 rem bottom bar. */
  .hdr-btn{
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: 0.375rem;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
    min-width: 2.5rem;
    min-height: 2.5rem;
}
  .hdr-phone .hdr-btn {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }

  /* The tempo mark on an incipit. HIDDEN, not removed: the ABC keeps its
     `Q:` so the ▸ beside the stave takes a reel at reel speed, while
     "♩ = 190" stops claiming a line of its own above three centimetres of
     music. abcjs ignores a zero-sized `tempofont` — tried first — so the
     class it already emits (`add_classes`) does the job instead. */
  .incipit .abcjs-tempo { display: none; }

  /* The last line of defence against a cut-off stave, and the only one that
     always holds. `staffwidth` is a REQUEST: abcjs will not compress music
     below its natural minimum, so asking for 179 px on a narrow phone still
     drew 247 and clipped the final bar (measured, which is how the request
     came in). `cropToInk` leaves a viewBox behind, so max-width + height:auto
     is all it takes for the drawing to scale down to whatever room there is —
     and to stay at its intrinsic size when there is room to spare, which is
     the whole difference from abcjs's own `responsive: 'resize'` (that one
     STRETCHES a two-bar stave across a 1600 px desktop). */
  .incipit svg { max-width: 100%; height: auto; }

  .card-checkbox {
    -moz-appearance: none;
         appearance: none; -webkit-appearance: none; position: relative; height: 0.875rem; width: 0.875rem; flex-shrink: 0; cursor: pointer; border-radius: 0.25rem; border-width: 1px; --tw-border-opacity: 1; border-color: rgb(var(--color-muted-ch) / var(--tw-border-opacity, 1)); background-color: transparent; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;
  }
  /* Flat selectors, not `&:checked` nesting: the build does not flatten CSS
     nesting, and Safari before 16.5 drops a nested rule — the box never
     looked checked. */
  .card-checkbox:checked{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-accent-ch) / var(--tw-bg-opacity, 1));
}
  .card-checkbox:checked::after {
    content: '';
    position: absolute; inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox=%270 0 10 8%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M1 4l3 3 5-6%27 stroke=%27white%27 stroke-width=%271.5%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27 fill=%27none%27/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: center; background-size: 75%;
  }
  .card-checkbox:indeterminate{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-accent-ch) / var(--tw-bg-opacity, 1));
}
  .card-checkbox:indeterminate::after {
    content: '';
    position: absolute; inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox=%270 0 10 2%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cline x1=%272%27 y1=%271%27 x2=%278%27 y2=%271%27 stroke=%27white%27 stroke-width=%271.5%27 stroke-linecap=%27round%27/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: center; background-size: 75%;
  }
.pointer-events-none{
  pointer-events: none;
}
.pointer-events-auto{
  pointer-events: auto;
}
.visible{
  visibility: visible;
}
.invisible{
  visibility: hidden;
}
.collapse{
  visibility: collapse;
}
.static{
  position: static;
}
.fixed{
  position: fixed;
}
.absolute{
  position: absolute;
}
.relative{
  position: relative;
}
.sticky{
  position: sticky;
}
.-inset-px{
  inset: -1px;
}
.inset-0{
  inset: 0px;
}
.inset-x-0{
  left: 0px;
  right: 0px;
}
.inset-y-0{
  top: 0px;
  bottom: 0px;
}
.-bottom-0\.5{
  bottom: -0.125rem;
}
.-bottom-1{
  bottom: -0.25rem;
}
.-bottom-4{
  bottom: -1rem;
}
.-left-\[7px\]{
  left: -7px;
}
.-right-0\.5{
  right: -0.125rem;
}
.-right-1{
  right: -0.25rem;
}
.-right-2{
  right: -0.5rem;
}
.-top-1{
  top: -0.25rem;
}
.-top-\[3px\]{
  top: -3px;
}
.bottom-0{
  bottom: 0px;
}
.bottom-1\.5{
  bottom: 0.375rem;
}
.left-0{
  left: 0px;
}
.left-1\/2{
  left: 50%;
}
.left-2\.5{
  left: 0.625rem;
}
.left-3{
  left: 0.75rem;
}
.left-4{
  left: 1rem;
}
.right-0{
  right: 0px;
}
.right-0\.5{
  right: 0.125rem;
}
.right-1{
  right: 0.25rem;
}
.right-2{
  right: 0.5rem;
}
.right-2\.5{
  right: 0.625rem;
}
.right-3{
  right: 0.75rem;
}
.right-full{
  right: 100%;
}
.top-0{
  top: 0px;
}
.top-0\.5{
  top: 0.125rem;
}
.top-1{
  top: 0.25rem;
}
.top-1\.5{
  top: 0.375rem;
}
.top-1\/2{
  top: 50%;
}
.top-10{
  top: 2.5rem;
}
.top-2{
  top: 0.5rem;
}
.top-3{
  top: 0.75rem;
}
.top-5{
  top: 1.25rem;
}
.top-full{
  top: 100%;
}
.isolate{
  isolation: isolate;
}
.-z-10{
  z-index: -10;
}
.z-10{
  z-index: 10;
}
.z-20{
  z-index: 20;
}
.z-30{
  z-index: 30;
}
.z-50{
  z-index: 50;
}
.z-\[100\]{
  z-index: 100;
}
.z-\[1\]{
  z-index: 1;
}
.z-\[2\]{
  z-index: 2;
}
.z-\[3\]{
  z-index: 3;
}
.z-\[4\]{
  z-index: 4;
}
.col-span-2{
  grid-column: span 2 / span 2;
}
.col-span-full{
  grid-column: 1 / -1;
}
.-m-2{
  margin: -0.5rem;
}
.m-0{
  margin: 0px;
}
.-mx-1{
  margin-left: -0.25rem;
  margin-right: -0.25rem;
}
.-mx-1\.5{
  margin-left: -0.375rem;
  margin-right: -0.375rem;
}
.-mx-4{
  margin-left: -1rem;
  margin-right: -1rem;
}
.-mx-5{
  margin-left: -1.25rem;
  margin-right: -1.25rem;
}
.-mx-6{
  margin-left: -1.5rem;
  margin-right: -1.5rem;
}
.-my-1\.5{
  margin-top: -0.375rem;
  margin-bottom: -0.375rem;
}
.-my-2{
  margin-top: -0.5rem;
  margin-bottom: -0.5rem;
}
.-my-4{
  margin-top: -1rem;
  margin-bottom: -1rem;
}
.mx-0\.5{
  margin-left: 0.125rem;
  margin-right: 0.125rem;
}
.mx-1{
  margin-left: 0.25rem;
  margin-right: 0.25rem;
}
.mx-4{
  margin-left: 1rem;
  margin-right: 1rem;
}
.mx-auto{
  margin-left: auto;
  margin-right: auto;
}
.my-1{
  margin-top: 0.25rem;
  margin-bottom: 0.25rem;
}
.-mb-2{
  margin-bottom: -0.5rem;
}
.-mb-px{
  margin-bottom: -1px;
}
.-ml-1\.5{
  margin-left: -0.375rem;
}
.-ml-2{
  margin-left: -0.5rem;
}
.-ml-\[18px\]{
  margin-left: -18px;
}
.-ml-px{
  margin-left: -1px;
}
.-mr-2{
  margin-right: -0.5rem;
}
.-mt-1{
  margin-top: -0.25rem;
}
.mb-0{
  margin-bottom: 0px;
}
.mb-0\.5{
  margin-bottom: 0.125rem;
}
.mb-1{
  margin-bottom: 0.25rem;
}
.mb-1\.5{
  margin-bottom: 0.375rem;
}
.mb-2{
  margin-bottom: 0.5rem;
}
.mb-2\.5{
  margin-bottom: 0.625rem;
}
.mb-3{
  margin-bottom: 0.75rem;
}
.mb-3\.5{
  margin-bottom: 0.875rem;
}
.mb-4{
  margin-bottom: 1rem;
}
.mb-\[22px\]{
  margin-bottom: 22px;
}
.mb-\[26px\]{
  margin-bottom: 26px;
}
.ml-1{
  margin-left: 0.25rem;
}
.ml-1\.5{
  margin-left: 0.375rem;
}
.ml-2{
  margin-left: 0.5rem;
}
.ml-\[22px\]{
  margin-left: 22px;
}
.ml-\[4px\]{
  margin-left: 4px;
}
.ml-auto{
  margin-left: auto;
}
.mr-1{
  margin-right: 0.25rem;
}
.mr-2{
  margin-right: 0.5rem;
}
.mr-auto{
  margin-right: auto;
}
.mt-0\.5{
  margin-top: 0.125rem;
}
.mt-1{
  margin-top: 0.25rem;
}
.mt-1\.5{
  margin-top: 0.375rem;
}
.mt-10{
  margin-top: 2.5rem;
}
.mt-14{
  margin-top: 3.5rem;
}
.mt-2{
  margin-top: 0.5rem;
}
.mt-2\.5{
  margin-top: 0.625rem;
}
.mt-3{
  margin-top: 0.75rem;
}
.mt-3\.5{
  margin-top: 0.875rem;
}
.mt-4{
  margin-top: 1rem;
}
.mt-6{
  margin-top: 1.5rem;
}
.mt-8{
  margin-top: 2rem;
}
.mt-\[30px\]{
  margin-top: 30px;
}
.mt-\[3px\]{
  margin-top: 3px;
}
.mt-auto{
  margin-top: auto;
}
.mt-px{
  margin-top: 1px;
}
.\!block{
  display: block !important;
}
.block{
  display: block;
}
.inline-block{
  display: inline-block;
}
.inline{
  display: inline;
}
.flex{
  display: flex;
}
.inline-flex{
  display: inline-flex;
}
.table{
  display: table;
}
.\!grid{
  display: grid !important;
}
.grid{
  display: grid;
}
.contents{
  display: contents;
}
.\!hidden{
  display: none !important;
}
.hidden{
  display: none;
}
.h-0{
  height: 0px;
}
.h-1\.5{
  height: 0.375rem;
}
.h-10{
  height: 2.5rem;
}
.h-11{
  height: 2.75rem;
}
.h-12{
  height: 3rem;
}
.h-2{
  height: 0.5rem;
}
.h-2\.5{
  height: 0.625rem;
}
.h-3{
  height: 0.75rem;
}
.h-3\.5{
  height: 0.875rem;
}
.h-4{
  height: 1rem;
}
.h-5{
  height: 1.25rem;
}
.h-6{
  height: 1.5rem;
}
.h-64{
  height: 16rem;
}
.h-7{
  height: 1.75rem;
}
.h-72{
  height: 18rem;
}
.h-8{
  height: 2rem;
}
.h-9{
  height: 2.25rem;
}
.h-\[1\.5px\]{
  height: 1.5px;
}
.h-\[112px\]{
  height: 112px;
}
.h-\[116px\]{
  height: 116px;
}
.h-\[124px\]{
  height: 124px;
}
.h-\[26px\]{
  height: 26px;
}
.h-\[30px\]{
  height: 30px;
}
.h-\[34px\]{
  height: 34px;
}
.h-\[38px\]{
  height: 38px;
}
.h-\[60px\]{
  height: 60px;
}
.h-\[78px\]{
  height: 78px;
}
.h-\[84px\]{
  height: 84px;
}
.h-\[96px\]{
  height: 96px;
}
.h-auto{
  height: auto;
}
.h-full{
  height: 100%;
}
.h-px{
  height: 1px;
}
.max-h-32{
  max-height: 8rem;
}
.max-h-40{
  max-height: 10rem;
}
.max-h-48{
  max-height: 12rem;
}
.max-h-52{
  max-height: 13rem;
}
.max-h-64{
  max-height: 16rem;
}
.max-h-72{
  max-height: 18rem;
}
.min-h-0{
  min-height: 0px;
}
.min-h-11{
  min-height: 2.75rem;
}
.min-h-14{
  min-height: 3.5rem;
}
.min-h-8{
  min-height: 2rem;
}
.min-h-9{
  min-height: 2.25rem;
}
.min-h-\[1\.25rem\]{
  min-height: 1.25rem;
}
.min-h-\[172px\]{
  min-height: 172px;
}
.min-h-\[196px\]{
  min-height: 196px;
}
.min-h-\[1rem\]{
  min-height: 1rem;
}
.min-h-\[2\.25rem\]{
  min-height: 2.25rem;
}
.min-h-\[3\.25rem\]{
  min-height: 3.25rem;
}
.min-h-\[5rem\]{
  min-height: 5rem;
}
.w-0{
  width: 0px;
}
.w-0\.5{
  width: 0.125rem;
}
.w-1\.5{
  width: 0.375rem;
}
.w-10{
  width: 2.5rem;
}
.w-11{
  width: 2.75rem;
}
.w-12{
  width: 3rem;
}
.w-14{
  width: 3.5rem;
}
.w-16{
  width: 4rem;
}
.w-2{
  width: 0.5rem;
}
.w-2\.5{
  width: 0.625rem;
}
.w-20{
  width: 5rem;
}
.w-3\.5{
  width: 0.875rem;
}
.w-32{
  width: 8rem;
}
.w-36{
  width: 9rem;
}
.w-4{
  width: 1rem;
}
.w-44{
  width: 11rem;
}
.w-5{
  width: 1.25rem;
}
.w-6{
  width: 1.5rem;
}
.w-7{
  width: 1.75rem;
}
.w-8{
  width: 2rem;
}
.w-9{
  width: 2.25rem;
}
.w-\[100px\]{
  width: 100px;
}
.w-\[104px\]{
  width: 104px;
}
.w-\[118px\]{
  width: 118px;
}
.w-\[128px\]{
  width: 128px;
}
.w-\[136px\]{
  width: 136px;
}
.w-\[19px\]{
  width: 19px;
}
.w-\[34px\]{
  width: 34px;
}
.w-\[78px\]{
  width: 78px;
}
.w-auto{
  width: auto;
}
.w-fit{
  width: -moz-fit-content;
  width: fit-content;
}
.w-full{
  width: 100%;
}
.w-max{
  width: -moz-max-content;
  width: max-content;
}
.w-px{
  width: 1px;
}
.min-w-0{
  min-width: 0px;
}
.min-w-4{
  min-width: 1rem;
}
.min-w-8{
  min-width: 2rem;
}
.min-w-\[10\.5rem\]{
  min-width: 10.5rem;
}
.min-w-\[13rem\]{
  min-width: 13rem;
}
.min-w-\[170px\]{
  min-width: 170px;
}
.min-w-\[180px\]{
  min-width: 180px;
}
.min-w-\[2\.25rem\]{
  min-width: 2.25rem;
}
.max-w-3xl{
  max-width: 48rem;
}
.max-w-\[100px\]{
  max-width: 100px;
}
.max-w-\[140px\]{
  max-width: 140px;
}
.max-w-\[18rem\]{
  max-width: 18rem;
}
.max-w-\[352px\]{
  max-width: 352px;
}
.max-w-\[45\%\]{
  max-width: 45%;
}
.max-w-full{
  max-width: 100%;
}
.max-w-lg{
  max-width: 32rem;
}
.max-w-sm{
  max-width: 24rem;
}
.flex-1{
  flex: 1 1 0%;
}
.flex-auto{
  flex: 1 1 auto;
}
.shrink{
  flex-shrink: 1;
}
.shrink-0{
  flex-shrink: 0;
}
.grow{
  flex-grow: 1;
}
.basis-full{
  flex-basis: 100%;
}
.-translate-x-1\/2{
  --tw-translate-x: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-x-full{
  --tw-translate-x: -100%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-1\/2{
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-0{
  --tw-translate-x: 0px;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-4{
  --tw-translate-x: 1rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-rotate-45{
  --tw-rotate: -45deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-rotate-90{
  --tw-rotate: -90deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-rotate-\[4deg\]{
  --tw-rotate: -4deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-180{
  --tw-rotate: 180deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-\[7deg\]{
  --tw-rotate: 7deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform{
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
@keyframes ping{

  75%, 100%{
    transform: scale(2);
    opacity: 0;
  }
}
.animate-ping{
  animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes pulse{

  50%{
    opacity: .5;
  }
}
.animate-pulse{
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes spin{

  to{
    transform: rotate(360deg);
  }
}
.animate-spin{
  animation: spin 1s linear infinite;
}
.cursor-col-resize{
  cursor: col-resize;
}
.cursor-default{
  cursor: default;
}
.cursor-ew-resize{
  cursor: ew-resize;
}
.cursor-grab{
  cursor: grab;
}
.cursor-not-allowed{
  cursor: not-allowed;
}
.cursor-pointer{
  cursor: pointer;
}
.cursor-text{
  cursor: text;
}
.touch-none{
  touch-action: none;
}
.touch-pan-y{
  --tw-pan-y: pan-y;
  touch-action: var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom);
}
.select-none{
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.select-all{
  -webkit-user-select: all;
     -moz-user-select: all;
          user-select: all;
}
.resize-none{
  resize: none;
}
.resize-y{
  resize: vertical;
}
.resize{
  resize: both;
}
.list-disc{
  list-style-type: disc;
}
.list-none{
  list-style-type: none;
}
.grid-cols-1{
  grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2{
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-cols-4{
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid-cols-\[1fr_auto\]{
  grid-template-columns: 1fr auto;
}
.grid-cols-\[1fr_auto_1fr\]{
  grid-template-columns: 1fr auto 1fr;
}
.grid-cols-\[1fr_auto_auto\]{
  grid-template-columns: 1fr auto auto;
}
.flex-row-reverse{
  flex-direction: row-reverse;
}
.flex-col{
  flex-direction: column;
}
.flex-wrap{
  flex-wrap: wrap;
}
.flex-nowrap{
  flex-wrap: nowrap;
}
.items-start{
  align-items: flex-start;
}
.items-end{
  align-items: flex-end;
}
.items-center{
  align-items: center;
}
.items-baseline{
  align-items: baseline;
}
.items-stretch{
  align-items: stretch;
}
.justify-start{
  justify-content: flex-start;
}
.justify-end{
  justify-content: flex-end;
}
.justify-center{
  justify-content: center;
}
.justify-between{
  justify-content: space-between;
}
.justify-items-center{
  justify-items: center;
}
.gap-0{
  gap: 0px;
}
.gap-0\.5{
  gap: 0.125rem;
}
.gap-1{
  gap: 0.25rem;
}
.gap-1\.5{
  gap: 0.375rem;
}
.gap-12{
  gap: 3rem;
}
.gap-2{
  gap: 0.5rem;
}
.gap-2\.5{
  gap: 0.625rem;
}
.gap-3{
  gap: 0.75rem;
}
.gap-3\.5{
  gap: 0.875rem;
}
.gap-4{
  gap: 1rem;
}
.gap-5{
  gap: 1.25rem;
}
.gap-\[3px\]{
  gap: 3px;
}
.gap-x-1\.5{
  -moz-column-gap: 0.375rem;
       column-gap: 0.375rem;
}
.gap-x-2{
  -moz-column-gap: 0.5rem;
       column-gap: 0.5rem;
}
.gap-x-4{
  -moz-column-gap: 1rem;
       column-gap: 1rem;
}
.gap-y-1{
  row-gap: 0.25rem;
}
.gap-y-1\.5{
  row-gap: 0.375rem;
}
.gap-y-3{
  row-gap: 0.75rem;
}
.space-y-0\.5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.125rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.125rem * var(--tw-space-y-reverse));
}
.space-y-1 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
}
.space-y-1\.5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
}
.space-y-2 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
.space-y-2\.5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.625rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.625rem * var(--tw-space-y-reverse));
}
.space-y-3 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
}
.space-y-3\.5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.875rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.875rem * var(--tw-space-y-reverse));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.space-y-5 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
.space-y-6 > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
}
.divide-y > :not([hidden]) ~ :not([hidden]){
  --tw-divide-y-reverse: 0;
  border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
  border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
}
.divide-border\/50 > :not([hidden]) ~ :not([hidden]){
  border-color: rgb(var(--color-border-ch) / 0.5);
}
.self-start{
  align-self: flex-start;
}
.self-end{
  align-self: flex-end;
}
.self-center{
  align-self: center;
}
.overflow-hidden{
  overflow: hidden;
}
.overflow-visible{
  overflow: visible;
}
.overflow-x-auto{
  overflow-x: auto;
}
.overflow-y-auto{
  overflow-y: auto;
}
.truncate{
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.whitespace-nowrap{
  white-space: nowrap;
}
.whitespace-pre{
  white-space: pre;
}
.whitespace-pre-wrap{
  white-space: pre-wrap;
}
.text-balance{
  text-wrap: balance;
}
.text-pretty{
  text-wrap: pretty;
}
.break-words{
  overflow-wrap: break-word;
}
.break-all{
  word-break: break-all;
}
.rounded{
  border-radius: 0.25rem;
}
.rounded-2xl{
  border-radius: 1rem;
}
.rounded-\[18px\]{
  border-radius: 18px;
}
.rounded-full{
  border-radius: 9999px;
}
.rounded-lg{
  border-radius: 0.5rem;
}
.rounded-md{
  border-radius: 0.375rem;
}
.rounded-sm{
  border-radius: 0.125rem;
}
.rounded-xl{
  border-radius: 0.75rem;
}
.rounded-b{
  border-bottom-right-radius: 0.25rem;
  border-bottom-left-radius: 0.25rem;
}
.rounded-r{
  border-top-right-radius: 0.25rem;
  border-bottom-right-radius: 0.25rem;
}
.border{
  border-width: 1px;
}
.border-0{
  border-width: 0px;
}
.border-2{
  border-width: 2px;
}
.border-\[3px\]{
  border-width: 3px;
}
.border-x{
  border-left-width: 1px;
  border-right-width: 1px;
}
.border-y{
  border-top-width: 1px;
  border-bottom-width: 1px;
}
.border-b{
  border-bottom-width: 1px;
}
.border-l{
  border-left-width: 1px;
}
.border-l-2{
  border-left-width: 2px;
}
.border-r{
  border-right-width: 1px;
}
.border-t{
  border-top-width: 1px;
}
.border-dashed{
  border-style: dashed;
}
.border-double{
  border-style: double;
}
.border-none{
  border-style: none;
}
.border-\[color\:var\(--tour-brand\)\]{
  border-color: var(--tour-brand);
}
.border-\[rgba\(37\2c 211\2c 102\2c \.28\)\]{
  border-color: rgba(37,211,102,.28);
}
.border-accent{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
}
.border-accent\/30{
  border-color: rgb(var(--color-accent-ch) / 0.3);
}
.border-accent\/40{
  border-color: rgb(var(--color-accent-ch) / 0.4);
}
.border-accent\/50{
  border-color: rgb(var(--color-accent-ch) / 0.5);
}
.border-accent\/60{
  border-color: rgb(var(--color-accent-ch) / 0.6);
}
.border-border{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
}
.border-border\/50{
  border-color: rgb(var(--color-border-ch) / 0.5);
}
.border-danger{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-danger-ch) / var(--tw-border-opacity, 1));
}
.border-danger\/40{
  border-color: rgb(var(--color-danger-ch) / 0.4);
}
.border-danger\/50{
  border-color: rgb(var(--color-danger-ch) / 0.5);
}
.border-irish\/30{
  border-color: rgb(var(--color-irish-ch) / 0.3);
}
.border-irish\/35{
  border-color: rgb(var(--color-irish-ch) / 0.35);
}
.border-irish\/50{
  border-color: rgb(var(--color-irish-ch) / 0.5);
}
.border-success\/40{
  border-color: rgb(var(--color-success-ch) / 0.4);
}
.border-transparent{
  border-color: transparent;
}
.border-warn\/25{
  border-color: rgb(var(--color-warn-ch) / 0.25);
}
.border-warn\/30{
  border-color: rgb(var(--color-warn-ch) / 0.3);
}
.border-warn\/40{
  border-color: rgb(var(--color-warn-ch) / 0.4);
}
.border-white\/25{
  border-color: rgb(255 255 255 / 0.25);
}
.border-white\/70{
  border-color: rgb(255 255 255 / 0.7);
}
.border-t-transparent{
  border-top-color: transparent;
}
.bg-\[color\:var\(--tour-brand\)\]{
  background-color: var(--tour-brand);
}
.bg-\[rgba\(37\2c 211\2c 102\2c \.07\)\]{
  background-color: rgba(37,211,102,.07);
}
.bg-accent{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-accent-ch) / var(--tw-bg-opacity, 1));
}
.bg-accent-dim{
  background-color: var(--color-accent-dim);
}
.bg-accent\/10{
  background-color: rgb(var(--color-accent-ch) / 0.1);
}
.bg-accent\/15{
  background-color: rgb(var(--color-accent-ch) / 0.15);
}
.bg-accent\/20{
  background-color: rgb(var(--color-accent-ch) / 0.2);
}
.bg-accent\/30{
  background-color: rgb(var(--color-accent-ch) / 0.3);
}
.bg-accent\/5{
  background-color: rgb(var(--color-accent-ch) / 0.05);
}
.bg-accent\/50{
  background-color: rgb(var(--color-accent-ch) / 0.5);
}
.bg-accent\/\[0\.07\]{
  background-color: rgb(var(--color-accent-ch) / 0.07);
}
.bg-accent\/\[0\.14\]{
  background-color: rgb(var(--color-accent-ch) / 0.14);
}
.bg-bg{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-bg-ch) / var(--tw-bg-opacity, 1));
}
.bg-black\/40{
  background-color: rgb(0 0 0 / 0.4);
}
.bg-black\/70{
  background-color: rgb(0 0 0 / 0.7);
}
.bg-border{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-border-ch) / var(--tw-bg-opacity, 1));
}
.bg-current{
  background-color: currentColor;
}
.bg-danger{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-danger-ch) / var(--tw-bg-opacity, 1));
}
.bg-danger\/10{
  background-color: rgb(var(--color-danger-ch) / 0.1);
}
.bg-danger\/20{
  background-color: rgb(var(--color-danger-ch) / 0.2);
}
.bg-danger\/5{
  background-color: rgb(var(--color-danger-ch) / 0.05);
}
.bg-dim{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-dim-ch) / var(--tw-bg-opacity, 1));
}
.bg-elevated{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
}
.bg-irish\/5{
  background-color: rgb(var(--color-irish-ch) / 0.05);
}
.bg-primary{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-primary-ch) / var(--tw-bg-opacity, 1));
}
.bg-success{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-success-ch) / var(--tw-bg-opacity, 1));
}
.bg-success\/10{
  background-color: rgb(var(--color-success-ch) / 0.1);
}
.bg-success\/15{
  background-color: rgb(var(--color-success-ch) / 0.15);
}
.bg-success\/20{
  background-color: rgb(var(--color-success-ch) / 0.2);
}
.bg-surface{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-surface-ch) / var(--tw-bg-opacity, 1));
}
.bg-surface\/85{
  background-color: rgb(var(--color-surface-ch) / 0.85);
}
.bg-transparent{
  background-color: transparent;
}
.bg-warn{
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-warn-ch) / var(--tw-bg-opacity, 1));
}
.bg-warn\/10{
  background-color: rgb(var(--color-warn-ch) / 0.1);
}
.bg-warn\/15{
  background-color: rgb(var(--color-warn-ch) / 0.15);
}
.bg-warn\/20{
  background-color: rgb(var(--color-warn-ch) / 0.2);
}
.bg-warn\/5{
  background-color: rgb(var(--color-warn-ch) / 0.05);
}
.bg-white{
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
}
.fill-\[color\:var\(--tour-brand\)\]{
  fill: var(--tour-brand);
}
.fill-danger{
  fill: rgb(var(--color-danger-ch) / 1);
}
.fill-muted{
  fill: rgb(var(--color-muted-ch) / 1);
}
.fill-none{
  fill: none;
}
.stroke-\[color\:var\(--tour-brand\)\]{
  stroke: var(--tour-brand);
}
.stroke-accent{
  stroke: rgb(var(--color-accent-ch) / 1);
}
.stroke-border{
  stroke: rgb(var(--color-border-ch) / 1);
}
.stroke-danger{
  stroke: rgb(var(--color-danger-ch) / 1);
}
.stroke-dim{
  stroke: rgb(var(--color-dim-ch) / 1);
}
.stroke-muted{
  stroke: rgb(var(--color-muted-ch) / 1);
}
.object-contain{
  -o-object-fit: contain;
     object-fit: contain;
}
.p-0{
  padding: 0px;
}
.p-1{
  padding: 0.25rem;
}
.p-2{
  padding: 0.5rem;
}
.p-2\.5{
  padding: 0.625rem;
}
.p-3{
  padding: 0.75rem;
}
.p-3\.5{
  padding: 0.875rem;
}
.p-4{
  padding: 1rem;
}
.p-6{
  padding: 1.5rem;
}
.px-0{
  padding-left: 0px;
  padding-right: 0px;
}
.px-1{
  padding-left: 0.25rem;
  padding-right: 0.25rem;
}
.px-1\.5{
  padding-left: 0.375rem;
  padding-right: 0.375rem;
}
.px-2{
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}
.px-2\.5{
  padding-left: 0.625rem;
  padding-right: 0.625rem;
}
.px-3{
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}
.px-3\.5{
  padding-left: 0.875rem;
  padding-right: 0.875rem;
}
.px-4{
  padding-left: 1rem;
  padding-right: 1rem;
}
.px-5{
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}
.px-6{
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
.px-\[19px\]{
  padding-left: 19px;
  padding-right: 19px;
}
.py-0{
  padding-top: 0px;
  padding-bottom: 0px;
}
.py-0\.5{
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
}
.py-1{
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}
.py-1\.5{
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
}
.py-10{
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
}
.py-2{
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}
.py-2\.5{
  padding-top: 0.625rem;
  padding-bottom: 0.625rem;
}
.py-3{
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}
.py-3\.5{
  padding-top: 0.875rem;
  padding-bottom: 0.875rem;
}
.py-4{
  padding-top: 1rem;
  padding-bottom: 1rem;
}
.py-5{
  padding-top: 1.25rem;
  padding-bottom: 1.25rem;
}
.py-6{
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}
.py-8{
  padding-top: 2rem;
  padding-bottom: 2rem;
}
.py-\[11px\]{
  padding-top: 11px;
  padding-bottom: 11px;
}
.py-\[7px\]{
  padding-top: 7px;
  padding-bottom: 7px;
}
.py-px{
  padding-top: 1px;
  padding-bottom: 1px;
}
.pb-1{
  padding-bottom: 0.25rem;
}
.pb-12{
  padding-bottom: 3rem;
}
.pb-16{
  padding-bottom: 4rem;
}
.pb-2{
  padding-bottom: 0.5rem;
}
.pb-2\.5{
  padding-bottom: 0.625rem;
}
.pb-3{
  padding-bottom: 0.75rem;
}
.pb-4{
  padding-bottom: 1rem;
}
.pb-6{
  padding-bottom: 1.5rem;
}
.pl-1{
  padding-left: 0.25rem;
}
.pl-10{
  padding-left: 2.5rem;
}
.pl-2{
  padding-left: 0.5rem;
}
.pl-2\.5{
  padding-left: 0.625rem;
}
.pl-3{
  padding-left: 0.75rem;
}
.pl-3\.5{
  padding-left: 0.875rem;
}
.pl-4{
  padding-left: 1rem;
}
.pr-1{
  padding-right: 0.25rem;
}
.pr-2{
  padding-right: 0.5rem;
}
.pr-24{
  padding-right: 6rem;
}
.pr-3{
  padding-right: 0.75rem;
}
.pr-8{
  padding-right: 2rem;
}
.pr-9{
  padding-right: 2.25rem;
}
.pt-0\.5{
  padding-top: 0.125rem;
}
.pt-1{
  padding-top: 0.25rem;
}
.pt-14{
  padding-top: 3.5rem;
}
.pt-2{
  padding-top: 0.5rem;
}
.pt-3{
  padding-top: 0.75rem;
}
.pt-4{
  padding-top: 1rem;
}
.pt-6{
  padding-top: 1.5rem;
}
.pt-8{
  padding-top: 2rem;
}
.pt-\[15vh\]{
  padding-top: 15vh;
}
.text-left{
  text-align: left;
}
.text-center{
  text-align: center;
}
.text-right{
  text-align: right;
}
.font-mono{
  font-family: IBM Plex Mono, ui-monospace, monospace;
}
.font-sans{
  font-family: IBM Plex Sans, system-ui, sans-serif;
}
.text-2xl{
  font-size: 1.5rem;
  line-height: 2rem;
}
.text-2xs{
  font-size: 11px;
  line-height: 1rem;
}
.text-3xl{
  font-size: 1.875rem;
  line-height: 2.25rem;
}
.text-\[13\.5px\]{
  font-size: 13.5px;
}
.text-\[13px\]{
  font-size: 13px;
}
.text-\[15px\]{
  font-size: 15px;
}
.text-\[38px\]{
  font-size: 38px;
}
.text-base{
  font-size: 1rem;
  line-height: 1.5rem;
}
.text-lg{
  font-size: 1.125rem;
  line-height: 1.75rem;
}
.text-sm{
  font-size: 0.875rem;
  line-height: 1.25rem;
}
.text-xl{
  font-size: 1.25rem;
  line-height: 1.75rem;
}
.text-xs{
  font-size: 0.75rem;
  line-height: 1rem;
}
.font-bold{
  font-weight: 700;
}
.font-extralight{
  font-weight: 200;
}
.font-medium{
  font-weight: 500;
}
.font-normal{
  font-weight: 400;
}
.font-semibold{
  font-weight: 600;
}
.uppercase{
  text-transform: uppercase;
}
.lowercase{
  text-transform: lowercase;
}
.capitalize{
  text-transform: capitalize;
}
.italic{
  font-style: italic;
}
.ordinal{
  --tw-ordinal: ordinal;
  font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);
}
.tabular-nums{
  --tw-numeric-spacing: tabular-nums;
  font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);
}
.leading-3{
  line-height: .75rem;
}
.leading-\[14px\]{
  line-height: 14px;
}
.leading-none{
  line-height: 1;
}
.leading-relaxed{
  line-height: 1.625;
}
.leading-snug{
  line-height: 1.375;
}
.leading-tight{
  line-height: 1.25;
}
.tracking-\[-0\.015em\]{
  letter-spacing: -0.015em;
}
.tracking-\[-0\.01em\]{
  letter-spacing: -0.01em;
}
.tracking-\[0\.16em\]{
  letter-spacing: 0.16em;
}
.tracking-\[0\.3em\]{
  letter-spacing: 0.3em;
}
.tracking-tighter{
  letter-spacing: -0.05em;
}
.tracking-wider{
  letter-spacing: 0.05em;
}
.tracking-widest{
  letter-spacing: 0.1em;
}
.text-\[color\:var\(--tour-brand\)\]{
  color: var(--tour-brand);
}
.text-accent{
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
}
.text-bg{
  --tw-text-opacity: 1;
  color: rgb(var(--color-bg-ch) / var(--tw-text-opacity, 1));
}
.text-danger{
  --tw-text-opacity: 1;
  color: rgb(var(--color-danger-ch) / var(--tw-text-opacity, 1));
}
.text-dim{
  --tw-text-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-text-opacity, 1));
}
.text-dim\/60{
  color: rgb(var(--color-dim-ch) / 0.6);
}
.text-dim\/70{
  color: rgb(var(--color-dim-ch) / 0.7);
}
.text-gold{
  --tw-text-opacity: 1;
  color: rgb(var(--color-gold-ch) / var(--tw-text-opacity, 1));
}
.text-inherit{
  color: inherit;
}
.text-irish{
  --tw-text-opacity: 1;
  color: rgb(var(--color-irish-ch) / var(--tw-text-opacity, 1));
}
.text-muted{
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
.text-primary{
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
.text-primary\/75{
  color: rgb(var(--color-primary-ch) / 0.75);
}
.text-primary\/90{
  color: rgb(var(--color-primary-ch) / 0.9);
}
.text-success{
  --tw-text-opacity: 1;
  color: rgb(var(--color-success-ch) / var(--tw-text-opacity, 1));
}
.text-transparent{
  color: transparent;
}
.text-warn{
  --tw-text-opacity: 1;
  color: rgb(var(--color-warn-ch) / var(--tw-text-opacity, 1));
}
.text-white{
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.underline{
  text-decoration-line: underline;
}
.line-through{
  text-decoration-line: line-through;
}
.no-underline{
  text-decoration-line: none;
}
.antialiased{
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.placeholder-dim::-moz-placeholder{
  --tw-placeholder-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-placeholder-opacity, 1));
}
.placeholder-dim::placeholder{
  --tw-placeholder-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-placeholder-opacity, 1));
}
.accent-accent{
  accent-color: rgb(var(--color-accent-ch) / 1);
}
.opacity-0{
  opacity: 0;
}
.opacity-100{
  opacity: 1;
}
.opacity-40{
  opacity: 0.4;
}
.opacity-45{
  opacity: 0.45;
}
.opacity-50{
  opacity: 0.5;
}
.opacity-60{
  opacity: 0.6;
}
.opacity-70{
  opacity: 0.7;
}
.opacity-80{
  opacity: 0.8;
}
.opacity-90{
  opacity: 0.9;
}
.opacity-\[0\.08\]{
  opacity: 0.08;
}
.shadow{
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-2xl{
  --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
  --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-lg{
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.outline-none{
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.outline{
  outline-style: solid;
}
.\!ring{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000) !important;
}
.ring{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-2{
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-accent{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(var(--color-accent-ch) / var(--tw-ring-opacity, 1));
}
.ring-current{
  --tw-ring-color: currentColor;
}
.ring-warn{
  --tw-ring-opacity: 1;
  --tw-ring-color: rgb(var(--color-warn-ch) / var(--tw-ring-opacity, 1));
}
.blur{
  --tw-blur: blur(8px);
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.brightness-150{
  --tw-brightness: brightness(1.5);
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.drop-shadow{
  --tw-drop-shadow: drop-shadow(0 1px 2px rgb(0 0 0 / 0.1)) drop-shadow(0 1px 1px rgb(0 0 0 / 0.06));
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.drop-shadow-sm{
  --tw-drop-shadow: drop-shadow(0 1px 1px rgb(0 0 0 / 0.05));
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.sepia{
  --tw-sepia: sepia(100%);
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.filter{
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.backdrop-blur-sm{
  --tw-backdrop-blur: blur(4px);
  -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.backdrop-filter{
  -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.transition{
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-\[filter\2c box-shadow\]{
  transition-property: filter,box-shadow;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-\[filter\]{
  transition-property: filter;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-\[width\]{
  transition-property: width;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-all{
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-colors{
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-opacity{
  transition-property: opacity;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-shadow{
  transition-property: box-shadow;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-transform{
  transition-property: transform;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.duration-200{
  transition-duration: 200ms;
}
.duration-300{
  transition-duration: 300ms;
}
.duration-500{
  transition-duration: 500ms;
}
.duration-700{
  transition-duration: 700ms;
}
.duration-75{
  transition-duration: 75ms;
}
.ease-in-out{
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

:root {
  /* The system bars' insets, in the page's own pixels. The app runs under a
     CSS zoom on <html> (zoomService: 90 % on a phone), and that zoom shrinks
     an env() length like any other: a 48 px three-button bar got a 43 px
     margin and Cadence's bottom bar ran under the buttons (Android 16, One
     UI 8, 2026-10-09). Dividing by the zoom gives back the real size. Always
     these, never env(safe-area-inset-*) directly. */
  --safe-top:    calc(env(safe-area-inset-top, 0px) / var(--zoom-factor, 1));
  --safe-bottom: calc(env(safe-area-inset-bottom, 0px) / var(--zoom-factor, 1));
  /* The notch and the Dynamic Island sit on a side in landscape. */
  --safe-left:   calc(env(safe-area-inset-left, 0px) / var(--zoom-factor, 1));
  --safe-right:  calc(env(safe-area-inset-right, 0px) / var(--zoom-factor, 1));
  /* The scheme the browser draws its own controls in — see the date fields in
     the base layer. */
  --native-scheme: dark;
  /* Direct hex values — used in inline styles and SVG attributes */
  --color-bg:             #0a0a0a;
  --color-surface:        #141414;
  --color-elevated:       #1e1e1e;
  --color-border:         #252525;
  /* Raised to clear WCAG AA (2026-09-10) — see the note above `--color-dim`
     in the light theme for the measurements and the reasoning. */
  --color-muted:          #a8a8a8;
  --color-dim:            #858585;
  --color-primary:        #e8e8e8;
  --color-accent:         #8b7cf8;
  --color-accent-hover:   #7c6af7;
  --color-accent-subtle:  rgba(139, 124, 248, 0.35);
  --color-accent-dim:     rgba(139, 124, 248, 0.15);
  --color-danger:         #f87171;
  --color-success:        #4ade80;
  --color-warn:           #fbbf24;

  /* RGB channels — used by Tailwind for opacity modifier support (bg-X/10 etc.) */
  --color-bg-ch:       10 10 10;
  --color-surface-ch:  20 20 20;
  --color-elevated-ch: 30 30 30;
  --color-border-ch:   37 37 37;
  --color-muted-ch:    168 168 168;
  --color-dim-ch:      133 133 133;
  --color-primary-ch:  232 232 232;
  --color-accent-ch:   139 124 248;
  --color-danger-ch:   248 113 113;
  --color-success-ch:  74 222 128;
  --color-warn-ch:     251 191 36;
  --color-irish-ch:    52 211 133;
  /* The app's yellow, the same in every theme: a favourite's star (any star)
     and the sync cloud waiting to upload. Not `warn`: that one is orange in
     the green theme, and a star is not a warning (the author, 2026-11-11 —
     « le jaune était mieux »). Tailwind's yellow-400, which both had before. */
  --color-gold-ch:     250 204 21;
}

[data-theme="green"] {
  --native-scheme: light;
  --color-bg:             #f7faf5;
  --color-surface:        #edf4e8;
  --color-elevated:       #ffffff;
  --color-border:         #c8dec0;
  --color-muted:          #365942;
  --color-dim:            #4e7859;
  --color-primary:        #1a3320;
  --color-accent:         #169b62;
  --color-accent-hover:   #117a4d;
  --color-accent-subtle:  rgba(22, 155, 98, 0.25);
  --color-accent-dim:     rgba(22, 155, 98, 0.12);
  --color-danger:         #dc2626;
  --color-success:        #15803d;
  --color-warn:           #e8783a;

  --color-bg-ch:       247 250 245;
  --color-surface-ch:  237 244 232;
  --color-elevated-ch: 255 255 255;
  --color-border-ch:   200 222 192;
  --color-muted-ch:    54 89 66;
  --color-dim-ch:      78 120 89;
  --color-primary-ch:  26 51 32;
  --color-accent-ch:   22 155 98;
  --color-danger-ch:   220 38 38;
  --color-success-ch:  21 128 61;
  --color-warn-ch:     232 120 58;
  --color-irish-ch:    22 155 98;
  --color-gold-ch:     250 204 21;
}

[data-theme="light"] {
  --native-scheme: light;
  --color-bg:             #ffffff;
  --color-surface:        #f5f5f5;
  --color-elevated:       #ececec;
  --color-border:         #d8d8d8;
  /* Text colour ladder, measured rather than eyeballed (2026-09-10).
     `dim` used to sit at 2,41–2,66:1 in all three themes — a failure of WCAG
     AA (4,5) and even of the 3,0 large-text floor, on a token used ~190 times
     including the session library's metadata line. Reported from the field
     before it was measured.

     Each value is the SMALLEST lightness change, at constant hue and
     saturation, that clears its target against the worst background it can
     land on (`elevated` here and in the dark theme, `surface` in the green
     one): `dim` to 4,5 and `muted` to 7,0, so the two stay a visible step
     apart (1,55:1 between them) instead of collapsing into one — raising
     `dim` alone would have put it exactly on the old `muted`.

     `muted` moved because it had to: in the green theme it was 4,43 on
     `surface`, failing AA as well, and in the light theme it cleared by 0,01.
     `primary` was already 13–19:1 and is untouched. */
  --color-muted:          #4e4e4e;
  --color-dim:            #6b6b6b;
  --color-primary:        #111111;
  --color-accent:         #6d5ef0;
  --color-accent-hover:   #5d4ee0;
  --color-accent-subtle:  rgba(109, 94, 240, 0.2);
  --color-accent-dim:     rgba(109, 94, 240, 0.1);
  --color-danger:         #dc2626;
  --color-success:        #16a34a;
  --color-warn:           #c07a00;

  --color-bg-ch:       255 255 255;
  --color-surface-ch:  245 245 245;
  --color-elevated-ch: 236 236 236;
  --color-border-ch:   216 216 216;
  --color-muted-ch:    78 78 78;
  --color-dim-ch:      107 107 107;
  --color-primary-ch:  17 17 17;
  --color-accent-ch:   109 94 240;
  --color-danger-ch:   220 38 38;
  --color-success-ch:  22 163 74;
  --color-warn-ch:     192 122 0;
  --color-irish-ch:    21 128 61;
  --color-gold-ch:     250 204 21;
}

@keyframes fadeSlideIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Écran d'accueil (UserSelector) ─────────────────────────────────────── */
.cadence-mark path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: markDraw 1.5s cubic-bezier(.5, 0, .2, 1) forwards;
}
.cadence-mark path:nth-child(1) { animation-delay: .15s; }
.cadence-mark path:nth-child(2) { animation-delay: .5s; animation-duration: 1.7s; }
.cadence-mark path:nth-child(3) { animation-delay: .95s; }
@keyframes markDraw { to { stroke-dashoffset: 0; } }
/* The app's update screen (native/updateOverlay.tsx): the strokes erased and
   drawn again in their own direction for as long as the download runs. The
   dash pattern repeats every 2 (a dash of 1, a gap of 1), so 0 and -2 are the
   same drawn stroke and -1 the erased one: the loop starts drawn, as the mark
   fades in. `both`: drawn during the delays too, not the base rule's hidden
   state. */
.cadence-mark.looping path { animation: markLoop 2.6s cubic-bezier(.5, 0, .2, 1) infinite both; }
.cadence-mark.looping path:nth-child(2) { animation-delay: .25s; }
.cadence-mark.looping path:nth-child(3) { animation-delay: .5s; }
@keyframes markLoop {
  0%   { stroke-dashoffset: 0; }
  45%  { stroke-dashoffset: -1; }
  100% { stroke-dashoffset: -2; }
}

.mark-in { animation: fadeIn .7s ease-out both; }
.fade-in { animation: fadeIn .7s ease-out both; }
.rise-in { animation: riseIn .6s cubic-bezier(.2, .7, .3, 1) both; }

/* A date field that refused what was typed (components/dateField.tsx): the
   border turns red and fades back to its own colour. Only `from` is given, so
   it fades to whatever the field's border is — the caller chose it. A change
   of colour, not a movement: nothing to switch off for reduced motion. */
.date-field-refused { animation: dateFieldRefused 1.2s ease-out; }
@keyframes dateFieldRefused {
  from { border-color: var(--color-danger); box-shadow: 0 0 0 1px var(--color-danger); }
}

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes riseIn {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}

/* The welcome screen's tour (components/welcomeTour.tsx) is drawn in the
   brand cyan, the logo's — which would not show against the light themes'
   white: a deeper teal there, dark enough for its small labels. */
.welcome-tour { --tour-brand: #6cf6e9; }
[data-theme="light"] .welcome-tour,
[data-theme="green"] .welcome-tour { --tour-brand: #0b7d76; }

/* Respect de la préférence système : on montre l'écran final, sans mouvement */
@media (prefers-reduced-motion: reduce) {
  .cadence-mark path,
  .mark-in, .fade-in, .rise-in {
    animation-duration: .01ms !important;
    animation-delay: 0ms !important;
  }
  /* A loop at .01ms would be a flicker: the drawn mark, still. */
  .cadence-mark.looping path { animation: none; stroke-dashoffset: 0; }
}

/* Markdown */
.markdown h1{
  margin-bottom: 0.75rem;
  margin-top: 1rem;
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 700;
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
.markdown h2{
  margin-bottom: 0.5rem;
  margin-top: 1rem;
  font-size: 1.125rem;
  line-height: 1.75rem;
  font-weight: 600;
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
.markdown h3{
  margin-bottom: 0.5rem;
  margin-top: 0.75rem;
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 600;
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
.markdown h4{
  margin-bottom: 0.25rem;
  margin-top: 0.75rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
.markdown h5{
  margin-bottom: 0.25rem;
  margin-top: 0.5rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.025em;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
.markdown p{
  margin-bottom: 0.75rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  line-height: 1.625;
  color: rgb(var(--color-primary-ch) / 0.9);
}
.markdown a{
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
  text-decoration-line: underline;
}
@media (hover: hover) and (pointer: fine){

  .markdown a:hover{
    color: var(--color-accent-hover);
  }
}
.markdown ul{
  margin-bottom: 0.75rem;
  list-style-position: inside;
  list-style-type: disc;
}
.markdown ul > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
}
.markdown ul{
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: rgb(var(--color-primary-ch) / 0.9);
}
.markdown ol{
  margin-bottom: 0.75rem;
  list-style-position: inside;
  list-style-type: decimal;
}
.markdown ol > :not([hidden]) ~ :not([hidden]){
  --tw-space-y-reverse: 0;
  margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
}
.markdown ol{
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: rgb(var(--color-primary-ch) / 0.9);
}
.markdown li input[type="checkbox"]{
  margin-right: 0.25rem;
  accent-color: rgb(var(--color-accent-ch) / 1);
}
.markdown code{
  border-radius: 0.25rem;
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
  padding-left: 0.375rem;
  padding-right: 0.375rem;
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
  font-family: IBM Plex Mono, ui-monospace, monospace;
  font-size: 0.75rem;
  line-height: 1rem;
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
}
.markdown pre{
  margin-bottom: 0.75rem;
  overflow-x: auto;
  border-radius: 0.25rem;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-bg-ch) / var(--tw-bg-opacity, 1));
  padding: 0.75rem;
}
.markdown pre code{
  border-radius: 0px;
  background-color: transparent;
  padding: 0px;
  font-size: 0.75rem;
  line-height: 1rem;
  color: rgb(var(--color-primary-ch) / 0.9);
}
.markdown blockquote{
  margin-bottom: 0.75rem;
  border-left-width: 2px;
  border-color: rgb(var(--color-accent-ch) / 0.4);
  padding-left: 0.75rem;
  font-style: italic;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
.markdown strong{
  font-weight: 600;
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}

/* ── ||Spoiler|| — click-to-reveal hidden text (notes & markdown files) ── */
.spoiler{
  cursor: pointer;
  border-radius: 0.25rem;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
  padding-left: 0.375rem;
  padding-right: 0.375rem;
}
.spoiler:not(.spoiler-revealed){
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.spoiler:not(.spoiler-revealed),
.spoiler:not(.spoiler-revealed) * { color: transparent !important; text-shadow: none !important; }
.spoiler:not(.spoiler-revealed) img { visibility: hidden; }
.spoiler:not(.spoiler-revealed):hover,
.spoiler:not(.spoiler-revealed):focus-visible{
  border-color: rgb(var(--color-accent-ch) / 0.5); outline: none;
}
.spoiler.spoiler-revealed{
  border-color: rgb(var(--color-accent-ch) / 0.3);
  background-color: rgb(var(--color-accent-ch) / 0.1);
}
.markdown em{
  font-style: italic;
}
.markdown hr{
  margin-top: 1rem;
  margin-bottom: 1rem;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
}
.markdown table{
  margin-bottom: 0.75rem;
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  line-height: 1.25rem;
}
.markdown thead{
  border-bottom-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
}
.markdown th{
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  text-align: left;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.025em;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
}
.markdown td{
  border-bottom-width: 1px;
  border-color: rgb(var(--color-border-ch) / 0.5);
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  color: rgb(var(--color-primary-ch) / 0.9);
}
.markdown tbody tr:hover{
  background-color: rgb(var(--color-elevated-ch) / 0.5);
}

/* ── The score transport ───────────────────────────────────────────────────
   abcjs ships its own stylesheet (`abcjs/abcjs-audio.css`, imported whole in
   main.ts) and it is built for a page that is not this one: a #424242 bar with
   #f4f4f4 icons, 28 × 34 buttons and a 2 px-bordered pill for a progress bar.
   Inside a dark, rounded, accent-purple app it read as a foreign object, and
   it was the first thing anyone saw on opening a score.

   The buttons are ours since 2026-11-04 — the viewer's one player
   (abcPlayer.ts), abcjs's SynthController and its widget gone — but they keep
   abcjs's classes, and its stylesheet: that is what shows play, pause or the
   spinner on the one button (`.abcjs-pushed`, `.abcjs-loading`). Restyled
   here, scoped under `.abc-transport`. */
.abc-transport .abcjs-inline-audio {
  height: auto;
  min-height: 2.75rem;
  padding: 0;
  border-radius: 0.5rem;
  background-color: transparent;
  gap: 0.125rem;
}

.abc-transport .abcjs-inline-audio .abcjs-btn {
  width: auto;
  height: auto;
  min-width: 2.25rem;
  min-height: 2.25rem;
  margin-right: 0;
  padding: 0.375rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 0.5rem;
  color: rgb(var(--color-muted-ch));
  transition: color .15s, background-color .15s;
}
/* The glyphs are drawn with explicit fill/stroke by the library, so they have
   to be told to follow the button's colour rather than keep their own. */
.abc-transport .abcjs-inline-audio .abcjs-btn g,
.abc-transport .abcjs-inline-audio .abcjs-btn path {
  fill: currentColor;
  stroke: currentColor;
}
.abc-transport .abcjs-inline-audio .abcjs-btn:hover { background-color: rgb(var(--color-bg-ch)); }
.abc-transport .abcjs-inline-audio .abcjs-btn:hover g,
.abc-transport .abcjs-inline-audio .abcjs-btn:hover path { fill: currentColor; stroke: currentColor; }

/* Play, stop and repeat, drawn exactly as the audio player draws them
   (audioPlayer.ts's `mkBtn`): a bordered square, muted at rest, accent border
   and brighter glyph on hover, accent through and through once it is on. The
   same three controls doing the same three jobs should not look like two
   different apps, and the audio player's is the shape this one is copying. */
.abc-transport .abcjs-inline-audio .abcjs-midi-start,
.abc-transport .abcjs-inline-audio .abc-midi-rewind,
.abc-transport .abcjs-inline-audio .abcjs-midi-reset,
.abc-transport .abcjs-inline-audio .abcjs-midi-loop {
  border: 1px solid rgb(var(--color-border-ch));
  border-radius: 4px;
  background-color: transparent;
  color: rgb(var(--color-muted-ch));
}
.abc-transport .abcjs-inline-audio .abcjs-midi-start:hover,
.abc-transport .abcjs-inline-audio .abc-midi-rewind:hover,
.abc-transport .abcjs-inline-audio .abcjs-midi-reset:hover,
.abc-transport .abcjs-inline-audio .abcjs-midi-loop:hover {
  border-color: rgb(var(--color-accent-ch));
  color: rgb(var(--color-primary-ch));
  background-color: transparent;
}

/* "Pushed" is a STATE — loop is on, and it was on by default with nothing
   saying so. Accent border and accent glyph, which is what the audio player's
   repeat button does when it is on. */
.abc-transport .abcjs-inline-audio .abcjs-midi-loop.abcjs-pushed,
.abc-transport .abcjs-inline-audio .abcjs-midi-start.abcjs-pushed {
  border-color: rgb(var(--color-accent-ch));
  color: rgb(var(--color-accent-ch));
  background-color: transparent;
}

/* ── The stave and its ABC together (the "both" face, 2026-11-04) ──────────
   The text first and the stave after it (the user, 2026-11-04): side by side
   when the viewer is wide enough, the text on the left; the stave under the
   text when it is not — decided by a container query on the viewer, never measured in
   script: a layout that measures itself can chase its own scrollbar. Where
   container queries are missing (iOS before 16), the two stay one above the
   other, which is the narrow layout anyway.

   `--abc-score-cap` is the stave's height cap alone (fileViewer.ts's
   capScore). Under the text it gets a share of it, so both are on screen;
   beside the text it gets all of it, and the text the row's height — at
   least a box's worth, for a short tune.

   The order is the grid's, not the DOM's: the viewer keeps the stave first,
   where its full page and the audio sync look for it. */
.abc-viewer { container: abc-viewer / inline-size; }
.abc-faces-both {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem;
}
.abc-faces-both > .abc-text-box { order: -1; }
/* The line between the two, which shares the width when they stand side by
   side (fileViewer.ts, 2026-11-04): faint at rest so it can be found, the
   accent once it is pointed at or held — the sidebar's handle's colours. */
.abc-faces-split { display: none; }
.abc-faces-split-line {
  width: 1px;
  height: 100%;
  background-color: rgb(var(--color-border-ch));
  transition: background-color .15s, width .15s;
}
.abc-faces-split:hover .abc-faces-split-line,
.abc-faces-split:focus-visible .abc-faces-split-line,
.abc-faces-split-active .abc-faces-split-line {
  width: 2px;
  background-color: rgb(var(--color-accent-ch) / 0.6);
}
.abc-faces-split:focus-visible { outline: none; }
.abc-faces-both > .abc-score-frame .abc-score-paper {
  max-height: calc(var(--abc-score-cap) * 0.55);
}
/* The audio sync's and the Play-along's text (syncedScore.tsx), read-only:
   a fixed height under the stave, whose own height those views measure and
   set — the text's must not depend on it. */
.abc-faces-both > .abc-text-box > .score-follow-text { max-height: 12rem; }
@container abc-viewer (min-width: 56rem) {
  /* Text, line, stave — placed by column, not by order: the DOM keeps the
     stave first. The shares are the line's (`--abc-text-fr`, faceSplit.ts),
     the same in the viewer and in the audio sync's and the Play-along's
     score (syncedScore.tsx). */
  .abc-faces-both {
    grid-template-columns: minmax(0, var(--abc-text-fr, 1fr)) 0.75rem minmax(0, var(--abc-score-fr, 1fr));
    grid-auto-rows: minmax(18rem, auto);
    -moz-column-gap: 0;
         column-gap: 0;
  }
  .abc-faces-both > .abc-text-box { grid-column: 1; grid-row: 1; }
  .abc-faces-both > .abc-faces-split {
    display: flex;
    justify-content: center;
    grid-column: 2;
    grid-row: 1;
    cursor: col-resize;
    touch-action: none;
  }
  .abc-faces-both > .abc-score-frame { grid-column: 3; grid-row: 1; }
  .abc-faces-both > .abc-score-frame .abc-score-paper {
    height: 100%;
    max-height: var(--abc-score-cap);
  }
  /* `!important` against the height the box's own handle writes on it, one
     above the other (an inline style): taken there, it held the box at that
     height side by side as well (2026-11-04, the user). Kept, it is the
     height the box has again under the stave. */
  .abc-faces-both > .abc-text-box textarea {
    height: 100% !important;
    resize: none;
  }
  /* Beside the stave, the row's height — never more: the text scrolls. */
  .abc-faces-both > .abc-text-box > .score-follow-text {
    position: absolute;
    inset: 0;
    max-height: none;
  }
}

/* ── A parser warning ──────────────────────────────────────────────────────
   abcjs marks the offending character in its warnings with markup of its own,
   which is stripped down to `<em>` before it is rendered (see
   `sanitizeEmphasisOnly`): the string quotes the user's own ABC, so its
   attributes cannot be trusted. The emphasis is therefore painted here rather
   than carried in the string. */
.abc-warning em {
  font-style: normal;
  font-weight: 600;
  color: rgb(var(--color-warn-ch));
  border-bottom: 2px solid rgb(var(--color-warn-ch));
  padding: 0 1px;
}

/* ── The engraved page ─────────────────────────────────────────────────────
   A safety net, not a layout: the score is engraved to the exact width of this
   box and needs no scaling, but between a resize and the re-engrave that
   follows it the drawing is briefly the width of the box it was made for. This
   keeps that moment from pushing a horizontal scrollbar onto the page.

   The tempo mark is hidden here rather than kept out of the ABC. Taking the
   `Q:` out was tried and reverted: it is what the note timestamps are built
   from, and without it clicking a note seeked into a different clock (see
   `injectDefaultTempo`). Hiding it in CSS reclaims the space it reserved all
   the same, because `cropToInk` measures INK and an element with
   `display: none` has none — which is the piece that was missing the first
   time this was tried. */
/* `display: block` because an SVG is inline by default, so it sits on a text
   baseline and the line-box leaves a few pixels of descender space under it.
   `height: auto` because abcjs makes the drawing its staff width PLUS its side
   paddings — wider than the box it was measured for — and `max-width` narrows
   it without touching its height attribute. The drawing, shrunk to the width,
   was then centred in a box still as tall as before: an empty band above the
   first staff and below the last, ~65 px each on a 360 px phone (measured
   2026-10-24, a 328-wide drawing in a 302 box). Following the width keeps the
   proportions, so the drawing fills its box.
   Centred: on a wide box the staff is capped at a readable spacing
   (abcLineBreaks.ts, `cappedStaffWidth`) and comes out narrower than it. */
.abc-score-paper svg { max-width: 100%; height: auto; display: block; margin-inline: auto; }
.abc-score-paper .abcjs-tempo { display: none; }
/* Score following (ScoreFollowView.tsx): a note pressed takes the recording
   to where it is played. */
.score-follow-paper .abcjs-note { cursor: pointer; }
/* The score is cropped to its ink (cropToInk); the region's bounds and their
   numbers stand a few units past the notes, into the paper's padding. */
.score-follow-paper svg { overflow: visible; }
/* The player's region on the score (syncedScore.tsx), in the colours of a
   passage's bounds on the score viewer: green where it starts, blue where it
   ends — never to be mistaken for the cursor running between them. */
.score-follow-bound-in, .score-follow-bound-out { stroke-width: 3px; stroke-linecap: round; pointer-events: none; }
.score-follow-bound-in { stroke: var(--abc-in, #16a34a); }
.score-follow-bound-out { stroke: var(--abc-out, #2563eb); }
/* Each bound's pass number: a small square against the top of its line, on
   its right — as the waveform shows a pass's number — in the bound's colour. */
/* `stroke: none`: abcjs strokes its whole SVG in the ink's colour, and the
   number came out ringed in black. */
.score-follow-bound-badge-in, .score-follow-bound-badge-out { pointer-events: none; }
.score-follow-bound-badge-in *, .score-follow-bound-badge-out * { stroke: none; }
.score-follow-bound-badge-in rect { fill: var(--abc-in, #16a34a); }
.score-follow-bound-badge-out rect { fill: var(--abc-out, #2563eb); }
.score-follow-bound-badge-in text, .score-follow-bound-badge-out text {
  font: 700 10px "IBM Plex Mono", ui-monospace, monospace;
  fill: var(--abc-paper, #fff);
}

/* The scrollbar down a full-page score that fits was NOT the score. abcjs
   measures glyph widths by drawing them into a scratch SVG, and
   `Svg.prototype.createDummySvg` (write/svg.js) appends that scratch to
   `<body>` once and never takes it away:

     <svg style="display: block !important;height: 1px;width: 1px;position: absolute;">

   `position: absolute` with no offsets keeps an element at its static place,
   and its static place is the END of the body — so it hangs one layout pixel
   past the bottom of the document, for good, from the first score drawn
   anywhere in the app. Measured: `documentElement.scrollHeight - clientHeight`
   = 1, `window.innerWidth - clientWidth` = 7, in a full-page reader whose own
   score box overflowed by exactly 0. A scrollbar down the whole window for one
   pixel of nothing.

   Pinning it to the origin costs abcjs nothing — it is never shown, only
   measured with `getBBox`, which does not care where the box sits. */
body > svg[style*="height: 1px"][style*="position: absolute"] {
  top: 0;
  left: 0;
  pointer-events: none;
}

/* Playback cursor + note highlight. The colour comes from the paper the score
   is drawn on (`--abc-cursor`, set by the viewer): the rose that reads well on
   white washes out on the dark surface, so each paper names its own. The
   fallback is the value this used to be hard-coded to, for any score drawn
   outside the viewer. */
.abcjs-cursor { stroke: var(--abc-cursor, #e11d48); stroke-width: 2px; }
.abcjs-highlight { fill: var(--abc-cursor, #e11d48) !important; }

/* The passage's bounds on the stave (fileViewer's drawBoundFlags): a dashed
   pole in the paper's own colour for each — green for the start, blue for the
   end — so neither reads as the solid cursor passing it. Only the pennant at
   the top answers a click — see boundFlag for why the pole must not. */
.abc-bound line {
  stroke-width: 1.5px;
  stroke-dasharray: 3 2;
  pointer-events: none;
}
.abc-bound-in line { stroke: var(--abc-in, #16a34a); }
.abc-bound-out line { stroke: var(--abc-out, #2563eb); }
.abc-bound polygon { pointer-events: none; }
.abc-bound-in polygon { fill: var(--abc-in, #16a34a); }
.abc-bound-out polygon { fill: var(--abc-out, #2563eb); }
.abc-bound .abc-bound-hit { fill: transparent; pointer-events: all; cursor: pointer; }
/* The two buttons that set them, in the same colours. Off the paper, on the
   dialog: mid tones, readable on the light theme and on the dark. */
.abc-bound-btn-in { color: #22c55e; }
.abc-bound-btn-out { color: #3b82f6; }
.abc-bound-btn-in:hover, .abc-bound-btn-out:hover { background-color: rgb(var(--color-accent-ch) / 0.1); }

/* ── The score viewer's own controls ───────────────────────────────────────
   An icon button in the viewer's toolbar row. 36 layout px, which the app's
   zoom turns into 45 on a desktop and 32,4 on a phone — the floor `.tap-btn`
   sets for every other target in the app, and which these did not meet (21 px)
   until 2026-09-21. */
.abc-tool-btn{
  display: flex;
  flex-shrink: 0;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  border-radius: 0.375rem;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
  min-width: 2.25rem;
  min-height: 2.25rem;
  padding-inline: 0.375rem;
}
/* The versions' arrows when the row is short of room (fileViewer.ts
   `setNavNarrow`): as tall, narrower. */
.abc-tool-btn.abc-nav-narrow {
  min-width: 1.25rem;
  padding-inline: 0;
}

/* A switch in the transport row — the metronome, the swing, the key. One class
   for the three so they cannot drift apart, and `.abc-chip-on` for the state.
   Sized as a target first (36 px, the app's floor) and as a glyph second. */
.abc-chip{
  display: flex;
  flex-shrink: 0;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  border-radius: 0.375rem;
  border-width: 1px;
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  --tw-bg-opacity: 1;
  background-color: rgb(var(--color-bg-ch) / var(--tw-bg-opacity, 1));
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
  --tw-text-opacity: 1;
  color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
  min-width: 2.25rem;
  min-height: 2.25rem;
  padding-inline: 0.5rem;
}
.abc-chip:hover{
  --tw-text-opacity: 1;
  color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
}
.abc-chip-on{
  border-color: rgb(var(--color-accent-ch) / 0.4);
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
  background-color: rgb(var(--color-accent-ch) / 0.15);
}
.abc-chip-on:hover{
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
}

/* The ABC viewer's bottom row (fileViewer.ts, 2026-10-15): the transport in
   the middle, the source face's version buttons on the left and Save on the
   right, on one line. Equal outer columns keep the transport centred whatever
   is beside it. When the whole does not fit, `abc-bottom-stacked` (decided in
   code, from the pieces' natural widths) puts the transport on a line of its
   own and the two sides on the next. */
.abc-bottom-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.5rem;
}
.abc-bottom-row > .abc-bottom-start { grid-column: 1; grid-row: 1; justify-self: start; }
.abc-bottom-row > .abc-transport { grid-column: 2; grid-row: 1; }
.abc-bottom-row > .abc-bottom-end { grid-column: 3; grid-row: 1; justify-self: end; }
.abc-bottom-row.abc-bottom-stacked { grid-template-columns: 1fr 1fr; }
.abc-bottom-row.abc-bottom-stacked > .abc-transport { grid-column: 1 / -1; }
.abc-bottom-row.abc-bottom-stacked > .abc-bottom-start { grid-column: 1; grid-row: 2; }
.abc-bottom-row.abc-bottom-stacked > .abc-bottom-end { grid-column: 2; grid-row: 2; }
/* Nothing beside the transport (every face but the source): one column, the
   transport's own wrapping and nothing measured — see layoutBottomRow. */
.abc-bottom-row.abc-bottom-solo { grid-template-columns: minmax(0, 1fr); }
.abc-bottom-row.abc-bottom-solo > .abc-transport { grid-column: 1; }

/* The ABC source face's marks (fileViewer.ts, 2026-10-15), in its layer
   under the text. Where play will start: a bar against the note's left edge,
   in the stave cursor's colour — the same question as the cursor answers,
   the same answer. A shadow, not a border: a border would move the text, and
   the layer must keep every character exactly under the box's. */
.abc-text-start { box-shadow: -2px 0 0 0 var(--abc-cursor, #e11d48); }
/* The passage: a [ before its first note, a ] after its last, in the
   colours of the stave's flags (the user, 2026-10-15). Drawn by pseudo-
   elements taken out of the flow, so that not a character of the layer moves
   from under the box's; a little taller than the line, to read as brackets.
   The upright stands right against the note, outside it, where the plain
   bars were. The cursor's bar wins where both are on one note (the user,
   2026-10-15): the bracket is painted above the bar's shadow, so its upright
   is made see-through there, and the red shows where it stood. */
.abc-text-in, .abc-text-out { position: relative; }
.abc-text-in::before, .abc-text-out::after {
  content: '';
  position: absolute;
  top: -1px;
  bottom: -1px;
  box-sizing: border-box;
  width: 4px;
  border-style: solid;
  border-width: 1.5px;
  pointer-events: none;
}
.abc-text-in::before { left: -1.5px; border-color: var(--abc-in, #22c55e); border-right-width: 0; }
.abc-text-start.abc-text-in::before { border-left-color: transparent; }
.abc-text-out::after { right: -1.5px; border-color: var(--abc-out, #3b82f6); border-left-width: 0; }

/* What abcjs objects to, in the same layer (2026-10-19): the editor's wavy
   line, in the warning colour. A decoration, which moves nothing; its colour
   is given explicitly because the layer's text is transparent and a
   decoration otherwise takes the text's. */
.abc-text-warn {
  text-decoration-line: underline;
  text-decoration-style: wavy;
  text-decoration-color: rgb(var(--color-warn-ch));
  text-decoration-thickness: 1px;
  -webkit-text-decoration-skip-ink: none;
          text-decoration-skip-ink: none;
  text-underline-offset: 2px;
}

/* The note being played, in the ABC source face's layer (fileViewer.ts,
   2026-10-15). Not tinted any more: the cursor's bar moves onto it instead,
   as the stave's cursor does (the user, 2026-10-15). Still a <mark>, which the
   layer scrolls into view — so the browser's own yellow is taken off, and the
   layer's text stays transparent, the box over it drawing the letters. */
.abc-text-playing {
  color: transparent;
  background-color: transparent;
}

/* The full-page toggle in the score's top right corner — in the dialog and in
   the full-page reader alike (2026-10-10). Small and bare at the user's
   request: no plate of its own, just the glyph on the paper, in the paper's
   ink, with a hit area still worth a finger. `color-mix` keeps one rule for
   three papers instead of three rules that can drift apart. */
.abc-score-tool-small {
  min-width: 2rem;
  min-height: 2rem;
  background: transparent;
  color: color-mix(in srgb, var(--abc-ink, #000000) 55%, transparent);
}
.abc-score-tool-small:hover {
  color: var(--abc-ink, #000000);
  background: color-mix(in srgb, var(--abc-ink, #000000) 8%, transparent);
}



/* The sidebar's creation bar (sidebar.tsx): its two buttons keep their size,
   and their words go first when the sidebar is too narrow to hold them — not
   cut, gone; the icons and the tooltip say the rest (the user, 2026-11-11).
   The threshold is the bar's content width the two labelled buttons need,
   measured in layout px (2026-11-11): 182 in English, 194 in French (the
   wider "Dossier"/"Paquet"), so 200 with a little room — the labels stay down
   to a 217 px sidebar, the default being 224. A new language with longer
   words moves this number. */
.sidebar-new { container: sidebar-new / inline-size; }
@container sidebar-new (max-width: 12.49rem) { .sidebar-new-label { display: none; } }

/* Library list — show date column when container is wide enough */
.lib-list { container-type: inline-size; }
.lib-date { display: none; }
@container (min-width: 450px) { .lib-date { display: block; } }

/* Stats grid — container-query responsive (4 → 2 → 1 columns) */
.stats-container {
  container-type: inline-size;
}
.stats-grid {
  display: grid;
  grid-template-columns: 1fr;
}
@container (min-width: 280px) {
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
}
@container (min-width: 520px) {
  .stats-grid { grid-template-columns: repeat(4, 1fr); }
}

/* An analysis's list of detections, and what its width decides — for EVERY
   card of the list at once, never card by card (2026-10-30, the user's call):
   a tune inside a set is a little narrower than one on its own, and would tip
   over at another width than its neighbours — which is what both rules below
   did while each card was its own container.

   1. Where a detection's name goes: on the line of its controls, or on a line
      of its own below them, so that the lines stay aligned from one card to
      the next (a name that only went down when it did not fit broke them).
      Both forms of the name are drawn (DetectionCard's NavigableName); the
      spacer holds the end of the line while the name is not on it. Under
      440 px the names go below.

   2. The confidence badge's word: "élevée 87 %" → "87 %" under 340 px. It
      used to give its room to the name on the line (2026-09-21, "on sacrifie
      trop le titre"); with the names below by then, it only goes when the
      line itself runs short. The number always stays, settled by the user
      after a first pass dropped it too: a bare coloured pill reads as
      decoration, and the percentage is the part that says something.

   A CONTAINER query, not a media query. The app runs under a CSS zoom on
   <html> — 125 % on a desktop by default, 80 % on a phone, anything from 25 %
   to 500 % (zoomService) — so the viewport's pixels and the list's are not the
   same pixels. The list is measured in layout pixels, after the zoom: at
   125 % both rules bite on a window 1.25 times wider, at 80 % on one 0.8
   times as wide. One number each to move. */
.analysis-list { container: analysis-list / inline-size; }
.detection-name-below, .detection-name-spacer { display: none; }
@container analysis-list (max-width: 439.98px) {
  .detection-name-inline { display: none; }
  .detection-name-below { display: block; }
  .detection-name-spacer { display: block; }
}
@container analysis-list (max-width: 339.98px) { .detection-conf-word { display: none; } }

/* Drag & drop indicators */
.drop-before { box-shadow: inset 0 2px 0 0 var(--color-accent); }
.drop-after  { box-shadow: inset 0 -2px 0 0 var(--color-accent); }
.drop-into   { background-color: var(--color-accent-dim) !important; }
/* The same pair for a row that runs sideways instead of down — the card's tag
   pills, which wrap. "Before" is the left edge there, so the edge moves but
   the meaning does not. */
.drop-left   { box-shadow: inset 2px 0 0 0 var(--color-accent); }
.drop-right  { box-shadow: inset -2px 0 0 0 var(--color-accent); }

/* Legal footer — static in raw HTML so it stays crawlable without JS (Google OAuth review) */
#legal-footer {
  position: fixed;
  /* Above the gesture bar where the page runs under it (Android 15+, iOS). */
  bottom: calc(var(--safe-bottom) + 4px);
  right: 8px;
  font-size: 9px;
  opacity: 0.4;
  z-index: 1;
  pointer-events: none;
  color: inherit;
}
#legal-footer a { color: inherit; pointer-events: auto; }

/* Shown on the user selector and the recovery screen only (2026-10-08, user's
   call): once a user is open the links are in Settings → About, and the footer
   sat over every screen's bottom corner for nothing. HIDDEN, never removed:
   the markup must stay in index.html for the OAuth review, which reads the
   page without running it. `app-open` is set by AppRoot. */
html.app-open #legal-footer { display: none; }
/* Nor does it ride the on-screen keyboard (services/softKeyboard.ts). */
html.soft-keyboard-open #legal-footer { display: none; }

/* ── Walkthrough bubble (walkthrough/engine.ts) ───────────────────────────────
   driver.js's popover in the app's own clothes. It is zoomed back to 1 so its
   position matches its measurements (see `unzoom` there), so every length here
   is multiplied by the app's zoom to read at the app's size. Two classes (and
   three on the buttons): driver.css is loaded after this file and would win a
   tie. */
.driver-popover.cadence-tour {
  --tz: var(--zoom-factor, 1);
  font-family: 'IBM Plex Sans', system-ui, sans-serif;
  background: rgb(var(--color-elevated-ch));
  color: rgb(var(--color-primary-ch));
  border: 1px solid rgb(var(--color-border-ch));
  border-radius: calc(12px * var(--tz));
  padding: calc(16px * var(--tz));
  min-width: calc(250px * var(--tz));
  max-width: min(calc(330px * var(--tz)), calc(100vw - 24px));
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.35);
  /* Shown once the lit box has reached its element (engine.ts, onHighlighted),
     not half-way there as driver.js would: its own fade is replaced. */
  opacity: 0;
  transition: opacity 160ms ease-out;
}
.driver-popover.cadence-tour.tour-shown { opacity: 1; }
/* driver.css's fade (`.driver-fade .driver-popover`) would show it at once. */
.driver-fade .driver-popover.cadence-tour { animation: none; }
.driver-popover.cadence-tour .driver-popover-title {
  font-size: calc(15px * var(--tz));
  font-weight: 600;
  line-height: 1.35;
  padding-right: calc(22px * var(--tz));
}
.driver-popover.cadence-tour .driver-popover-description {
  font-size: calc(13px * var(--tz));
  line-height: 1.55;
  color: rgb(var(--color-muted-ch));
}
.driver-popover.cadence-tour .driver-popover-description strong { color: rgb(var(--color-primary-ch)); font-weight: 600; }
.driver-popover.cadence-tour .driver-popover-description code {
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: 0.9em;
  padding: 0 0.3em;
  border-radius: 4px;
  background: rgb(var(--color-surface-ch));
  border: 1px solid rgb(var(--color-border-ch));
}
.driver-popover.cadence-tour .driver-popover-footer { margin-top: calc(14px * var(--tz)); }
.driver-popover.cadence-tour .driver-popover-progress-text {
  font-size: calc(12px * var(--tz));
  color: rgb(var(--color-dim-ch));
  font-variant-numeric: tabular-nums;
}
.driver-popover.cadence-tour .driver-popover-footer .driver-popover-footer-btn {
  font-family: inherit;
  font-size: calc(13px * var(--tz));
  font-weight: 500;
  padding: calc(6px * var(--tz)) calc(14px * var(--tz));
  border-radius: calc(6px * var(--tz));
  border: none;
  background: rgb(var(--color-accent-ch));
  color: #fff;
  text-shadow: none;
}
.driver-popover.cadence-tour .driver-popover-footer .driver-popover-footer-btn:hover,
.driver-popover.cadence-tour .driver-popover-footer .driver-popover-footer-btn:focus-visible {
  background: var(--color-accent-hover);
}
.driver-popover.cadence-tour .driver-popover-footer .driver-popover-footer-btn:focus-visible {
  outline: 2px solid rgb(var(--color-accent-ch) / 0.5);
  outline-offset: 2px;
}
.driver-popover.cadence-tour .driver-popover-close-btn {
  color: rgb(var(--color-dim-ch));
  width: calc(34px * var(--tz));
  height: calc(34px * var(--tz));
  font-size: calc(18px * var(--tz));
}
.driver-popover.cadence-tour .driver-popover-close-btn:hover,
.driver-popover.cadence-tour .driver-popover-close-btn:focus { color: rgb(var(--color-primary-ch)); }
/* The arrow is a bordered box with three sides transparent: the fourth takes
   the bubble's colour. */
.driver-popover.cadence-tour .driver-popover-arrow { border-width: calc(6px * var(--tz)); }
.driver-popover.cadence-tour .driver-popover-arrow-side-left   { border-left-color:   rgb(var(--color-elevated-ch)); }
.driver-popover.cadence-tour .driver-popover-arrow-side-right  { border-right-color:  rgb(var(--color-elevated-ch)); }
.driver-popover.cadence-tour .driver-popover-arrow-side-top    { border-top-color:    rgb(var(--color-elevated-ch)); }
.driver-popover.cadence-tour .driver-popover-arrow-side-bottom { border-bottom-color: rgb(var(--color-elevated-ch)); }
/* Moved off the controls it would have covered (walkthrough/placement.ts):
   no longer beside the lit element, so its arrow would point at nothing. */
.driver-popover.cadence-tour.tour-detached .driver-popover-arrow { display: none; }
/* A deck's cards while a walkthrough has the user link one: the field's list
   of matches hangs below it, over the rows, and must stay inside the lit box
   — what is outside it lies under the veil and cannot be pressed. */
.driver-active [data-tour="deck-cards"] { min-height: 22rem; }
/* A walkthrough of the Irish trad extension: framed in its green, as its lines
   are in the help (help.tsx's ExtensionBox). */
.driver-popover.cadence-tour.cadence-tour-irish { border-color: rgb(var(--color-irish-ch) / 0.6); }
/* A list hanging from the lit field but drawn elsewhere on the page — a search
   field's suggestions (data-tour-float): over the veil, and pickable. */
.driver-active [data-tour-float] { z-index: 10001 !important; }
.driver-active [data-tour-float], .driver-active [data-tour-float] * { pointer-events: auto; }
@media (min-width: 1024px){
  html.ios .lg\:overflow-y-auto { overscroll-behavior-y: contain; }
}
.placeholder\:italic::-moz-placeholder{
  font-style: italic;
}
.placeholder\:italic::placeholder{
  font-style: italic;
}
.placeholder\:text-dim::-moz-placeholder{
  --tw-text-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-text-opacity, 1));
}
.placeholder\:text-dim::placeholder{
  --tw-text-opacity: 1;
  color: rgb(var(--color-dim-ch) / var(--tw-text-opacity, 1));
}
.before\:absolute::before{
  content: var(--tw-content);
  position: absolute;
}
.before\:-inset-y-\[5px\]::before{
  content: var(--tw-content);
  top: -5px;
  bottom: -5px;
}
.before\:inset-x-0::before{
  content: var(--tw-content);
  left: 0px;
  right: 0px;
}
.before\:content-\[\'\'\]::before{
  --tw-content: '';
  content: var(--tw-content);
}
.last\:border-0:last-child{
  border-width: 0px;
}
.focus-within\:border-accent:focus-within{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
}
@media (hover: hover) and (pointer: fine){

  .hover\:border-\[rgba\(37\2c 211\2c 102\2c \.6\)\]:hover{
    border-color: rgba(37,211,102,.6);
  }

  .hover\:border-accent:hover{
    --tw-border-opacity: 1;
    border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
  }

  .hover\:border-accent\/50:hover{
    border-color: rgb(var(--color-accent-ch) / 0.5);
  }

  .hover\:border-accent\/60:hover{
    border-color: rgb(var(--color-accent-ch) / 0.6);
  }

  .hover\:border-dim:hover{
    --tw-border-opacity: 1;
    border-color: rgb(var(--color-dim-ch) / var(--tw-border-opacity, 1));
  }

  .hover\:border-irish:hover{
    --tw-border-opacity: 1;
    border-color: rgb(var(--color-irish-ch) / var(--tw-border-opacity, 1));
  }

  .hover\:border-irish\/60:hover{
    border-color: rgb(var(--color-irish-ch) / 0.6);
  }

  .hover\:border-muted:hover{
    --tw-border-opacity: 1;
    border-color: rgb(var(--color-muted-ch) / var(--tw-border-opacity, 1));
  }

  .hover\:bg-\[rgba\(37\2c 211\2c 102\2c \.12\)\]:hover{
    background-color: rgba(37,211,102,.12);
  }

  .hover\:bg-accent\/10:hover{
    background-color: rgb(var(--color-accent-ch) / 0.1);
  }

  .hover\:bg-accent\/20:hover{
    background-color: rgb(var(--color-accent-ch) / 0.2);
  }

  .hover\:bg-accent\/5:hover{
    background-color: rgb(var(--color-accent-ch) / 0.05);
  }

  .hover\:bg-bg:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-bg-ch) / var(--tw-bg-opacity, 1));
  }

  .hover\:bg-black\/10:hover{
    background-color: rgb(0 0 0 / 0.1);
  }

  .hover\:bg-border\/60:hover{
    background-color: rgb(var(--color-border-ch) / 0.6);
  }

  .hover\:bg-danger\/10:hover{
    background-color: rgb(var(--color-danger-ch) / 0.1);
  }

  .hover\:bg-danger\/20:hover{
    background-color: rgb(var(--color-danger-ch) / 0.2);
  }

  .hover\:bg-elevated:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-elevated-ch) / var(--tw-bg-opacity, 1));
  }

  .hover\:bg-irish\/5:hover{
    background-color: rgb(var(--color-irish-ch) / 0.05);
  }

  .hover\:bg-success\/20:hover{
    background-color: rgb(var(--color-success-ch) / 0.2);
  }

  .hover\:bg-surface:hover{
    --tw-bg-opacity: 1;
    background-color: rgb(var(--color-surface-ch) / var(--tw-bg-opacity, 1));
  }

  .hover\:bg-transparent:hover{
    background-color: transparent;
  }

  .hover\:bg-warn\/10:hover{
    background-color: rgb(var(--color-warn-ch) / 0.1);
  }

  .hover\:bg-warn\/20:hover{
    background-color: rgb(var(--color-warn-ch) / 0.2);
  }

  .hover\:text-accent:hover{
    --tw-text-opacity: 1;
    color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
  }

  .hover\:text-accent\/70:hover{
    color: rgb(var(--color-accent-ch) / 0.7);
  }

  .hover\:text-danger:hover{
    --tw-text-opacity: 1;
    color: rgb(var(--color-danger-ch) / var(--tw-text-opacity, 1));
  }

  .hover\:text-gold:hover{
    --tw-text-opacity: 1;
    color: rgb(var(--color-gold-ch) / var(--tw-text-opacity, 1));
  }

  .hover\:text-muted:hover{
    --tw-text-opacity: 1;
    color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  }

  .hover\:text-primary:hover{
    --tw-text-opacity: 1;
    color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
  }

  .hover\:text-success:hover{
    --tw-text-opacity: 1;
    color: rgb(var(--color-success-ch) / var(--tw-text-opacity, 1));
  }

  .hover\:underline:hover{
    text-decoration-line: underline;
  }

  .hover\:opacity-100:hover{
    opacity: 1;
  }

  .hover\:opacity-90:hover{
    opacity: 0.9;
  }

  .hover\:brightness-110:hover{
    --tw-brightness: brightness(1.1);
    filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
  }

  .hover\:brightness-125:hover{
    --tw-brightness: brightness(1.25);
    filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
  }
}
.focus\:border-accent:focus{
  --tw-border-opacity: 1;
  border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
}
.active\:cursor-grabbing:active{
  cursor: grabbing;
}
.active\:text-accent:active{
  --tw-text-opacity: 1;
  color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
}
.disabled\:cursor-default:disabled{
  cursor: default;
}
.disabled\:cursor-not-allowed:disabled{
  cursor: not-allowed;
}
.disabled\:opacity-100:disabled{
  opacity: 1;
}
.disabled\:opacity-40:disabled{
  opacity: 0.4;
}
@media (hover: hover) and (pointer: fine){

  .disabled\:hover\:bg-transparent:hover:disabled{
    background-color: transparent;
  }

  .disabled\:hover\:text-dim:hover:disabled{
    --tw-text-opacity: 1;
    color: rgb(var(--color-dim-ch) / var(--tw-text-opacity, 1));
  }

  .disabled\:hover\:text-muted:hover:disabled{
    --tw-text-opacity: 1;
    color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  }

  .group:hover .group-hover\:translate-x-0\.5{
    --tw-translate-x: 0.125rem;
    transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
  }

  .group:hover .group-hover\:border-accent{
    --tw-border-opacity: 1;
    border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
  }

  .group:hover .group-hover\:border-accent\/50{
    border-color: rgb(var(--color-accent-ch) / 0.5);
  }

  .group:hover .group-hover\:bg-accent\/20{
    background-color: rgb(var(--color-accent-ch) / 0.2);
  }

  .group:hover .group-hover\:bg-accent\/40{
    background-color: rgb(var(--color-accent-ch) / 0.4);
  }

  .group:hover .group-hover\:bg-danger\/20{
    background-color: rgb(var(--color-danger-ch) / 0.2);
  }

  .group:hover .group-hover\:bg-success\/20{
    background-color: rgb(var(--color-success-ch) / 0.2);
  }

  .group:hover .group-hover\:bg-warn\/20{
    background-color: rgb(var(--color-warn-ch) / 0.2);
  }

  .group:hover .group-hover\:text-accent{
    --tw-text-opacity: 1;
    color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
  }

  .group:hover .group-hover\:text-muted{
    --tw-text-opacity: 1;
    color: rgb(var(--color-muted-ch) / var(--tw-text-opacity, 1));
  }

  .group:hover .group-hover\:text-primary{
    --tw-text-opacity: 1;
    color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
  }

  .group:hover .group-hover\:text-warn{
    --tw-text-opacity: 1;
    color: rgb(var(--color-warn-ch) / var(--tw-text-opacity, 1));
  }

  .group:hover .group-hover\:opacity-100{
    opacity: 1;
  }

  .group:hover .group-hover\:brightness-110{
    --tw-brightness: brightness(1.1);
    filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
  }

  .hoverable\:border-accent:hover{
    --tw-border-opacity: 1;
    border-color: rgb(var(--color-accent-ch) / var(--tw-border-opacity, 1));
  }

  .hoverable\:bg-accent\/20:hover{
    background-color: rgb(var(--color-accent-ch) / 0.2);
  }

  .hoverable\:text-accent:hover{
    --tw-text-opacity: 1;
    color: rgb(var(--color-accent-ch) / var(--tw-text-opacity, 1));
  }

  .hoverable\:text-primary:hover{
    --tw-text-opacity: 1;
    color: rgb(var(--color-primary-ch) / var(--tw-text-opacity, 1));
  }
}
@media (min-width: 480px){

  .min-\[480px\]\:p-5{
    padding: 1.25rem;
  }

  .min-\[480px\]\:text-3xl{
    font-size: 1.875rem;
    line-height: 2.25rem;
  }
}
@media (min-width: 520px){

  .min-\[520px\]\:grid-cols-2{
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 640px){

  .sm\:inline{
    display: inline;
  }

  .sm\:flex-1{
    flex: 1 1 0%;
  }

  .sm\:flex-row{
    flex-direction: row;
  }

  .sm\:items-center{
    align-items: center;
  }

  .sm\:gap-3{
    gap: 0.75rem;
  }

  .sm\:self-auto{
    align-self: auto;
  }

  .sm\:truncate{
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .sm\:whitespace-nowrap{
    white-space: nowrap;
  }

  .sm\:p-8{
    padding: 2rem;
  }

  .sm\:px-14{
    padding-left: 3.5rem;
    padding-right: 3.5rem;
  }
}
@media (min-width: 900px){

  .min-\[900px\]\:grid-cols-4{
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (min-width: 1024px){

  .lg\:my-auto{
    margin-top: auto;
    margin-bottom: auto;
  }

  .lg\:flex{
    display: flex;
  }

  .lg\:hidden{
    display: none;
  }

  .lg\:min-w-0{
    min-width: 0px;
  }

  .lg\:max-w-\[640px\]{
    max-width: 640px;
  }

  .lg\:flex-1{
    flex: 1 1 0%;
  }

  .lg\:flex-\[1\.3\]{
    flex: 1.3;
  }

  .lg\:flex-row{
    flex-direction: row;
  }

  .lg\:gap-3{
    gap: 0.75rem;
  }

  .lg\:overflow-hidden{
    overflow: hidden;
  }

  .lg\:overflow-y-auto{
    overflow-y: auto;
  }

  .lg\:border-l{
    border-left-width: 1px;
  }

  .lg\:border-border{
    --tw-border-opacity: 1;
    border-color: rgb(var(--color-border-ch) / var(--tw-border-opacity, 1));
  }

  .lg\:bg-surface\/40{
    background-color: rgb(var(--color-surface-ch) / 0.4);
  }

  .lg\:py-10{
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
  }

  .lg\:pt-\[72px\]{
    padding-top: 72px;
  }

  .lg\:text-\[30px\]{
    font-size: 30px;
  }
}
.\[\&\>\*\]\:flex-1>*{
  flex: 1 1 0%;
}
.\[\&\>svg\]\:h-\[1\.1em\]>svg{
  height: 1.1em;
}
.\[\&\>svg\]\:w-\[1\.1em\]>svg{
  width: 1.1em;
}
.\[\&\>svg\]\:shrink-0>svg{
  flex-shrink: 0;
}
@media(pointer:coarse){

  .\[\@media\(pointer\:coarse\)\]\:hidden{
    display: none;
  }
}

/* Some basic CSS to make the Audio controls in abcjs presentable. */

.abcjs-inline-audio {
	height: 26px;
	padding: 0 5px;
	border-radius: 3px;
	background-color: #424242;
	display: flex;
	align-items: center;
	box-sizing: border-box;
}

.abcjs-inline-audio.abcjs-disabled {
	opacity: 0.5;
}

.abcjs-inline-audio .abcjs-btn {
	display: block;
	width: 28px;
	height: 34px;
	margin-right: 2px;
	padding: 7px 4px;

	background: none !important;
	border: 1px solid transparent;
	box-sizing: border-box;
	line-height: 1;
}

.abcjs-btn g {
	fill: #f4f4f4;
	stroke: #f4f4f4;
}

.abcjs-inline-audio .abcjs-btn:hover g {
	fill: #cccccc;
	stroke: #cccccc;
}

.abcjs-inline-audio .abcjs-midi-selection.abcjs-pushed {
	border: 1px solid #cccccc;
	background-color: #666666;
	box-sizing: border-box;
}

.abcjs-inline-audio .abcjs-midi-loop.abcjs-pushed {
	border: 1px solid #cccccc;
	background-color: #666666;
	box-sizing: border-box;
}

.abcjs-inline-audio .abcjs-midi-reset.abcjs-pushed {
	border: 1px solid #cccccc;
	background-color: #666666;
	box-sizing: border-box;
}

.abcjs-inline-audio .abcjs-midi-start .abcjs-pause-svg {
	display: none;
}

.abcjs-inline-audio .abcjs-midi-start .abcjs-loading-svg {
	display: none;
}

.abcjs-inline-audio .abcjs-midi-start.abcjs-pushed .abcjs-play-svg {
	display: none;
}

.abcjs-inline-audio .abcjs-midi-start.abcjs-loading .abcjs-play-svg {
	display: none;
}

.abcjs-inline-audio .abcjs-midi-start.abcjs-pushed .abcjs-pause-svg {
	display: block;
}

.abcjs-inline-audio .abcjs-midi-progress-background {
	background-color: #424242;
	height: 10px;
	border-radius: 5px;
	border: 2px solid #cccccc;
	margin: 0 8px 0 15px;
	position: relative;
	flex: 1;
	padding: 0;
	box-sizing: border-box;
}

.abcjs-inline-audio .abcjs-midi-progress-indicator {
	width: 20px;
	margin-left: -10px; /* half of the width */
	height: 14px;
	background-color: #f4f4f4;
	position: absolute;
	display: inline-block;
	border-radius: 6px;
	top: -4px;
	left: 0;
	box-sizing: border-box;
}

.abcjs-inline-audio .abcjs-midi-clock {
	margin-left: 4px;
	margin-top: 1px;
	margin-right: 2px;
	display: inline-block;
	font-family: sans-serif;
	font-size: 16px;
	box-sizing: border-box;
	color: #f4f4f4;
}

.abcjs-inline-audio .abcjs-tempo-wrapper {
	font-size: 10px;
	color: #f4f4f4;
	box-sizing: border-box;
	display: flex;
	align-items: center;
}

.abcjs-inline-audio .abcjs-midi-tempo {
	border-radius: 2px;
	border: none;
	margin: 0 2px 0 4px;
	width: 42px;
	padding-left: 2px;
	box-sizing: border-box;
}

.abcjs-inline-audio .abcjs-loading .abcjs-loading-svg {
	display: inherit;
}

.abcjs-inline-audio .abcjs-loading {
	outline: none;
	animation-name: abcjs-spin;
	animation-duration: 1s;
	animation-iteration-count: infinite;
	animation-timing-function: linear;

}
.abcjs-inline-audio .abcjs-loading-svg circle {
	stroke: #f4f4f4;
}

@keyframes abcjs-spin {
	from {transform:rotate(0deg);}
	to {transform:rotate(360deg);}
}

/* Adding the class "abcjs-large" will make the control easier on a touch device. */
.abcjs-large .abcjs-inline-audio {
	height: 52px;
}
.abcjs-large .abcjs-btn {
	width: 56px;
	height: 52px;
	font-size: 28px;
	padding: 6px 8px;
}
.abcjs-large .abcjs-midi-progress-background {
	height: 20px;
	border: 4px solid #cccccc;
}
.abcjs-large .abcjs-midi-progress-indicator {
	height: 28px;
	top: -8px;
	width: 40px;
}
.abcjs-large .abcjs-midi-clock {
	font-size: 32px;
	margin-right: 10px;
	margin-left: 10px;
	margin-top: -1px;
}
.abcjs-large .abcjs-midi-tempo {
	font-size: 20px;
	width: 50px;
}
.abcjs-large .abcjs-tempo-wrapper {
	font-size: 20px;
}

.abcjs-css-warning {
	display: none;
}

