/* cyrillic-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/ad99a4c1cf58.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/4f12a1a0ae41.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/e3000ed81c87.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/a3b94a5a967d.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/52ea38a7d8d6.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/ad99a4c1cf58.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/4f12a1a0ae41.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/e3000ed81c87.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/a3b94a5a967d.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/52ea38a7d8d6.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/c18dbd11ca5b.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/ac78c6c2ff98.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/8a92de9f3770.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/a9e49ee5f58f.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/74db058fe06d.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/c18dbd11ca5b.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/ac78c6c2ff98.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/8a92de9f3770.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/a9e49ee5f58f.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/74db058fe06d.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/c18dbd11ca5b.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/ac78c6c2ff98.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/8a92de9f3770.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/a9e49ee5f58f.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/74db058fe06d.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/c18dbd11ca5b.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/ac78c6c2ff98.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/8a92de9f3770.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/a9e49ee5f58f.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/74db058fe06d.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/dced7149525e.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/7de3c5b4c5e7.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/7af61c95c207.woff2") format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/6cd1f63be011.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/8462a12a7c78.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/a5a4517fcbf1.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/4f8405520dc8.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/fe6ea7dc48cb.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/3f2b7e2b2ef8.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/4f8405520dc8.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/fe6ea7dc48cb.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/3f2b7e2b2ef8.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/9b967522bc5a.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/d30ef885441c.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/e599ceb478c4.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/9b967522bc5a.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/d30ef885441c.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/e599ceb478c4.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/9b967522bc5a.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/d30ef885441c.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/e599ceb478c4.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/9b967522bc5a.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/d30ef885441c.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/e599ceb478c4.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Fragment Mono';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("fonts/89d1b754bb47.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fragment Mono';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("fonts/62caf587b650.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Fragment Mono';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("fonts/89d1b754bb47.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fragment Mono';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("fonts/62caf587b650.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Fragment Mono';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("fonts/89d1b754bb47.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Fragment Mono';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("fonts/62caf587b650.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

  

  /* --accent is the TEXT-SAFE rendering of the brand vermilion, per theme.
     #E34234 is the brand red and stays the brand red in graphics — the mark,
     the ring's centre dot, the og cards, the selection wash. But as TEXT on
     white it measures 4.12:1, under the 4.5:1 WCAG AA needs for normal-size
     text, and it is used at 11-12px for every category eyebrow, prose link and
     the 404 copy. Those are the smallest text on the site failing the contrast
     floor, which is the wrong way round.
     So the token carries a value tuned to its own theme's background: darker on
     white, lighter on black, hue held at 4.8deg so it is recognisably the same
     red. Measured: #D12B1D is 5.15:1 on #FFFFFF and 4.60:1 on #F2F2F2 (hover);
     #E54E41 is 5.50:1 on #000000 and 4.60:1 on #191919 (card).
     A graphic has no such floor (3:1 applies to UI components, and both values
     clear it), which is why the brand literal is left alone where it is drawn
     rather than read. */
  /* --accent-strong is the pressed/hovered accent: more contrast than --accent,
     not less. It exists because the hover colour was the literal #B6352A,
     written straight into the .catlink rule. On white that is 5.95:1 and fine.
     In dark mode it was 2.96:1 against a card — so hovering a category link
     made it HARDER to read than leaving it alone, and being a literal, no theme
     could correct it. Same class of bug as --accent itself: a colour named in
     one place and used in another. */
  #site-root { --bg:#FFFFFF; --fg:#060606; --faded:#5B5F66; --border:#E5E5E5; --tileborder:#CCCCCC; --accent:#D12B1D; --accent-strong:#B6352A; --hover:#F2F2F2; --imgline:var(--fg); }

  #site-root [data-tile] { text-decoration:none; }

  #site-root [data-tile] [data-dot] { opacity:0; transition:opacity 0.18s ease; }

  #site-root [data-tile] [data-label] { transition:transform 0.18s ease; }

  /* :hover for pointers (clears when the pointer leaves); :active mirrors it so
     touch gets the same feedback while pressed but it never sticks after
     release. See the note near .article-card. */
  @media (hover: hover) {
    #site-root [data-tile]:hover { background:var(--hover); }
    #site-root [data-tile]:hover [data-dot] { opacity:1; }
    #site-root [data-tile]:hover [data-label] { transform:translateX(17px); }
  }
  #site-root [data-tile]:active { background:var(--hover); }
  #site-root [data-tile]:active [data-dot] { opacity:1; }
  #site-root [data-tile]:active [data-label] { transform:translateX(17px); }

  #site-root[data-theme="alt"] { --bg:#000000; --fg:#FFFFFF; --faded:rgba(255,255,255,0.56); --border:rgba(255,255,255,0.14); --tileborder:rgba(255,255,255,0.24); --accent:#E54E41; --accent-strong:#EA7469; --hover:rgba(255,255,255,0.06); --imgline:rgba(255,255,255,0.32); }

  /* Safety net: a re-render can momentarily drop #site-root's data-theme (it is
     restored in componentDidUpdate). Keying the dark tokens off the never-rebuilt
     <html data-theme="alt"> as well means the surface never flashes back to paper. */
  html[data-theme="alt"] #site-root { --bg:#000000; --fg:#FFFFFF; --faded:rgba(255,255,255,0.56); --border:rgba(255,255,255,0.14); --tileborder:rgba(255,255,255,0.24); --accent:#E54E41; --accent-strong:#EA7469; --hover:rgba(255,255,255,0.06); --imgline:rgba(255,255,255,0.32); }

  /* DEFAULT: image frames = black in light, muted #41463F in dark; nav tiles = stronger both modes */
  /* tweak: 'prev' = faint hairline on BOTH nav tiles and image-card frames */
  #site-root[data-tilestroke="prev"] { --tileborder:var(--border); --imgline:var(--border); }

  /* tweak: 'white' = original glaring-white dark image frames (reference) */
  #site-root[data-theme="alt"][data-tilestroke="white"] { --imgline:var(--fg); }

  /* Kill only the mobile browser's tap-flash (the blue/grey sheen). Real links
     keep their native long-press menu — we no longer suppress touch-callout. */
  * { -webkit-tap-highlight-color: transparent; }

  /* ===== card links (semantic "stretched link") =====
     A card's title is a real <a class="cardlink">; its ::after overlay covers
     the whole .article-card so a click/tap anywhere navigates to the article. The
     nested category chip (.catlink) sits above the overlay so it stays its own
     link (→ topic). Title reddens on hover (real pointers) and press/hold
     (touch, via :active, which clears on release) to nudge the tap. */
  .article-card { position: relative; }

  .cardlink { color: inherit; text-decoration: none; transition: color 0.2s; }

  .cardlink::after { content: ""; position: absolute; inset: 0; z-index: 1; }

  .catlink { position: relative; z-index: 2; color: inherit; text-decoration: none; }

  /* The category label reads light, and `font-weight: 500` on it — which is
     what the markup asks for — does nothing at all. Fragment Mono ships a
     single weight with no weight axis, and the @font-face blocks declare 400,
     500 and 600 against that one file, so the browser finds an exact match at
     each and never synthesises either. Measured as ink coverage over the same
     string at 56px, 400 against 700: Cormorant +51.9%, Newsreader +67.7%,
     Fragment Mono +0.0%. Raising the number is not the fix; nothing downstream
     of it is listening.

     A hairline stroke in the glyph's own colour is, and it is the one lever
     that adds weight rather than size. 0.35 at 11.5px: enough to hold its own
     under a 700-weight headline, short of the point where the counters in a
     and e start to silt up, which is around 0.5.

     Homepage only, because the three row templates are not one component: the
     archive's label is an unclassed Fragment Mono at 12px, and the topic row's
     is Newsreader, which has a real weight axis and can be bolded by asking.
     Only these two have something to hang the rule on.

     The featured card is in the list because it now prints the same category in
     the same face; before that it said "Featured" and was not this component at
     all. Without the stroke it was the one category label on the page rendering
     a weight lighter than the rest — and raising its font-weight would have
     done nothing, for the reason above. Same 0.35: it sets at 11px against the
     rows' 11.5, close enough that a separate value would be false precision. */
  .row-eyebrow,
  [data-feat-label] { -webkit-text-stroke: 0.35px currentColor; }

  /* Home category label: darken to a deeper red and underline on hover/press.
     Both the rows and the featured card — the featured slot used to print a
     static "Featured" here with nothing to hover, so the rule only ever named
     .row-eyebrow. Now that it carries the same category link as every other
     card, it has to behave like one. */
  @media (hover: hover) {
    .row-eyebrow .catlink:hover,
    [data-feat-label] .catlink:hover { color: var(--accent-strong); text-decoration: underline; text-underline-offset: 2px; }
  }
  .row-eyebrow .catlink:active,
  [data-feat-label] .catlink:active { color: var(--accent-strong); text-decoration: underline; text-underline-offset: 2px; }

  @media (hover: hover) { .cardlink:hover { color: var(--accent); }
 }
  .cardlink:active { color: var(--accent); }

  /* ===== coming soon =====
     A piece announced before it is ready (status: "soon" in the article list).
     The card keeps its place in the listing so the reader can see what is on
     the way, but it is not an offer: faded well back, no pointer, no hover, and
     — the part CSS cannot be trusted with on its own — no href anywhere in it
     (tools/build.mjs writes plain spans where the links would be). The title
     drops to the faded ink rather than the headline black, so it reads as a
     note about an article rather than the article's own name.

     .42, not lower: the art and the dek still have to be legible as a preview
     of the piece. Fading the whole card rather than tinting each part keeps the
     three row layouts identical to their live neighbours in every other way. */
  .article-card[data-soon] { opacity: 0.42; pointer-events: none; cursor: default; user-select: none; }
  .article-card[data-soon] [data-title],
  .article-card[data-soon] h2 { color: var(--faded); }

  /* The chip stands where the date would: the article page's category kicker
     (reader.a65cd3da62.css .kicker), the same outlined box in the mono with the accent
     node, so the vocabulary of "a label about this piece" is one shape across
     the site. */
  .soon-chip { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--fg); padding: 2.5px 10px; font-family: 'Fragment Mono', monospace; font-size: 11px; letter-spacing: 0.04em; color: var(--fg); white-space: nowrap; vertical-align: middle; }
  .soon-chip-dot { flex: none; width: 6px; height: 6px; background: var(--accent); }

  /* Search result rows are whole-row real links (.wos-hit). Hover/press cue. */
  .wos-hit { transition: background 0.18s; }

  .wos-hit [data-title] { transition: color 0.18s; }

  @media (hover: hover) { .wos-hit:hover { background: var(--hover); }
 .wos-hit:hover [data-title] { color: var(--accent); }
 }
  .wos-hit:active [data-title] { color: var(--accent); }

  /* ===== menu button icon (CSS bars, morphs to X) =====
     A 4-bar hamburger: bars 1 & 4 are the full top/bottom lines; bars 2 & 3 are
     two overlapping SHORT bars stacked at the centre, so at rest they read as a
     single 70%-width middle line. On open, the top/bottom fade inward and the
     two middle bars scissor into an X — the X forms *inside* the hamburger
     footprint, where the middle line was (cf. worksinprogress.co). */
  .hamburger { display:inline-block; position:relative; width:26px; height:18px; }

  .hamburger i {
    position:absolute; height:2px; background:currentColor; border-radius:2px;
    transition:transform .32s cubic-bezier(.2,.72,.28,1), opacity .2s ease, width .28s ease;
  }

  .hamburger i:nth-child(1) { top:1px; left:0; width:100%; }

  .hamburger i:nth-child(4) { bottom:1px; left:0; width:100%; }

  .hamburger i:nth-child(2), .hamburger i:nth-child(3) { top:50%; left:50%; width:70%; transform:translate(-50%,-50%) rotate(0deg); }

  [data-menu-toggle][data-open] .hamburger i:nth-child(1) { opacity:0; transform:translateY(4px); }

  [data-menu-toggle][data-open] .hamburger i:nth-child(4) { opacity:0; transform:translateY(-4px); }

  [data-menu-toggle][data-open] .hamburger i:nth-child(2) { width:100%; transform:translate(-50%,-50%) rotate(45deg); }

  [data-menu-toggle][data-open] .hamburger i:nth-child(3) { width:100%; transform:translate(-50%,-50%) rotate(-45deg); }

  /* hide-on-scroll (mobile/tablet only): site.js toggles .mast-hidden when
     scrolling down and clears it on scroll-up; slide the sticky header up out of
     view. Desktop keeps it pinned (no rule here). Reduced-motion keeps it pinned. */
  @media (max-width: 1023.98px) {
    [data-site] header#masthead.mast-hidden { transform: translateY(-100%); }
  }
  @media (prefers-reduced-motion: reduce) {
    [data-site] header#masthead.mast-hidden { transform: none; }
  }

  /* condensed (scrolled) masthead height: compact on phone/tablet, a taller
     ~83px bar on desktop so the sticky header matches the reader's. */
  header#masthead.mast-condensed { padding-top: 14px !important; padding-bottom: 14px !important; }

  @media (min-width: 1024px) { [data-site] header#masthead.mast-condensed { padding-top: 24px !important; padding-bottom: 24px !important; } }

  /* ---- PHONE: single-column architecture ---- */
  /* ---- PHONE masthead: static single-line lockup ----
     Globe on the left, wordmark centred to the viewport, menu button on the
     right — one fixed layout, no scroll morph (the .mast-condensed selectors
     carry identical values so scrolling changes nothing). Only the single-line
     lockup is used on phone (the stacked variant is hidden). Globe + wordmark stay
     inside the home link, so either navigates home. Everything is positioned
     within the sticky header (its positioning context); desktop/tablet and the
     reader keep the shared lockup untouched. */
  @media (max-width: 759.98px) { [data-site] header#masthead [data-lockup="stacked"] { display: none !important; } }

  /* Globe policy: hidden by default (wordmark-only). Desktop/tablet keep it hidden
     — the wordmark is left-aligned and the right-side top-nav balances it, so a
     centred wordmark would fight the nav. Phone RE-SHOWS the globe in the left
     corner with the wordmark centred (see the phone globe rule below): centring
     reads well on phone precisely because there's no top-nav to balance against,
     and the corner globe anchors the otherwise-sparse left. */
  header#masthead #globe-single { display: none !important; }

  /* phone lockup container: neutral block spanning the header so the globe and
     wordmark position absolutely against the sticky header (no transform here, or
     it would become the containing block and re-trap the absolute children). */
  @media (max-width: 759.98px) { [data-site] header#masthead [data-lockup="single"] {
    display: block !important; position: static !important; transform: none !important;
  } }

  @media (max-width: 759.98px) { [data-site] header#masthead, [data-site] header#masthead.mast-condensed {
    padding: 0 !important;
    min-height: 66px;
    /* full-bleed: break out of the 8px body margin so the bottom divider runs
       edge to edge. */
    margin-left: -8px !important; margin-right: -8px !important;
  } }

  /* globe: re-shown on phone, tucked into the left corner, vertically centred */
  @media (max-width: 759.98px) { [data-site] header#masthead #globe-single, [data-site] header#masthead.mast-condensed #globe-single {
    display: inline-flex !important;
    position: absolute !important; left: 14px !important; top: 50%;
    transform: translateY(-50%); margin: 0 !important; flex: none;
    width: 44px !important; height: 44px !important;
  } }

  /* wordmark: centred across the full header width (globe sits under its left edge,
     menu under its right — the wordmark spans between them, centred). */
  @media (max-width: 759.98px) { [data-site] header#masthead [data-lockup="single"] > span:last-child, [data-site] header#masthead.mast-condensed [data-lockup="single"] > span:last-child {
    position: absolute !important; left: 50% !important; right: auto !important;
    top: 50%; transform: translate(-50%, -50%);
    font-size: 28px !important; line-height: 1.05 !important;
    text-align: center !important; white-space: nowrap;
  } }

  /* menu button: right, dropped so the bottom line of the icon sits on the
     wordmark's baseline (bottom-aligned with the wordmark, measured). */
  @media (max-width: 759.98px) { [data-site] header#masthead > span, [data-site] header#masthead.mast-condensed > span {
    position: absolute !important; right: 20px;
    top: 50%; transform: translateY(calc(-50% + 4px));
  } }

  /* ---- DESKTOP / TABLET masthead: single-line centred lockup (matches the phone
     header). The tall stacked hero is removed at every non-phone width; the header
     is one fixed centred bar — globe left, wordmark centred, menu right — with no
     scroll morph (the .mast-condensed selectors carry identical values). */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead [data-lockup="stacked"] { display: none !important; } }
@media (min-width: 1024px) { [data-site] header#masthead [data-lockup="stacked"] { display: none !important; } }

  /* container: neutral block spanning the header so the globe and wordmark position
     absolutely against the sticky header (no transform, or it becomes their
     containing block and re-traps them). */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead [data-lockup="single"] { display: block !important; position: static !important; transform: none !important; } }
@media (min-width: 1024px) { [data-site] header#masthead [data-lockup="single"] { display: block !important; position: static !important; transform: none !important; } }

  /* stable, non-morphing bar height in both scroll states */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead, [data-site] header#masthead.mast-condensed {
    /* The globe (60px) and wordmark are position:absolute, so they don't give the
       header any height — without a floor the bar collapses to the little hamburger
       (~31px) and the 60px globe + wordmark overflow, the divider cutting through
       them (worst with the nav hidden while the menu is open). Floor it at 76px so it
       always contains the globe with breathing room. */
    box-sizing: border-box !important;
    padding-top: 8px !important; padding-bottom: 8px !important; min-height: 80px !important;
    /* adopt the phone header's edge treatment: full-bleed (break out of the body's
       8px margin so the divider runs edge to edge) with the globe hugging the left
       and the menu the right, instead of inset to the 1100px content column. */
    /* Globe + menu align to the CONTENT gutter. The header is full-bleed
       (margin:-8px breaks out of the body's 8px margin so the divider reaches the
       edge), so its padding must be the content gutter + 8px to land the globe and
       menu at the same x as the sections below. Keep this = (section gutter + 8). */
    padding-left: 58px !important; padding-right: 58px !important;
    margin-left: -8px !important; margin-right: -8px !important;
  } }
@media (min-width: 1024px) { [data-site] header#masthead, [data-site] header#masthead.mast-condensed {
    /* The globe (60px) and wordmark are position:absolute, so they don't give the
       header any height — without a floor the bar collapses to the little hamburger
       (~31px) and the 60px globe + wordmark overflow, the divider cutting through
       them (worst with the nav hidden while the menu is open). Floor it at 76px so it
       always contains the globe with breathing room. */
    box-sizing: border-box !important;
    padding-top: 8px !important; padding-bottom: 8px !important; min-height: 80px !important;
    /* adopt the phone header's edge treatment: full-bleed (break out of the body's
       8px margin so the divider runs edge to edge) with the globe hugging the left
       and the menu the right, instead of inset to the 1100px content column. */
    /* Globe + menu align to the CONTENT gutter. The header is full-bleed
       (margin:-8px breaks out of the body's 8px margin so the divider reaches the
       edge), so its padding must be the content gutter + 8px to land the globe and
       menu at the same x as the sections below. Keep this = (section gutter + 8). */
    padding-left: 58px !important; padding-right: 58px !important;
    margin-left: -8px !important; margin-right: -8px !important;
  } }

  /* globe: re-shown, tucked into the left corner at the content gutter, vertically
     centred (overrides the wordmark-only display:none). */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead #globe-single {
    display: inline-flex !important;
    position: absolute !important; left: 58px !important; top: 50%;
    transform: translateY(-50%); margin: 0 !important;
    width: 70px !important; height: 70px !important;
  } }
@media (min-width: 1024px) { [data-site] header#masthead #globe-single {
    display: inline-flex !important;
    position: absolute !important; left: 58px !important; top: 50%;
    transform: translateY(-50%); margin: 0 !important;
    width: 70px !important; height: 70px !important;
  } }

  /* iPad portrait (tablet) uses a 24px content gutter, not 50px, so the globe must
     sit at 24 + 8 (full-bleed compensation) = 32px to mirror the content — the
     shared 58px above is for the 50px-gutter desktop/tablet-ls widths. */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead #globe-single { left: 32px !important; } }

  /* wordmark: centred on the header. Shrink-wrapped (left:50% + translate) so its
     box is only as wide as the text — a full-width box (left:0;right:0) would sit on
     top of the top-nav and swallow its clicks. */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead [data-lockup="single"] > span:last-child {
    position: absolute !important; left: 50% !important; right: auto !important;
    /* Optical raise: cap centres already align with the nav, but the wordmark's
       lowercase mass sits low, so lift it ~2px to centre its VISUAL mass on the
       shared midline (else the nav reads as sitting high on the wordmark). */
    top: 50%; transform: translate(-50%, calc(-50% - 2px));
    padding: 0 !important;
    font-size: 45px !important; line-height: 1 !important; white-space: nowrap;
    text-align: center !important;
  } }
@media (min-width: 1024px) { [data-site] header#masthead [data-lockup="single"] > span:last-child {
    position: absolute !important; left: 50% !important; right: auto !important;
    /* Optical raise: cap centres already align with the nav, but the wordmark's
       lowercase mass sits low, so lift it ~2px to centre its VISUAL mass on the
       shared midline (else the nav reads as sitting high on the wordmark). */
    top: 50%; transform: translate(-50%, calc(-50% - 2px));
    padding: 0 !important;
    font-size: 45px !important; line-height: 1 !important; white-space: nowrap;
    text-align: center !important;
  } }

  /* Keep the right-side cluster (nav, search bar, hamburger) above the absolutely-
     positioned centred wordmark so it always receives clicks — the wordmark's box,
     even shrink-wrapped, can still reach under the nav at narrower widths. */
  header#masthead .mast-right { position: relative; z-index: 3; }

  header#masthead [data-lockup="single"] > span:last-child { z-index: 1; }

  /* menu button: bigger icon, still shorter than the globe so the bar height is
     unaffected (scale keeps it out of layout flow) */
  /* Enlarge the hamburger by real dimensions, NOT transform:scale — scaling also
     multiplies the 2px line thickness and pushes the bars onto fractional pixels, so
     they anti-alias unevenly (the bottom line looked thicker). Sizing the box keeps
     the lines a crisp, even 2px and gives the hamburger enough width to bookend the
     globe on the right. */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead .hamburger {
    width: 40px !important; height: 23px !important;
  } }
@media (min-width: 1024px) { [data-site] header#masthead .hamburger {
    width: 40px !important; height: 23px !important;
  } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead .hamburger i {
    height: 2px !important;
  } }
@media (min-width: 1024px) { [data-site] header#masthead .hamburger i {
    height: 2px !important;
  } }

  /* Middle line: the default centres it (top:50% + translateY), which lands a
     fractional-thickness line on a half-pixel so it renders soft and looks bigger
     than the crisp edge-pinned top/bottom lines. Pin it to a whole pixel (top:11px,
     no translateY) so it sits on the grid and renders identically crisp. */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead .hamburger i:nth-child(2), [data-site] header#masthead .hamburger i:nth-child(3) {
    top: 11px !important; transform: translateX(-50%) rotate(0deg) !important;
  } }
@media (min-width: 1024px) { [data-site] header#masthead .hamburger i:nth-child(2), [data-site] header#masthead .hamburger i:nth-child(3) {
    top: 11px !important; transform: translateX(-50%) rotate(0deg) !important;
  } }

  /* keep the X morph working with the new (translateY-free) centring */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead [data-menu-toggle][data-open] .hamburger i:nth-child(2) {
    transform: translateX(-50%) rotate(45deg) !important;
  } }
@media (min-width: 1024px) { [data-site] header#masthead [data-menu-toggle][data-open] .hamburger i:nth-child(2) {
    transform: translateX(-50%) rotate(45deg) !important;
  } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead [data-menu-toggle][data-open] .hamburger i:nth-child(3) {
    transform: translateX(-50%) rotate(-45deg) !important;
  } }
@media (min-width: 1024px) { [data-site] header#masthead [data-menu-toggle][data-open] .hamburger i:nth-child(3) {
    transform: translateX(-50%) rotate(-45deg) !important;
  } }

  /* ===== Desktop top-nav + unfolding header search =====
     Nav (Search/About/Archive/Newsletter) shows only on non-phone; the hamburger
     stays. Clicking Search adds .header-search-open to the header: the nav collapses
     (max-width -> 0) and the search bar unfolds (max-width 0 -> open) in its place.
     Both hidden on phone (mobile keeps the hamburger only).

     visibility is what actually hides them, not max-width/opacity. Those two
     collapse the box and fade the pixels but leave the element focusable, so
     the collapsed search bar kept its input, its submit and its close button in
     the tab order — three invisible stops in the middle of the masthead — and
     the nav links did the same while the search bar was open over them.
     pointer-events:none had already handled the mouse; nothing had handled the
     keyboard. visibility:hidden removes them from the tab order and still
     animates, so the unfold looks exactly as it did: the transition delays the
     flip to the end of the collapse (0s linear .38s) and runs it immediately on
     open (0s linear 0s). */
  [data-top-nav], [data-header-searchbar] { display: none; }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead [data-top-nav] {
    display: flex; max-width: 600px; opacity: 1; overflow: hidden; visibility: visible;
    transition: max-width .38s cubic-bezier(.16,1,.3,1), opacity .2s ease, visibility 0s linear 0s;
  } }
@media (min-width: 1024px) { [data-site] header#masthead [data-top-nav] {
    display: flex; max-width: 600px; opacity: 1; overflow: hidden; visibility: visible;
    transition: max-width .38s cubic-bezier(.16,1,.3,1), opacity .2s ease, visibility 0s linear 0s;
  } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead [data-header-searchbar] {
    display: flex; max-width: 0; opacity: 0; overflow: hidden; pointer-events: none; visibility: hidden;
    transition: max-width .38s cubic-bezier(.16,1,.3,1), opacity .25s ease, visibility 0s linear .38s;
  } }
@media (min-width: 1024px) { [data-site] header#masthead [data-header-searchbar] {
    display: flex; max-width: 0; opacity: 0; overflow: hidden; pointer-events: none; visibility: hidden;
    transition: max-width .38s cubic-bezier(.16,1,.3,1), opacity .25s ease, visibility 0s linear .38s;
  } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead.header-search-open [data-top-nav] {
    max-width: 0; opacity: 0; pointer-events: none; visibility: hidden;
    transition: max-width .38s cubic-bezier(.16,1,.3,1), opacity .2s ease, visibility 0s linear .38s;
  } }
@media (min-width: 1024px) { [data-site] header#masthead.header-search-open [data-top-nav] {
    max-width: 0; opacity: 0; pointer-events: none; visibility: hidden;
    transition: max-width .38s cubic-bezier(.16,1,.3,1), opacity .2s ease, visibility 0s linear .38s;
  } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead.header-search-open [data-header-searchbar] {
    max-width: 400px; opacity: 1; pointer-events: auto; visibility: visible;
    transition: max-width .38s cubic-bezier(.16,1,.3,1), opacity .25s ease, visibility 0s linear 0s;
  } }
@media (min-width: 1024px) { [data-site] header#masthead.header-search-open [data-header-searchbar] {
    max-width: 400px; opacity: 1; pointer-events: auto; visibility: visible;
    transition: max-width .38s cubic-bezier(.16,1,.3,1), opacity .25s ease, visibility 0s linear 0s;
  } }

  @media (hover: hover) {
    /* Hover -> accent. The transition lives on :hover only (not the base), so the
       colour eases IN on hover but snaps back OUT instantly when the pointer leaves
       — no lingering fade. (The inline transition was removed from the markup for
       the same reason.) */
    header#masthead [data-header-search-close]:hover { color: var(--accent); transition: color 0.15s; }
@media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead .topnav-link:not(.topnav-off):hover { color: var(--accent); transition: color 0.15s; } }
@media (min-width: 1024px) { [data-site] header#masthead .topnav-link:not(.topnav-off):hover { color: var(--accent); transition: color 0.15s; } }

  }
  /* When the hamburger menu is open, hide the top-nav + header search bar so the menu
     isn't duplicated in the header behind it — only the globe, wordmark and the X show. */
  header#masthead.menu-open [data-top-nav], header#masthead.menu-open [data-header-searchbar] { display: none !important; }

  /* Below 1280px the header can't fit the top-nav + an unfolding search bar next to
     the centred wordmark — iPad portrait (~768) and narrow / 1024 desktop windows
     run out of room, and the search bar in particular has nowhere to go. So fall back
     to the mobile chrome there: hamburger only, with search living inside the menu.
     (>=1280 keeps the full top-nav; phone is already hamburger-only via its vp rules.) */
  @media (max-width: 1279px) {
    @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead [data-top-nav], [data-site] header#masthead [data-header-searchbar] { display: none !important; } }
@media (min-width: 1024px) { [data-site] header#masthead [data-top-nav], [data-site] header#masthead [data-header-searchbar] { display: none !important; } }

    /* re-show the in-menu search that the desktop/tablet rule otherwise hides
       (form[...] adds an element to out-specify that hide rule regardless of order),
       and let it span the full menu width (drop the 540px cap) so it reaches under
       the X, the way it does on mobile — instead of stopping in the corner. */

  }

  /* ---- Full-width body: adopt the phone gutters (8px) for the rest of the page,
     not just the header. Drop the 1100px content column so sections and the footer
     run edge to edge like the masthead. Only the horizontal padding + max-width
     change; each section keeps its own vertical padding. Text blocks are already
     capped at their own max-width, so measures stay readable. */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] section {
    max-width: none !important;
    padding-left: 50px !important; padding-right: 50px !important;
  } }
@media (min-width: 1024px) { [data-site] section {
    max-width: none !important;
    padding-left: 50px !important; padding-right: 50px !important;
  } }

  /* About "letter" column: on desktop, left-align it so its text edge sits where
     a normal article's body text starts. The article body begins at
     margin-left clamp(90px, 8vw, 130px) + ~20px inner padding; the About section
     already carries a 50px horizontal pad, so subtract that here. Mobile/tablet
     keep the centred inline margin. */
@media (min-width: 1024px) { [data-site] .about-col {
    max-width: none !important;
    margin-left: clamp(52px, calc(8vw - 38px), 92px) !important;
    margin-right: 297px !important;
  } }

  /* Cap the whole body (masthead + content, all inside #site-root) at 1600px and
     centre it. Below 1600 the app runs full-width with the 8px gutters above;
     past 1600 it becomes a centred column. The fixed menu overlay is position:fixed
     so it escapes this cap and still covers the viewport. */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] #site-root {
    max-width: 1600px !important;
    margin-inline: auto !important;
  } }
@media (min-width: 1024px) { [data-site] #site-root {
    max-width: 1600px !important;
    margin-inline: auto !important;
  } }

  @media (max-width: 759.98px) { [data-site] main { grid-template-columns: 1fr !important; padding: 6px 8px !important; gap: 14px !important; } }

  @media (max-width: 759.98px) { [data-site] section { padding: 20px 8px 48px !important; } }

  /* Archive: the head and the list are one continuous unit, so collapse the
     stacked section paddings between them (the intro's bottom + the list's top)
     to a single tight gap on every viewport, instead of two full section gutters. */
  [data-site] .arch-intro { padding-bottom: 0 !important; }
  [data-site] .arch-list { padding-top: 8px !important; }
  @media (max-width: 759.98px) {
    [data-site] .arch-intro { padding-bottom: 0 !important; padding-left: 0 !important; padding-right: 0 !important; }
    [data-site] .arch-list { padding-top: 0 !important; padding-left: 0 !important; padding-right: 0 !important; }
    /* on phones the section stack already carries main's 14px grid gap, so drop
       the head's own bottom padding and the list's top padding — the list starts
       right under the intro instead of a third gutter piling on. */
    [data-site] .arch-headwrap { padding-bottom: 0 !important; }
  }

  /* Search: the field and the results are one unit, exactly like the archive
     above. The generic phone rule gives EVERY section 20px top and 48px bottom,
     which is right for a section that stands alone and wrong for two that are
     meant to read as one — it put 109px of nothing between the search field and
     the first result on a 844px screen, so the answer to what you just typed
     started an eighth of a viewport away from the question.
     Same collapse, same reasoning, same values. */
  [data-site] .search-intro { padding-bottom: 0 !important; }
  [data-site] .search-list { padding-top: 8px !important; }
  @media (max-width: 759.98px) {
    [data-site] .search-intro { padding-bottom: 0 !important; }
    [data-site] .search-list { padding-top: 0 !important; }
  }

  /* featured (structural: only featured uses article) -> stacked */
  /* Featured card fills the first screen on phones: fix the card to the viewport
     height (below the sticky masthead + top padding, less a small bottom sliver)
     and let the image row absorb whatever the text row doesn't use. The image
     grows big and the next article sits just below the fold instead of peeking. */
  @media (max-width: 759.98px) { [data-site] article.article-card { grid-template-columns: 1fr !important; grid-template-rows: 1fr auto !important; height: calc(100dvh - 113px) !important; margin-bottom: 24px !important; } }

  /* Featured image height scales with the viewport so the card always clears the
     fold: full 180px on tall phones, shrinking on short ones (dvh tracks the URL
     bar). Crossover ~750px of viewport height. */
  @media (max-width: 759.98px) { [data-site] article.article-card > div:first-child { min-height: 0 !important; height: auto !important; align-self: stretch !important; border-right: none !important; border-bottom: 1px solid var(--fg) !important; } }

  @media (max-width: 759.98px) { [data-site] article.article-card > div:last-child { padding: 18px 0 0 !important; } }

  @media (max-width: 759.98px) { [data-site] article.article-card > div:last-child > div:not([style*="border-top"]), [data-site] article.article-card > div:last-child > h2, [data-site] article.article-card > div:last-child > p { padding-left: 12px !important; padding-right: 12px !important; } }

  @media (max-width: 759.98px) { [data-site] article.article-card > div:last-child > div:last-child { padding-bottom: 20px !important; padding-top: 12px !important; } }

  @media (max-width: 759.98px) { [data-site] article.article-card h2 { font-size: 2rem !important; } }

  @media (max-width: 759.98px) { [data-site] article.article-card p { font-size: 1.06rem !important; } }

  /* The featured card's eyebrow used to read "Featured" — a word the layout
     already says — so phones dropped it to keep the headline and meta high
     enough that the date is visible without scrolling. It now carries the
     article's CATEGORY, which is real information and the one thing this card
     would otherwise lack that every card below it has. So it stays.

     The vertical budget that justified hiding it is genuinely tight: measured
     at 375x667, the meta row ended at 656px, eleven pixels of headroom. The
     label cannot be free. It is paid for out of the two margins directly under
     it, which are set for a desktop column and are loose on a phone: the
     eyebrow's own 24px drops to 8, and the dek's 32px to 18. */
  @media (max-width: 759.98px) {
    [data-site] [data-feat-label] { margin-bottom: 8px !important; }
    [data-site] article.article-card h2 { margin-bottom: 14px !important; }
    [data-site] article.article-card p { margin-bottom: 18px !important; }
  }

  /* Keep the featured card's outer height fixed, but give its image the same
     roughly 3:2 height as a normal mobile row. The tighter internal gaps pay
     for that extra image height without pushing the card itself taller. */
  @media (max-width: 759.98px) {
    [data-site] article.article-card { grid-template-rows: 246px 1fr !important; height: calc(100dvh - 101px) !important; margin-top: -10px !important; }
    [data-site] [data-feat-label] { display: none !important; }
    [data-site] article.article-card > div:last-child > div:last-child { padding: 4px 12px !important; }
    [data-site] [data-feat-label] { margin-bottom: 4px !important; }
    [data-site] article.article-card h2 { margin-bottom: 8px !important; }
    [data-site] article.article-card p { margin-bottom: 6px !important; }
  }

  /* current-grid two-up cards: ease body padding + let meta wrap so it doesn't clip the corners */
  @media (max-width: 759.98px) { [data-site] main > div > div:last-child { padding-left: 0 !important; padding-right: 0 !important; } }

  @media (max-width: 759.98px) { [data-site] main > div > div:last-child > div { padding-left: 16px !important; padding-right: 16px !important; } }

  @media (max-width: 759.98px) { [data-site] main > div > div:last-child > div:last-child { white-space: normal !important; } }

  /* A + E rows -> stacked */
  @media (max-width: 759.98px) { [data-site] [data-r="a"], [data-site] [data-r="e"] { grid-template-columns: 1fr !important; gap: 14px !important; padding: 22px 2px !important; } }

  @media (max-width: 759.98px) { [data-site] [data-r="e"] h3 { font-size: 1.85rem !important; } }

  /* Home list adopts the archive treatment on phones: trim the section to ~18px
     a side (matching the archive), and turn each row's date into the same compact
     outlined [square-node . date] chip. Category eyebrow, node+date and read-time
     removal come from the templates and hold on every viewport. */
  @media (max-width: 759.98px) { [data-site] .home-sec { padding-left: 0 !important; padding-right: 0 !important; } }
  @media (max-width: 759.98px) { [data-site] [data-r="e"] .row-meta { display: inline-flex !important; align-items: center !important; font-size: 11px !important; letter-spacing: 0 !important; color: var(--fg) !important; border: 1px solid var(--fg) !important; padding: 2px 7px !important; } }
  /* Coming-soon rows already contain their own outlined chip. Keep the mobile
     date treatment on published rows, but don't wrap the soon chip in a second
     border and padding box. */
  @media (max-width: 759.98px) { [data-site] [data-r="e"][data-soon] .row-meta { border: 0 !important; padding: 0 !important; } }
  @media (max-width: 759.98px) { [data-site] [data-r="e"] .row-meta > span[aria-hidden] { margin-right: 7px !important; top: 0 !important; } }

  /* B compact rows -> MOBILE: the category rides on top as an accent eyebrow;
     below it the title + dek sit in the left column with the (larger, 104px)
     square art top-aligned beside them; then a compact outlined [node · date]
     chip. Three stacked left-anchored bands. The dek takes the article page's
     own deck colour (fg @ 82%) so the list and the article read as one system. */
  @media (max-width: 759.98px) { [data-site] [data-r="b"] { grid-template-columns: 1fr 104px !important; column-gap: 16px !important; row-gap: 10px !important; align-items: start !important; padding: 20px 2px !important; } }

  /* image: 104px square, top-right (row 2), top-aligned with the title */
  @media (max-width: 759.98px) { [data-site] [data-r="b"] > div:first-child { width: 104px !important; height: 104px !important; grid-column: 2 !important; grid-row: 2 !important; align-self: start !important; } }

  /* title + dek stay wrapped together in the left column (row 2) */
  @media (max-width: 759.98px) { [data-site] [data-r="b"] > div:nth-child(2) { grid-column: 1 !important; grid-row: 2 !important; min-width: 0 !important; } }

  /* title: flush left, wraps freely (no single-line ellipsis) */
  @media (max-width: 759.98px) { [data-site] [data-r="b"] [data-title] { text-align: left !important; white-space: normal !important; display: block !important; -webkit-line-clamp: none !important; overflow: visible !important; text-overflow: clip !important; max-height: none !important; height: auto !important; margin: 0 0 8px !important; } }

  /* dek: article-deck colour (fg @ 82%), wraps freely */
  @media (max-width: 759.98px) { [data-site] [data-r="b"] p { text-align: left !important; white-space: normal !important; display: block !important; -webkit-line-clamp: none !important; overflow: visible !important; max-height: none !important; height: auto !important; margin: 0 !important; color: var(--fg) !important; opacity: 0.82 !important; } }

  /* dissolve the meta wrapper so category + date place independently in the grid */
  @media (max-width: 759.98px) { [data-site] [data-r="b"] > div:nth-child(3) { display: contents !important; } }

  /* category -> accent eyebrow, full-width on top (row 1) */
  @media (max-width: 759.98px) { [data-site] [data-r="b"] > div:nth-child(3) > div:nth-child(1) { grid-column: 1 / -1 !important; grid-row: 1 !important; text-align: left !important; margin: 0 !important; font-family: 'Fragment Mono', monospace !important; font-size: 11.5px !important; letter-spacing: 0.06em !important; color: var(--accent) !important; } }

  /* date -> compact outlined chip that hugs its content (row 3); keeps the square node */
  @media (max-width: 759.98px) { [data-site] [data-r="b"] > div:nth-child(3) > div:nth-child(2) { grid-column: 1 / -1 !important; grid-row: 3 !important; justify-self: start !important; align-self: start !important; width: auto !important; margin: 0 !important; display: inline-flex !important; align-items: center !important; font-family: 'Fragment Mono', monospace !important; font-size: 11px !important; letter-spacing: 0 !important; color: var(--fg) !important; border: 1px solid var(--fg) !important; padding: 2px 7px !important; } }
  @media (max-width: 759.98px) { [data-site] [data-r="b"] > div:nth-child(3) > div:nth-child(2) > span[aria-hidden] { margin-right: 7px !important; top: 0 !important; } }

  /* B compact rows -> iPad: keep two-column desktop structure, top-align so title stays level with the image, wrap title (2-line slot) + 3-line subtitle slot */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-r="b"] { align-items: start !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-r="b"] [data-title] { white-space: normal !important; display: -webkit-box !important; -webkit-box-orient: vertical !important; -webkit-line-clamp: 2 !important; overflow: hidden !important; text-overflow: clip !important; max-height: calc(1.1em * 2) !important; height: auto !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-r="b"] p { display: -webkit-box !important; -webkit-box-orient: vertical !important; -webkit-line-clamp: 3 !important; overflow: hidden !important; height: calc(1.35em * 3) !important; white-space: normal !important; } }

  /* C index list -> number + title, drop trailing meta, untruncate */
  @media (max-width: 759.98px) { [data-site] [data-r="c"] { grid-template-columns: 26px 1fr !important; gap: 12px !important; align-items: start !important; } }

  @media (max-width: 759.98px) { [data-site] [data-r="c"] > span:last-child { display: none !important; } }

  @media (max-width: 759.98px) { [data-site] [data-r="c"] h3 { white-space: normal !important; overflow: visible !important; text-overflow: clip !important; } }

  /* search results page rows */
  @media (max-width: 759.98px) { [data-site] [data-r="srow"] { grid-template-columns: 64px 1fr !important; gap: 4px 14px !important; align-items: start !important; padding: 20px 2px !important; } }

  @media (max-width: 759.98px) { [data-site] [data-r="srow"] > div:first-child { width: 64px !important; height: 64px !important; grid-row: 1 / span 3 !important; } }

  @media (max-width: 759.98px) { [data-site] [data-r="srow"] > span:last-child { grid-column: 2 !important; margin-top: 8px !important; padding-top: 0 !important; } }

  @media (max-width: 759.98px) { [data-site] [data-r="srow"] h3 { font-size: 1.45rem !important; } }

  @media (max-width: 759.98px) { [data-site] [data-r="srow"] p { -webkit-line-clamp: 3 !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-r="srow"] { gap: 22px !important; } }

  /* D two-up cards -> single column */
  @media (max-width: 759.98px) { [data-site] [data-rw="d"] { grid-template-columns: 1fr !important; } }

  /* footer / subscribe */
  @keyframes footerRingSpin { to { transform: rotate(360deg); } }
  /* MCF stamp invert. Split by input type so touch doesn't leave it stuck
     inverted: :hover only for real pointers (clears normally), :active for
     touch (drops on release). The sigil snaps (no transition). */

  /* New footer bar: globe left, credits right at every width; only the globe
     size (128 static -> 84 spinning) and padding change on phones. */
  /* Taller bar so the globe + credits drop to the bottom (back-to-top stays up
     top via space-between); globe bottom-aligns with the credits. */

  /* drop the back-to-top down so it sits just below the globe's top; translateY
     (not margin) so the globe + credits don't reflow — they stay put. */

  /* bottom-align the credits with the globe (match the globe's 12px margin-bottom;
     back-to-top stays put at the top of the column) */

  /* menu overlay: clamp big nav type to frame width, single-column topics */

  /* Desktop/tablet: the top-nav "Search" already unfolds a search bar, so the
     search field inside the hamburger menu is redundant — hide it. Phone keeps it
     (no top-nav, so the menu is the only place to search). */

  /* ---- TABLET breakpoint trims ---- */
  /* content gutter is 24px; the masthead is full-bleed (margin:-8) so its padding is
     24 + 8 = 32 to land the globe/menu at the same x as the content below.
     .mast-condensed must be named here even though the value is the same for both
     states. The 58px rule above carries it in its selector list, which makes it a
     class more specific than this one — so patching only the bare selector left the
     scrolled state on the desktop 58px. The header transitions `padding`, so on
     tablet the globe and hamburger slid 26px inward on every scroll down and back
     out on every scroll up. */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] header#masthead, [data-site] header#masthead.mast-condensed { padding-left: 32px !important; padding-right: 32px !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] main { padding: 24px !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] section { padding-left: 24px !important; padding-right: 24px !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-r="e"] { grid-template-columns: 300px 1fr !important; gap: 32px !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-footer-cta] { gap: 28px !important; padding-left: 24px !important; padding-right: 24px !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-footer-meta] { padding-left: 24px !important; padding-right: 24px !important; } }

  /* The tablet-band menu nav size used to be pinned here, at 3.4rem. This
     stylesheet is loaded on the index family only, so the SAME shared menu
     came out fixed on the homepage and fluid on articles — 54.4px against
     50px at 834, and 54.4 against 60 at 1000, where the article's was
     visibly the larger. The menu is shared chrome (tools/build/chrome.mjs);
     styling it from a page stylesheet is what let the two drift.
     Deleted rather than moved to chrome.css: the fluid size the article
     already used runs smoothly through this band and matches what both
     surfaces do at 1024 and up, so pinning it here only created a flat spot
     nothing else had. */

  /* tablet featured -> stacked, full-width landscape image */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] article.article-card { grid-template-columns: 1fr !important; } }

  /* TABLET ROWS: let the picture reach the full height of the text beside it.
     The cell is aspect-ratio:3/2 on a fixed 380px column, so at this width the
     picture came out shorter than its own text column and the eyebrow sat above
     the frame while the date sat below it — the row read as three things, not
     two. Stretching the grid and dropping the ratio makes the frame span exactly
     the block it belongs to. The <img> inside is already inset:0 + object-fit,
     so it fills whatever height it is given. */
  @media (min-width: 760px) and (max-width: 1023.98px) {
    [data-site] .article-card[data-r="e"] { align-items: stretch !important; }
    [data-site] .article-card[data-r="e"] > div:first-child { aspect-ratio: auto !important; }
  }


  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] article.article-card > div:first-child { min-height: 0 !important; aspect-ratio: 16/9 !important; border-right: none !important; border-bottom: 1px solid var(--fg) !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] article.article-card > div:last-child { padding: 40px 0 0 !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] article.article-card > div:last-child > div:not([style*="border-top"]), [data-site] article.article-card > div:last-child > h2, [data-site] article.article-card > div:last-child > p { padding-left: 44px !important; padding-right: 44px !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] article.article-card > div:last-child > div:last-child { padding-bottom: 40px !important; } }

  /* tablet: keep orbit ring beside subscribe, just smaller */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-footer-ring] { flex: 0 0 auto !important; min-width: 0 !important; align-self: flex-start !important; margin-top: 4px !important; } }

  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-footer-ring] #subscribe-ring { width: 178px !important; height: 178px !important; } }

  /* ---- current-grid card clamps per viewport (current grid = main > div; featured = article, excluded) ----
     narrower tablet/phone cards wrap more lines before the clamp, so raise the clamp AND the
     band's slot min-height to match (sized for the worst-case 2.5rem title so bands never overflow
     and the divider/meta lines stay aligned across a row). Desktop keeps its inline 2/3 clamps. */
  @media (max-width: 759.98px) { [data-site]  main > div > div:last-child h2 { -webkit-line-clamp: 3 !important; } }
@media (min-width: 760px) and (max-width: 1023.98px) { [data-site] main > div > div:last-child h2 { -webkit-line-clamp: 3 !important; } }

  @media (max-width: 759.98px) { [data-site]  main > div > div:last-child > div:first-child { min-height: 138px !important; } }
@media (min-width: 760px) and (max-width: 1023.98px) { [data-site] main > div > div:last-child > div:first-child { min-height: 138px !important; } }

  @media (max-width: 759.98px) { [data-site]  main > div > div:last-child p { -webkit-line-clamp: 4 !important; } }
@media (min-width: 760px) and (max-width: 1023.98px) { [data-site] main > div > div:last-child p { -webkit-line-clamp: 4 !important; } }

  @media (max-width: 759.98px) { [data-site]  main > div > div:last-child > div:nth-child(3) { min-height: 138px !important; padding-top: 16px !important; padding-bottom: 16px !important; } }
@media (min-width: 760px) and (max-width: 1023.98px) { [data-site] main > div > div:last-child > div:nth-child(3) { min-height: 138px !important; padding-top: 16px !important; padding-bottom: 16px !important; } }

  /* tablet meta: trim card body padding + nudge font down so the meta line always fits on one line */
  @media (min-width: 760px) and (max-width: 1023.98px) { [data-site] main > div > div:last-child > div:last-child { padding-left: 22px !important; padding-right: 22px !important; font-size: 16px !important; white-space: normal !important; } }

  /* ---- topic page header (intro stacked under the "Topics" title) ----
     Not the bare one. This padding is the air ABOVE the head's rule, so it
     belongs to heads that draw a rule; the topics overview no longer does, and
     without the exclusion its 22px stacked with the grid's own margin exactly
     as the desktop 34px did. :not() rather than a later override — an override
     would tie at 0,2,0 and be decided by source order, which is the way this
     stylesheet has lost declarations before. */
  @media (max-width: 759.98px) { [data-site] [data-tophead]:not([data-tophead="bare"]) { padding-bottom: 22px !important; } }
@media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-tophead]:not([data-tophead="bare"]) { padding-bottom: 22px !important; } }

  @media (max-width: 759.98px) { [data-site] [data-tophead] p { max-width: none !important; } }
@media (min-width: 760px) and (max-width: 1023.98px) { [data-site] [data-tophead] p { max-width: none !important; } }

  @media (max-width: 759.98px) { [data-site] [data-tophead] h1 { font-size: 3rem !important; } }

  @media (max-width: 759.98px) { [data-site] [data-tophead] p { font-size: 1.18rem !important; } }

  /* dark mode: keep the page root pure black behind #site-root (overscroll, scrollbars) */
  html[data-theme="alt"], html[data-theme="alt"] body { background: #000000; }

/* Shrink the Built-by chip on phones so the "Built by" label never wraps. */
@media (max-width: 759.98px) { [data-site] a[href*="marscodefactory"] { font-size: 8px !important; letter-spacing: 0.05em !important; padding: 4px 7px !important; gap: 5px !important; white-space: nowrap !important; } }

@media (max-width: 759.98px) { [data-site] a[href*="marscodefactory"] > span { width: 6px !important; height: 6px !important; } }

/* ===== Accessibility: prefers-reduced-motion =====
   Kill all CSS animations and decorative transitions when the user asks for
   reduced motion. Every transition on this site is cosmetic (hover fades, menu
   fade/slide, image zoom, theme cross-fade), so a blanket rule is safe: each
   element simply snaps to its final state and nothing becomes unreachable.
   !important also overrides inline styles — including the JS-set
   footerRingSpin on the footer globe ring — and the @media re-evaluates live,
   so toggling the OS setting mid-session starts/stops these without a reload.
   (The subscribe subscribe-ring uses SVG SMIL animateTransform, which CSS cannot
   stop; that one is guarded in app-index.js instead.) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }

  html { scroll-behavior: auto !important; }

}

/* ===== Static-site chrome animation (baked art, CSS-driven) ===== */
/* Footer globe: the strip group translates exactly one strip-width per 30s
   revolution (473.14 SVG user units == the copy offset baked into the SVG by
   tools/build/globe.mjs — the same constant, so the loop is seamless). */
/* One perpetual motion per footer. The subscribe CTA's counter-rotating ring
   is that motion where it exists — but it exists on the homepage alone, and
   this rule used to read "index-family pages are static", which left about,
   subscribe, contact, search, topics and archive with a footer that did not
   move at all. So the globe rolls by default, at the article footer's calm
   30s pace, and stands still only in the one footer that has the ring. */
.wos-globe-roll { animation: wosGlobeRoll 30s linear infinite; }
footer[data-has-ring] .wos-globe-roll { animation: none; }
@keyframes wosGlobeRoll { to { transform: translateX(-473.14px); } }

/* Easter egg: a globe rolls while hovered — masthead marks (wos-globe-hroll,
   never auto-animated) and the static index footer globes. JS adds .egg-roll
   on mouseenter; on mouseleave it lets the revolution in progress finish and
   removes the class on the animationiteration boundary, which is exactly the
   seam/rest frame — so the stop is always seamless, never a snap. Taps get
   one full revolution the same way. Linear, because the loop is continuous
   while hovered (easing would pulse every lap). Gated by
   prefers-reduced-motion via the blanket animation kill above + JS guard.

   The footer half of the egg is scoped to the ring footer, because that is now
   the only footer whose globe is at rest. On a globe that is already rolling,
   swapping to the 5s animation on hover restarts it from the seam — a visible
   snap, the exact thing the animationiteration handshake exists to avoid. */
.egg-roll .wos-globe-hroll { animation: wosGlobeRoll 5s linear infinite; }
footer[data-has-ring] .egg-roll .wos-globe-roll { animation: wosGlobeRoll 5s linear infinite; }

/* Phone: no hover to invite, so even the ring footer's globe carries motion
   itself. The hover/tap egg is ≥760px only (site.c4701745ee.js gates on the same
   breakpoint), so the two animations can never fight over the strip. Masthead
   marks stay still on phones. Reduced motion: covered by the blanket kill. */
@media (max-width: 759.98px) {
  footer[data-has-ring] .wos-globe-roll { animation: wosGlobeRoll 30s linear infinite; }
}

/* ===== Cross-document view transitions (no JS; unsupported browsers just
   navigate normally). Disabled under prefers-reduced-motion below. ===== */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.18s; }

/* Reduced motion: the blanket animation/transition kill in the block above
   covers the globe and ring groups; view-transition pseudo-elements live
   outside the DOM tree, so they get their own explicit kill. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-image-pair(*),
  ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* Subscribe ring: two counter-rotating orbit groups (was SMIL, now CSS). */
.wos-ring-a { animation: wosRingA 90s linear infinite; }
.wos-ring-b { animation: wosRingB 60s linear infinite; }
@keyframes wosRingA { to { transform: rotate(360deg); } }
@keyframes wosRingB { to { transform: rotate(-360deg); } }

/* Hover styling that used to be attached by JS (rowEnter/plateEnter and the
   dc style-hover attributes), now pure CSS. !important where the base style
   is inline on the element. */
@media (hover: hover) {
  .article-card:hover [data-title] { color: var(--accent); }
  .article-card:hover [data-title] a { color: var(--accent); }
  article.article-card:hover > div:first-child img { transform: scale(1.04); }
  [data-subscribe-row] button[type="submit"]:hover { background: var(--accent) !important; border-color: var(--accent) !important; color: #FFFFFF !important; }
  [data-backtotop]:hover { background: var(--fg) !important; color: var(--bg) !important; }
  [data-theme-toggle]:hover { color: var(--accent) !important; }
}
[data-subscribe-row] button[type="submit"]:active { background: var(--accent) !important; border-color: var(--accent) !important; color: #FFFFFF !important; }
[data-backtotop]:active { background: var(--fg) !important; color: var(--bg) !important; }

/* Theme alias: the shared head bootstrap and site.js set data-theme="dark" on
   <html>; keep the legacy "alt" selectors working and mirror them for "dark". */
html[data-theme="dark"] #site-root { --bg:#000000; --fg:#FFFFFF; --faded:rgba(255,255,255,0.56); --border:rgba(255,255,255,0.14); --tileborder:rgba(255,255,255,0.24); --accent:#E54E41; --accent-strong:#EA7469; --hover:rgba(255,255,255,0.06); --imgline:rgba(255,255,255,0.32); }
/* Paint the page canvas itself (html/body), not just #site-root, so the light
   background is a single uniform surface with no seam on overscroll/rubber-band
   or the mobile chrome. The dark selector below has higher specificity, so dark
   still wins. */
html, html body { background: #FFFFFF; }
html[data-theme="dark"], html[data-theme="dark"] body { background: #000000; }

/* ===== Document scrollbar (classic gutter, theme-aware) =====
   Styling the scrollbar opts Chrome/Edge out of the floating overlay thumb,
   which otherwise draws directly on top of the page (invisible gutter on the
   light paper) and changes width between idle and hover. A styled scrollbar
   gets a permanently reserved gutter at the window edge, constant width, and
   theme-correct colors. Square corners per the site's hairline-and-rectangle
   language; Firefox picks up the colors via scrollbar-color. */
html { --sb-track: #2A2A2A; --sb-line: rgba(0,0,0,0.35); --sb-thumb: rgba(255,255,255,0.35); --sb-thumb-hover: rgba(255,255,255,0.6); color-scheme: light; }
html[data-theme="dark"] { --sb-track: #101010; --sb-line: rgba(255,255,255,0.14); --sb-thumb: rgba(255,255,255,0.3); --sb-thumb-hover: rgba(255,255,255,0.55); color-scheme: dark; }
/* Firefox only: the standard property (in Chrome it would disable the
   ::-webkit-scrollbar styles below, putting the overlay thumb back) */
@supports not selector(::-webkit-scrollbar) {
  html { scrollbar-color: var(--sb-thumb) var(--sb-track); }
}
html::-webkit-scrollbar { width: 13px; }
html::-webkit-scrollbar-track { background: var(--sb-track); border-left: 1px solid var(--sb-line); }
html::-webkit-scrollbar-thumb { background: var(--sb-thumb); border: 3px solid var(--sb-track); }
html::-webkit-scrollbar-thumb:hover { background: var(--sb-thumb-hover); }

/* ===== topics: filter chip + compact menu, view crossfade, overview previews ===== */
[data-site] .topicbar { position: relative; display: inline-block; margin-bottom: 26px; }
[data-site] .topicchip {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 10px;
  font-family: 'Fragment Mono', monospace; font-size: 12px; letter-spacing: 0.04em;
  color: var(--fg); background: var(--bg);
  border: 1px solid var(--fg); padding: 7px 13px;
  transition: background 0.15s, color 0.15s;
}
[data-site] .topicchip::-webkit-details-marker { display: none; }
[data-site] .topicbar[open] .topicchip { background: var(--fg); color: var(--bg); }
@media (hover: hover) { [data-site] .topicchip:hover { background: var(--fg); color: var(--bg); } }
[data-site] .topicchip:active { background: var(--fg); color: var(--bg); }
[data-site] .topicchip-chev { transition: transform 0.2s ease; }
[data-site] .topicbar[open] .topicchip-chev { transform: rotate(180deg); }

[data-site] .topicmenu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 60;
  min-width: 212px; display: flex; flex-direction: column;
  background: var(--bg); border: 1px solid var(--fg);
}
[data-site] .topicmenu-item {
  font-family: 'Fragment Mono', monospace; font-size: 12.5px; letter-spacing: 0.02em;
  color: var(--fg); text-decoration: none; padding: 11px 15px;
  display: flex; align-items: center; gap: 10px; transition: background 0.13s, color 0.13s;
}
[data-site] .topicmenu-item + .topicmenu-item { border-top: 1px solid var(--border); }
[data-site] .topicmenu-item::before {
  content: ""; width: 6px; height: 6px; background: var(--accent);
  flex: none; opacity: 0; transition: opacity 0.13s;
}
@media (hover: hover) { [data-site] .topicmenu-item:hover { background: var(--border); } }
[data-site] .topicmenu-item:active { background: var(--border); }
[data-site] .topicmenu-item.is-active { color: var(--accent); }
[data-site] .topicmenu-item.is-active::before { opacity: 1; }

[data-site] .topics-view { transition: opacity 0.2s ease; }

/* ---- topic index: one framed table, four cells ----
   The share panel's language, which is the house's: a single outer rule, cells
   divided by hairlines that run edge to edge, and nothing inside a cell that
   frames it again.

   It was four separate plates, each with its own black border AND an inset grey
   frame 8px in, floating in a 24px gutter. Four boxes inside four boxes with air
   between them — three competing rectangles per topic, none of them structural.
   A table has one frame and shares its lines, so the geometry is the layout
   rather than decoration applied to it.

   The accent tick under each name is gone with it. It sat on its own line at
   34px and grew to span the word on hover, which is a lot of moving parts for a
   list of four links, and a growing rule is the one gesture that cannot be
   squared with lines that are meant to read as structure. */
[data-site] .topic-cards {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 0;
  border: 1px solid var(--fg);
  /* The whole gap between the intro and the table, not half of it — the head
     no longer carries padding of its own. Sized as one space rather than as
     two halves either side of a rule that is gone. */
  margin-top: clamp(26px, 2.8vw, 36px);
}
[data-site] .topic-card {
  position: relative;
  display: flex; flex-direction: column;
  padding: clamp(24px, 2.4vw, 30px);
  background: var(--bg); color: var(--fg);
  text-decoration: none; border: 0;
  transition: background 0.16s ease;
}
/* Shared internal rules: a cell draws the line above it and the line to its
   left, and the outer frame supplies the rest. Written by position rather than
   by count so a fifth topic lands correctly without touching this. */
[data-site] .topic-card:nth-child(n+3) { border-top: 1px solid var(--fg); }
[data-site] .topic-card:nth-child(even) { border-left: 1px solid var(--fg); }
/* An odd last card takes the whole row rather than leaving the cell beside it
   empty. The frame is a closed rectangle, so a missing cell reads as a hole in
   the table rather than as the end of it — which is exactly what appeared the
   first time the count went from four topics to three. By position again, so
   five topics work as well as three. */
[data-site] .topic-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
[data-site] .topic-card-name {
  font-family: 'Cormorant Garamond', Georgia, serif; font-weight: 600;
  font-size: clamp(2rem, 3.6vw, 2.7rem); line-height: 1.02; color: var(--fg);
  position: relative; z-index: 1; transition: color 0.18s ease;
  align-self: flex-start; margin-bottom: 16px;
}
/* --fg at 0.82, the archive and homepage description colour, not --faded. The
   descriptions here are the only prose on the page and were set as though they
   were metadata. */
[data-site] .topic-card-desc {
  font-family: 'Newsreader', Georgia, serif; font-size: 1.08rem; line-height: 1.5;
  color: var(--fg); opacity: 0.82; position: relative; z-index: 1;
}
/* An outlined mono chip that fills to solid accent — the site's outline-to-fill
   language, the same shape the article kicker, the settings segments and the
   Subscribe button use. Loose mono under a paragraph read as an afterthought;
   boxed, the mono is doing what mono does here, labelling a control.

   Right-aligned, so the cell has a diagonal to read along: name at the top
   left, the way out at the bottom right.

   margin-top:auto pins it to the bottom of the cell, so the chips line up
   across a row however long the descriptions run. The gap above it belongs to
   the description rather than the chip: an auto top margin absorbs whatever
   space is free, which is none once a description is long enough, and a
   padding-top would have grown the box instead of the space around it. */
[data-site] .topic-card-go {
  margin-top: auto;
  align-self: flex-end;
  display: inline-flex; align-items: center; gap: 9px;
  font-family: 'Fragment Mono', monospace; font-size: 12px; letter-spacing: 0.01em;
  color: var(--fg); position: relative; z-index: 1;
  border: 1px solid var(--fg); padding: 5px 13px;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
[data-site] .topic-card-desc { margin-bottom: clamp(16px, 2vw, 22px); }

/* Interactive state — :hover for pointers (clears when the pointer leaves);
   :active mirrors it so touch gets the same feedback while pressed without it
   sticking after release.

   The chip fills, which is what an outlined chip does here, and the name takes
   the colour. The cell no longer washes: a filled accent chip against a washed
   accent cell is the same colour twice at two strengths, and the chip is the
   thing that should read as the action. No lift either — a cell in a table
   cannot rise off the page without tearing the rules it shares with its
   neighbours, which is what the plates could afford and this cannot. */
@media (hover: hover) {
  [data-site] .topic-card:hover .topic-card-name { color: var(--accent); }
  [data-site] .topic-card:hover .topic-card-go {
    background: var(--accent); border-color: var(--accent); color: #fff;
  }
}
[data-site] .topic-card:active .topic-card-name { color: var(--accent); }
[data-site] .topic-card:active .topic-card-go {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
@media (prefers-reduced-motion: reduce) {
  [data-site] .topic-card, [data-site] .topic-card-go { transition: none; }
}
/* One column: every cell but the first draws the rule above it, and none draws
   one to its left — the nth-child(even) rule above is about columns, and there
   are none here. */
@media (max-width: 759.98px) {
  [data-site] .topic-cards { grid-template-columns: 1fr; }
  [data-site] .topic-card:nth-child(even) { border-left: 0; }
  [data-site] .topic-card:nth-child(n+2) { border-top: 1px solid var(--fg); }
}

/* inline prose links (About, 404, ...): black text, red underline; red text on hover/press */
[data-site] .prose-link { color: var(--fg); text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 1.5px; text-underline-offset: 2px; }
@media (hover: hover) { [data-site] .prose-link:hover { color: var(--accent); text-decoration-color: var(--accent); } }
[data-site] .prose-link:active { color: var(--accent); text-decoration-color: var(--accent); }

/* ---- subscribe form (/subscribe/): accessible focus / error / loading / success ---- */
[data-site] .sub-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* base border lives here (not inline) so the focus/error states below can
   recolour it — an inline border shorthand would outrank them */
[data-site] .sub-input { border: 1px solid var(--fg); }
/* on focus the input's own border turns accent — no offset ring stacked outside it */
[data-site] .sub-input:focus,
[data-site] .sub-input:focus-visible { outline: none; border-color: var(--accent); }
[data-site] .sub-input::placeholder { color: var(--faded); }
/* error is signalled by the status TEXT + aria-invalid; the border/colour are only reinforcement */
[data-site] .sub-input[aria-invalid="true"] { border-color: var(--accent); }
[data-site] .sub-status[data-state="error"] { color: var(--accent); }
[data-site] .sub-status[data-state="success"] { color: var(--fg); }
[data-site] .sub-status[data-state="loading"] { color: var(--faded); }
[data-site] .sub-btn[disabled] { opacity: 0.55; cursor: default; }
@media (hover: hover) { [data-site] .sub-btn:not([disabled]):hover { background: var(--accent); border-color: var(--accent); } }
[data-site] .sub-btn:not([disabled]):active { background: var(--accent); border-color: var(--accent); }
/* narrow screens: input over button, both full width (no fixed dimensions) */
@media (max-width: 519.98px) {
  [data-site] .sub-row { flex-direction: column; align-items: stretch; }
  [data-site] .sub-btn { justify-content: center; }
}

/* ---- subscribe confirmation modal (native <dialog>) ----
   Mirrors the reader's share sheet: framed panel, italic top-bar label with a
   hairline underline, edge-to-edge action cell at the foot, scale-in on open. */
[data-site] .sub-modal {
  box-sizing: border-box;
  width: min(480px, calc(100vw - 24px)); padding: 0; margin: auto;
  border: 1px solid var(--fg); background: var(--bg); color: var(--fg);
  box-shadow: 0 24px 60px -24px rgba(0,0,0,0.5); overflow: hidden;
  font-family: 'Newsreader', Georgia, serif;
}
[data-site] .sub-modal:not([open]) { display: none; }
[data-site] .sub-modal::backdrop { background: rgba(0,0,0,0.5); }
@media (prefers-reduced-motion: no-preference) {
  [data-site] .sub-modal[open] { animation: subModalIn 0.24s cubic-bezier(0.2,0.8,0.25,1); }
  [data-site] .sub-modal[open]::backdrop { animation: subBackdropIn 0.24s ease; }
}
@keyframes subModalIn { from { opacity: 0; scale: 0.94; } to { opacity: 1; scale: 1; } }
@keyframes subBackdropIn { from { opacity: 0; } to { opacity: 1; } }

/* top-bar: italic label + close, black underline (the share-sheet frame) */
[data-site] .sub-modal-top {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px 12px 22px; border-bottom: 1px solid var(--fg);
}
[data-site] .sub-modal-eyebrow {
  font-family: 'Cormorant Garamond', Georgia, serif; font-style: italic; font-weight: 600;
  font-size: 20px; line-height: 1; color: var(--fg);
}
[data-site] .sub-modal-close {
  width: 28px; height: 28px; padding: 0; appearance: none; border: none; background: none;
  cursor: pointer; color: var(--fg); display: flex; align-items: center; justify-content: center;
  transition: color 0.12s;
}
@media (hover: hover) { [data-site] .sub-modal-close:hover { color: var(--accent); } }
[data-site] .sub-modal-close:active { color: var(--accent); }
[data-site] .sub-modal-close svg { width: 17px; height: 17px; }

/* body */
[data-site] .sub-modal-body { padding: clamp(22px, 5vw, 30px) clamp(22px, 5vw, 30px) clamp(24px, 5vw, 30px); }
[data-site] .sub-modal-title {
  font-family: 'Cormorant Garamond', Georgia, serif; font-weight: 600;
  font-size: clamp(1.9rem, 4vw, 2.3rem); line-height: 1.04; letter-spacing: 0.005em; margin: 0 0 14px;
}
[data-site] .sub-modal-text { font-size: 1.06rem; line-height: 1.6; color: var(--fg); margin: 0 0 14px; text-wrap: pretty; }
[data-site] .sub-modal-text strong { font-weight: 600; }
[data-site] .sub-modal-fine { font-family: 'Newsreader', Georgia, serif; font-size: 1.06rem; line-height: 1.6; color: var(--fg); margin: 0; }

/* foot: one edge-to-edge action cell, like the share sheet's cells */
[data-site] .sub-modal-resend {
  width: 100%; appearance: none; background: none; border: none; border-top: 1px solid var(--fg);
  cursor: pointer; padding: 16px 12px; display: flex; align-items: center; justify-content: center; gap: 9px;
  font-family: 'Fragment Mono', monospace; font-size: 12.5px; letter-spacing: 0.02em; line-height: 1; color: var(--fg);
  transition: color 0.12s;
}
/* hover lands on the text only — the label recolours to accent; the cell
   itself never tints (that read too button-like) */
[data-site] .sub-modal-resend [data-subscribe-resend-label] { transition: color 0.12s; }
@media (hover: hover) { [data-site] .sub-modal-resend:hover [data-subscribe-resend-label] { color: var(--accent); } }
[data-site] .sub-modal-resend:active [data-subscribe-resend-label] { color: var(--accent); }
[data-site] .sub-modal-resend.confirmed { color: var(--accent); cursor: default; }
[data-site] .sub-modal-resend-check { display: none; align-items: center; }
[data-site] .sub-modal-resend-check svg { width: 15px; height: 15px; }
[data-site] .sub-modal-resend.confirmed .sub-modal-resend-check { display: inline-flex; }
