/* tokens/fonts.css */
/* Hava Kava - self-hosted webfonts.
   GENERATED by scripts/fetch-fonts.mjs. Do not edit by hand.
   Source: https://fonts.googleapis.com/css2?family=Bevan:ital@0;1&family=Rye&family=Spectral:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400;1,600&family=Space+Mono:ital,wght@0,400;0,700;1,400&display=swap */

@font-face {
  font-family: 'Bevan';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/bevan-400-italic-1.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;
}

@font-face {
  font-family: 'Bevan';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/bevan-400-italic-2.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;
}

@font-face {
  font-family: 'Bevan';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/bevan-400-italic-3.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Bevan';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/bevan-400-normal-1.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;
}

@font-face {
  font-family: 'Bevan';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/bevan-400-normal-2.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;
}

@font-face {
  font-family: 'Bevan';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/bevan-400-normal-3.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Rye';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/rye-400-normal-1.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;
}

@font-face {
  font-family: 'Rye';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/rye-400-normal-2.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Space Mono';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-mono-400-italic-1.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;
}

@font-face {
  font-family: 'Space Mono';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-mono-400-italic-2.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;
}

@font-face {
  font-family: 'Space Mono';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-mono-400-italic-3.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-mono-400-normal-1.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;
}

@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-mono-400-normal-2.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;
}

@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/space-mono-400-normal-3.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/space-mono-700-normal-1.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;
}

@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/space-mono-700-normal-2.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;
}

@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/space-mono-700-normal-3.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-italic-1.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-italic-2.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-italic-3.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-italic-4.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-italic-5.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-italic-1.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-italic-2.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-italic-3.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-italic-4.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-italic-5.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/spectral-300-normal-1.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/spectral-300-normal-2.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/spectral-300-normal-3.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/spectral-300-normal-4.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/spectral-300-normal-5.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-normal-1.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-normal-2.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-normal-3.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-normal-4.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/spectral-400-normal-5.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/spectral-500-normal-1.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/spectral-500-normal-2.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/spectral-500-normal-3.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/spectral-500-normal-4.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/fonts/spectral-500-normal-5.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-normal-1.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-normal-2.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-normal-3.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-normal-4.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/spectral-600-normal-5.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/spectral-700-normal-1.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/spectral-700-normal-2.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/spectral-700-normal-3.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/spectral-700-normal-4.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;
}

@font-face {
  font-family: 'Spectral';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/spectral-700-normal-5.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;
}


/* tokens/colors.css */
/* Hava Kava — colour system.
   Palette: ink black + boiler blue + ember red, with brass/copper as the only metals
   and aged paper as the single light surface family. */
:root {
  /* ── Ink (blacks & graphites — the iron chassis) ─────────────── */
  --ink-1000: #06070a;
  --ink-900: #0c0f16;
  --ink-800: #141922;
  --ink-700: #1d232e;
  --ink-600: #2a323e;
  --ink-500: #3b4553;

  /* ── Boiler Blue (primary hue — steam, enamel dials, night) ──── */
  --blue-900: #07182a;
  --blue-800: #0e2740;
  --blue-700: #143a5c;
  --blue-600: #1b5178;
  --blue-500: #246c99;
  --blue-400: #3e8cb8;
  --blue-300: #6fb0d2;
  --blue-200: #a8cfe3;
  --blue-100: #d7e7f0;

  /* ── Ember Red (action, heat, signage) ──────────────────────── */
  --red-900: #3f0b0b;
  --red-800: #63120f;
  --red-700: #8b1a14;
  --red-600: #b2261c;
  --red-500: #ce3a26;
  --red-400: #e4644a;
  --red-300: #f0967f;

  /* ── Brass & Copper (metals — hairlines, rivets, ornament) ──── */
  --brass-700: #6f4f13;
  --brass-600: #a67c21;
  --brass-500: #c89b2c;
  --brass-400: #dcb74f;
  --brass-300: #eed98a;
  --copper-600: #8c4a26;
  --copper-500: #b3673a;
  --copper-400: #cd8a5c;

  /* ── Aged Paper (light surfaces — menus, receipts, labels) ──── */
  --paper-100: #fbf6ea;
  --paper-200: #f2e9d6;
  --paper-300: #e2d5bb;
  --paper-400: #c9b894;
  --paper-500: #a2916f;

  /* ── Moss (the one non-palette semantic: kava, growth, ready) ─ */
  --moss-600: #2f6146;
  --moss-500: #3e7b57;
  --moss-400: #5c9a73;
  /* The light step badges use for their text, as --brass-300 and --red-300
     do. Same hue as --moss-400, lifted to ~68% lightness. */
  --moss-300: #95c6a7;

  /* ═══ Semantic aliases ══════════════════════════════════════ */
  /* Backgrounds: the system is dark-first. */
  --bg-base: var(--ink-1000);
  --bg-sunken: #030407;
  --bg-raised: var(--ink-900);
  --bg-plate: var(--blue-900);
  --bg-plate-alt: var(--ink-800);
  --bg-paper: var(--paper-200);
  --bg-paper-raised: var(--paper-100);

  /* Surfaces */
  --surface-card: var(--ink-900);
  --surface-card-hover: var(--ink-800);
  --surface-card-paper: var(--paper-100);
  --surface-inset: #04050a;
  --surface-field: rgba(255, 255, 255, 0.04);
  --surface-field-paper: #fffdf7;

  /* Text */
  --text-hi: var(--paper-100);
  --text-body: #cfd8e0;
  --text-muted: #8794a1;
  /* Raised from the design's #5d6a78, which fails WCAG AA for normal text
     (3.19-3.64:1). #738395 is the minimum along the same hue that passes
     (4.54-5.19:1) and stays dimmer than --text-muted. Locked by test/css.test.js. */
  --text-faint: #738395;
  --text-metal: var(--brass-400);
  --text-inverse: var(--ink-900);
  --text-inverse-muted: #5c5140;
  --text-on-accent: var(--paper-100);

  /* Accents */
  --accent-primary: var(--red-600);
  --accent-primary-hover: var(--red-500);
  --accent-primary-press: var(--red-700);
  --accent-secondary: var(--blue-500);
  --accent-secondary-hover: var(--blue-400);
  --accent-secondary-press: var(--blue-600);
  --accent-metal: var(--brass-500);
  --accent-metal-hover: var(--brass-400);

  /* Lines: every hairline in this system is a metal, never grey. */
  --line-metal: rgba(200, 155, 44, 0.42);
  /* The same brass, at the alpha a CONTROL's boundary needs. --line-metal is
     2.18:1 against --bg-base, which is fine for a decorative hairline (WCAG
     sets no minimum for those) but not for the entire visible boundary of an
     interactive control: SC 1.4.11 Non-text Contrast requires 3:1 for that, and
     .btn--ghost and .tag are both transparent-backgrounded, so their border IS
     the control. --line-metal-strong only ever appeared on :hover/:active,
     which keyboard and touch users never reach. This is 3.89:1, asserted from
     the shipped value in test/css.test.js. */
  --line-control: rgba(200, 155, 44, 0.66);
  --line-metal-strong: var(--brass-600);
  --line-cool: rgba(111, 176, 210, 0.22);
  --line-hairline: rgba(226, 213, 187, 0.14);
  --line-paper: rgba(90, 74, 44, 0.24);
  --line-rule: var(--brass-700);

  /* Status */
  --status-ready: var(--moss-500);
  --status-brewing: var(--brass-500);
  --status-hot: var(--red-500);
  --status-info: var(--blue-400);

  /* Location accents: each location's events carry its own border and glow,
     matching the Hava Kava app's schedule. Stuart is brass; Port St. Lucie is
     a bluish aluminum. Line is the 1px border, ring a 1px halo just outside it
     at 35%, glow an 18px soft glow at 45%: the same structure as
     --glow-brass in elevation.css. Applied by .loc-accent in pages.css. */
  --loc-stuart-line: var(--brass-400);
  --loc-stuart-ring: rgba(220, 183, 79, 0.35);  /* brass-400 #dcb74f */
  --loc-stuart-glow: rgba(200, 155, 44, 0.45);  /* brass-500 #c89b2c */
  --loc-psl-line: var(--blue-200);
  --loc-psl-ring: rgba(168, 207, 227, 0.35);    /* blue-200 #a8cfe3 */
  --loc-psl-glow: rgba(111, 176, 210, 0.45);    /* blue-300 #6fb0d2 */

  /* Utility */
  --focus-ring: var(--brass-400);
  --scrim: rgba(3, 4, 7, 0.78);
  --glass: rgba(12, 15, 22, 0.72);
  --selection-bg: var(--red-700);

  /* Signature washes — used full-bleed behind dark sections only. */
  --wash-boiler: radial-gradient(120% 90% at 12% 0%, #143a5c 0%, #07182a 46%, #06070a 100%); /* @kind color */
  --wash-ember: radial-gradient(90% 80% at 88% 108%, #8b1a14 0%, #3f0b0b 40%, #06070a 100%); /* @kind color */
  --wash-protect: linear-gradient(180deg, rgba(6, 7, 10, 0) 0%, rgba(6, 7, 10, 0.86) 72%, #06070a 100%); /* @kind color */
  --texture-rivet: radial-gradient(circle at center, var(--brass-600) 0 1.5px, rgba(200, 155, 44, 0.18) 1.5px 2.6px, transparent 2.7px); /* @kind color */
}

::selection { background: var(--selection-bg); color: var(--paper-100); }

/* tokens/typography.css */
/* Hava Kava — typography.
   Bevan (Victorian slab) shouts. Rye (woodtype) is a garnish, never a paragraph.
   Spectral reads. Space Mono meters, labels, and prices things. */
:root {
  --font-display: "Bevan", "Rockwell", "Clarendon", Georgia, serif;
  --font-accent: "Rye", "Bevan", Georgia, serif;
  --font-body: "Spectral", Georgia, "Times New Roman", serif;
  --font-mono: "Space Mono", "IBM Plex Mono", "Courier New", monospace;

  --weight-display: 400;
  --weight-body-light: 300;
  --weight-body: 400;
  --weight-body-medium: 500;
  --weight-body-bold: 600;
  --weight-mono: 400;
  --weight-mono-bold: 700;

  /* Type scale — 1.28 ratio, rounded to real numbers, not a 4px grid. */
  --size-micro: 11px;
  --size-label: 13px;
  --size-caption: 14px;
  --size-body-sm: 15px;
  --size-body: 17px;
  --size-body-lg: 19px;
  --size-title-sm: 23px;
  --size-title: 29px;
  --size-title-lg: 37px;
  --size-display-sm: 47px;
  --size-display: 60px;
  --size-display-lg: 77px;
  --size-mega: 104px;

  --leading-tight: 0.94;
  --leading-display: 1.02;
  --leading-title: 1.12;
  --leading-body: 1.62;
  --leading-loose: 1.78;

  --tracking-mega: -0.02em;
  --tracking-display: -0.005em;
  --tracking-body: 0;
  --tracking-label: 0.16em;
  --tracking-eyebrow: 0.28em;
  --tracking-mono: 0.06em;

  /* Semantic roles */
  --text-mega: var(--weight-display) var(--size-mega) / var(--leading-tight) var(--font-display);
  --text-display: var(--weight-display) var(--size-display) / var(--leading-display) var(--font-display);
  --text-display-sm: var(--weight-display) var(--size-display-sm) / var(--leading-display) var(--font-display);
  --text-title: var(--weight-display) var(--size-title) / var(--leading-title) var(--font-display);
  --text-accent-title: var(--weight-display) var(--size-title-lg) / var(--leading-title) var(--font-accent);
  --text-lede: var(--weight-body-light) var(--size-body-lg) / var(--leading-loose) var(--font-body);
  --text-copy: var(--weight-body) var(--size-body) / var(--leading-body) var(--font-body);
  --text-copy-sm: var(--weight-body) var(--size-body-sm) / var(--leading-body) var(--font-body);
  --text-caption: var(--weight-body) var(--size-caption) / var(--leading-body) var(--font-body);
  --text-eyebrow: var(--weight-mono-bold) var(--size-micro) / 1.4 var(--font-mono);
  --text-label: var(--weight-mono) var(--size-label) / 1.4 var(--font-mono);
  --text-meter: var(--weight-mono-bold) var(--size-caption) / 1.2 var(--font-mono);
}

/* tokens/space.css */
/* Hava Kava — spacing & layout.
   Base unit 6px: machined, slightly tighter than an 8px grid, so plates and
   rivets sit close together the way riveted steel does. */
:root {
  --space-0: 0;
  --space-1: 3px;
  --space-2: 6px;
  --space-3: 10px;
  --space-4: 14px;
  --space-5: 18px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 42px;
  --space-9: 56px;
  --space-10: 72px;
  --space-11: 96px;
  --space-12: 128px;
  --space-13: 168px;

  --gutter-inline: var(--space-6);
  --gutter-inline-lg: var(--space-8);
  --section-y: var(--space-11);
  --section-y-sm: var(--space-9);

  --pad-control-y: 11px;
  --pad-control-x: 20px;
  --pad-control-y-sm: 7px;
  --pad-control-x-sm: 13px;
  --pad-card: var(--space-6);
  --pad-card-lg: var(--space-8);

  --measure-narrow: 34ch;
  --measure: 62ch;
  --measure-wide: 78ch;

  --width-content: 1160px;
  --width-prose: 720px;
  --width-app: 390px;

  --control-h: 44px;
  --control-h-sm: 34px;
  --control-h-lg: 54px;
  --touch-min: 44px;
  --nav-h: 76px;
}

/* tokens/shape.css */
/* Hava Kava — shape & borders.
   Rule: nothing is a pill except tags and status lozenges. Plates get a 2px
   radius (cut steel), cards 3px, and one signature "ticket notch" clip. */
:root {
  --radius-none: 0;
  --radius-plate: 2px;
  --radius-card: 3px;
  --radius-control: 2px;
  --radius-lozenge: 999px;
  --radius-dialog: 4px;

  --border-hair: 1px;
  --border-plate: 2px;
  --border-heavy: 3px;

  --border-metal: var(--border-hair) solid var(--line-metal);
  --border-metal-strong: var(--border-plate) solid var(--line-metal-strong);
  --border-cool: var(--border-hair) solid var(--line-cool);
  --border-hairline: var(--border-hair) solid var(--line-hairline);
  --border-paper: var(--border-hair) solid var(--line-paper);

  /* Ticket notch — punched-card corners for vouchers, receipts, price tags. */
  --clip-ticket: polygon(0 9px, 9px 0, calc(100% - 9px) 0, 100% 9px, 100% calc(100% - 9px), calc(100% - 9px) 100%, 9px 100%, 0 calc(100% - 9px)); /* @kind other */
  --clip-tab: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%); /* @kind other */
}

/* tokens/elevation.css */
/* Hava Kava — elevation.
   Two systems: OUTER shadows are near-black and tight (objects sit on iron, they
   don't float), INNER shadows do the real work — pressed metal, engraved wells,
   and a 1px brass top-light on every raised plate. */
:root {
  --shadow-none: none;
  --shadow-plate: 0 1px 0 rgba(238, 217, 138, 0.14) inset, 0 2px 0 rgba(6, 7, 10, 0.6);
  --shadow-card: 0 1px 0 rgba(238, 217, 138, 0.1) inset, 0 6px 18px rgba(3, 4, 7, 0.55);
  --shadow-raised: 0 1px 0 rgba(238, 217, 138, 0.16) inset, 0 10px 28px rgba(3, 4, 7, 0.68);
  --shadow-dialog: 0 1px 0 rgba(238, 217, 138, 0.18) inset, 0 30px 70px rgba(3, 4, 7, 0.8);
  --shadow-pressed: 0 2px 6px rgba(3, 4, 7, 0.7) inset;
  --shadow-well: 0 2px 5px rgba(3, 4, 7, 0.65) inset, 0 1px 0 rgba(238, 217, 138, 0.08);
  --shadow-paper: 0 1px 0 rgba(255, 255, 255, 0.6) inset, 0 4px 12px rgba(63, 11, 11, 0.14);

  /* Glow is used sparingly: live/hot states only. */
  --glow-ember: 0 0 0 1px rgba(206, 58, 38, 0.5), 0 0 22px rgba(178, 38, 28, 0.4);
  --glow-brass: 0 0 0 1px rgba(220, 183, 79, 0.55), 0 0 18px rgba(200, 155, 44, 0.28);
  --ring-focus: 0 0 0 2px var(--bg-base), 0 0 0 4px var(--focus-ring);

  --blur-glass: blur(14px) saturate(120%); /* @kind other */
}

/* tokens/motion.css */
/* Hava Kava — motion.
   Machinery, not jelly. Things engage with a short mechanical snap; nothing
   bounces, nothing springs past its target. Long fades are for steam only. */
:root {
  --ease-clunk: cubic-bezier(0.2, 0.9, 0.2, 1); /* @kind other */
  --ease-engage: cubic-bezier(0.35, 0, 0.15, 1); /* @kind other */
  --ease-steam: cubic-bezier(0.4, 0, 0.6, 1); /* @kind other */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* @kind other */

  --dur-instant: 70ms; /* @kind other */
  --dur-snap: 130ms; /* @kind other */
  --dur-base: 220ms; /* @kind other */
  --dur-slow: 380ms; /* @kind other */
  --dur-steam: 900ms; /* @kind other */

  --transition-control: background-color var(--dur-snap) var(--ease-clunk), border-color var(--dur-snap) var(--ease-clunk), color var(--dur-snap) var(--ease-clunk), box-shadow var(--dur-snap) var(--ease-clunk), transform var(--dur-instant) var(--ease-clunk);
  --transition-surface: background-color var(--dur-base) var(--ease-engage), box-shadow var(--dur-base) var(--ease-engage), border-color var(--dur-base) var(--ease-engage);
  --press-shift: translateY(1px); /* @kind other */
}

@keyframes br-steam-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes br-gauge-tick { 0%, 100% { transform: rotate(-2deg); } 50% { transform: rotate(2deg); } }
@keyframes br-ember-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* tokens/ds-base.css */
/* Hava Kava — base layer: element defaults + a small set of brand
   utilities that would otherwise be re-invented on every screen. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--bg-base); color: var(--text-body); font: var(--text-copy); text-wrap: pretty; -webkit-font-smoothing: antialiased; }
h1, h2, h3, h4 { margin: 0; color: var(--text-hi); font-family: var(--font-display); font-weight: var(--weight-display); letter-spacing: var(--tracking-display); line-height: var(--leading-title); }
h1 { font-size: var(--size-display); line-height: var(--leading-display); }
h2 { font-size: var(--size-title-lg); }
h3 { font-size: var(--size-title); }
h4 { font-size: var(--size-title-sm); }
p { margin: 0 0 var(--space-4); max-width: var(--measure); }
a { color: var(--brass-400); text-decoration: none; border-bottom: 1px solid var(--line-metal); transition: color var(--dur-snap) var(--ease-clunk), border-color var(--dur-snap) var(--ease-clunk); }
a:hover { color: var(--red-400); border-bottom-color: var(--red-500); }
a:active { color: var(--red-500); }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline: none; box-shadow: var(--ring-focus); }
strong { color: var(--text-hi); font-weight: var(--weight-body-bold); }
em { font-style: italic; }
hr { height: 0; margin: var(--space-7) 0; border: 0; border-top: 1px solid var(--line-metal); }
small { font: var(--text-caption); color: var(--text-muted); }
code, kbd { font-family: var(--font-mono); font-size: 0.92em; letter-spacing: var(--tracking-mono); color: var(--brass-300); }
img { display: block; max-width: 100%; }
button { font-family: inherit; }

/* Utilities */
.br-eyebrow { font: var(--text-eyebrow); letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--text-metal); }
.br-plate { background: var(--bg-plate-alt); border: var(--border-metal); border-radius: var(--radius-plate); box-shadow: var(--shadow-plate); }
.br-rivets { background-image: var(--texture-rivet); background-size: 22px 22px; background-position: 0 0; }
.br-rule { height: 2px; border: 0; background: linear-gradient(90deg, var(--brass-600), rgba(200, 155, 44, 0.08)); }
.br-paper { background: var(--bg-paper); color: var(--text-inverse); }
.br-paper a { color: var(--red-700); border-bottom-color: rgba(139, 26, 20, 0.4); }
.br-paper a:hover { color: var(--blue-700); border-bottom-color: rgba(20, 58, 92, 0.5); }
.br-ticket { clip-path: var(--clip-ticket); }

/* base.css */
/* Hava Kava - base styles. Resets, document defaults, and the handful of
   utility classes the design's markup uses directly. */

*, *::before, *::after { box-sizing: border-box; }

/* The header is `position: sticky; top: 0` with `min-height: var(--nav-h)`, so
   anything the browser scrolls to the top of the viewport lands underneath it:
   every in-page anchor (#kava, #serve, #happy-hour, #install, and the skip
   link's own #main), and every element the browser scrolls into view when it
   receives focus during a Tab pass. scroll-padding on the scrolling element
   fixes all of them at once - it tells the browser the top --nav-h of the
   viewport is not usable landing space.

   This replaces a per-component `.location-card { scroll-margin-top }` rule,
   which was the only compensation anywhere and only ever covered
   /locations/#stuart and #psl (whole-branch review, finding I7). Do not add
   scroll-margin-top to individual components on top of this: the two offsets
   add up, and the target ends up parked well below the header. */
html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h, 76px) + var(--space-4, 14px));
}

body {
  margin: 0;
  background: var(--bg-base);
  color: var(--text-body);
  font: var(--text-copy);
  -webkit-font-smoothing: antialiased;
}

/* ds-base.css sets the family, weight, colour, leading and tracking already.
   Uppercase is the one display rule it does not carry, and the design applies it
   to every headline. */
h1, h2, h3, h4 { text-transform: uppercase; }

p:last-child { margin-bottom: 0; }

video { max-width: 100%; height: auto; display: block; }

/* Element defaults, links, .br-eyebrow, .br-paper and the focus ring all come
   from the design system's own base layer (tokens/ds-base.css), which loads
   first. Do NOT restate them here: this file loads afterwards, so a duplicate
   silently wins and the design's version becomes dead code.

   Focus in particular: ds-base.css applies box-shadow: var(--ring-focus), which
   elevation.css defines as "0 0 0 2px var(--bg-base), 0 0 0 4px var(--focus-ring)"
   - the 2px ink gap then 2px brass ring the design calls for.

   One addition the design layer lacks: a box-shadow is invisible in Windows
   forced-colors mode, so pair it with a transparent outline, which forced-colors
   repaints as a real ring. The selector list MUST match ds-base.css's so both
   rules tie on specificity and source order (this file wins) decides which wins.
   If you simplify this to bare :focus-visible, outline: none will silently win
   on every focusable element and forced-colors mode gets no indicator at all. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
}

.container {
  max-width: 1160px;
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 42px);
}

.section { padding-block: clamp(56px, 8vw, 96px); }

/* .br-eyebrow, .br-paper, .br-plate, .br-rivets, .br-rule and .br-ticket are
   NOT defined here — the design system's own base layer ships all six, and this
   file loads after it, so restating any of them would override the design's
   version with a near-copy. Use them directly in markup. */

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  top: 0; left: 0;
  z-index: 100;
  padding: var(--space-3) var(--space-5);
  background: var(--ink-900);
  border: 1px solid var(--line-metal-strong);
  transform: translateY(-120%);
}
.skip-link:focus { transform: translateY(0); }

/* Machinery, not jelly - and none of it for anyone who asked for less. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* components.css */
/* Hava Kava - components. Plates, not cards: 1px brass hairline, a 1px inner
   top-light, tight near-black drop, and radii that stay small. Spec 5.3. */

/* ── Buttons ──────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding-inline: var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-control, 2px);
  font: var(--text-label);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 130ms var(--ease-clunk, cubic-bezier(.2,.9,.2,1)),
              border-color 130ms var(--ease-clunk, cubic-bezier(.2,.9,.2,1)),
              transform 130ms var(--ease-clunk, cubic-bezier(.2,.9,.2,1));
}

.btn--sm { min-height: 34px; font-size: var(--size-micro); }
.btn--md { min-height: 44px; }
.btn--lg { min-height: 54px; padding-inline: var(--space-6); font-size: var(--size-label); }

.btn--primary {
  background: var(--accent-primary);
  border-color: var(--accent-primary);
  color: var(--text-on-accent);
}
.btn--primary:hover {
  background: var(--accent-primary-hover);
  border-color: var(--line-metal-strong);
  color: var(--text-on-accent);
}
.btn--primary:active {
  background: var(--accent-primary-press);
  transform: translateY(1px);
}

/* Transparent fill, so this border is the whole control: --line-control, not
   the decorative --line-metal. See the token's note in tokens/colors.css. */
.btn--ghost {
  background: transparent;
  border-color: var(--line-control);
  color: var(--text-hi);
}
.btn--ghost:hover {
  background: var(--surface-card-hover);
  border-color: var(--line-metal-strong);
  color: var(--text-hi);
}
.btn--ghost:active { background: var(--surface-card); border-color: var(--line-metal-strong); transform: translateY(1px); }

/* Buttons are not links: strip the base link underline. */
a.btn { border-bottom: 1px solid transparent; }
a.btn--ghost { border-bottom-color: var(--line-control); }

.btn[disabled], .btn[aria-disabled="true"] {
  opacity: 0.42;
  cursor: not-allowed;
}

/* ── Badges ───────────────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 22px;
  padding: 2px var(--space-3);
  border: 1px solid;
  border-radius: var(--radius-plate, 2px);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  white-space: nowrap;
}

.badge--brass { border-color: var(--line-metal); color: var(--brass-300); background: rgba(200,155,44,0.08); }
.badge--ember { border-color: rgba(206,58,38,0.45); color: var(--red-300); background: rgba(206,58,38,0.12); }
.badge--ink   { border-color: var(--line-hairline); color: var(--text-muted); background: var(--ink-800); }
/* Moss is the system's one green: "kava, growth, ready" (colors.css). Used for
   a location that has just opened. */
.badge--moss  { border-color: rgba(92,154,115,0.55); color: var(--moss-300); background: rgba(62,123,87,0.18); }

.badge__dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--red-500);
  flex: none;
}
.badge--moss .badge__dot { background: var(--moss-300); }
.badge--live .badge__dot { animation: br-ember-pulse 1600ms ease-in-out infinite; }

@keyframes br-ember-pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(206,58,38,0.55); }
  50%      { opacity: 0.6; box-shadow: 0 0 0 4px rgba(206,58,38,0); }
}

/* ── Tags (the one pill in the system) ────────────────────────────── */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--control-h-sm);
  padding: 0 var(--space-4);
  /* Same reasoning as .btn--ghost: transparent fill, so the border is the
     control's only boundary and owes 3:1 under SC 1.4.11. */
  border: 1px solid var(--line-control);
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  text-decoration: none;
}
.tag:hover { border-color: var(--line-metal-strong); color: var(--text-hi); }
.tag:active { background: var(--surface-card); border-color: var(--line-metal-strong); color: var(--text-hi); transform: translateY(1px); }
.tag--selected {
  background: var(--accent-metal);
  border-color: var(--accent-metal);
  color: var(--text-inverse);
}
.tag--selected:hover { background: var(--accent-metal-hover); color: var(--text-inverse); }

/* ── Divider ──────────────────────────────────────────────────────── */
.divider {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  border-top: 1px solid var(--line-metal);
  padding-top: var(--space-4);
}
.divider__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--text-metal);
}

/* ── Plates: the system's surface, five finishes only ─────────────── */
.plate {
  position: relative;
  background: var(--surface-card);
  border: 1px solid var(--line-metal);
  border-radius: var(--radius-card, 3px);
  box-shadow: var(--shadow-card), inset 0 1px 0 rgba(238,217,138,0.08);
}
.plate--boiler { background: var(--wash-boiler); }
.plate--ember  { background: var(--wash-ember); border-color: rgba(206,58,38,0.35); }
.plate--inset  {
  background: var(--surface-inset);
  border-color: var(--line-hairline);
  box-shadow: var(--shadow-well);
}
.plate--paper {
  background: var(--surface-card-paper);
  border-color: var(--line-paper);
  color: var(--text-inverse);
}

.plate--link { display: block; text-decoration: none; color: inherit; border-bottom: 0; }
.plate--link:hover {
  transform: translateY(-2px);
  border-color: var(--line-metal-strong);
  color: inherit;
}
.plate--link { transition: transform 220ms var(--ease-engage, cubic-bezier(.2,.9,.2,1)), border-color 130ms; }

@media (prefers-reduced-motion: reduce) {
  .plate--link:hover { transform: none; }
  .badge--live .badge__dot { animation: none; }
  .btn--primary:active,
  .btn--ghost:active,
  .tag:active { transform: none; }
}

/* ── Site header: the only fixed element in the system ────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  min-height: var(--nav-h, 76px);
  padding-inline: clamp(18px, 4vw, 42px);
  background: var(--glass);
  backdrop-filter: var(--blur-glass, blur(14px) saturate(120%));
  border-bottom: 1px solid var(--line-metal);
  box-shadow: inset 0 1px 0 rgba(238,217,138,0.08), 0 8px 24px rgba(3,4,7,0.5);
}
.site-header__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  border-bottom: 0;
}
/* The `image` shortcode writes the largest generated rendition's intrinsic
   size (320x201 for the logo's own widths) onto width/height so the browser can
   reserve layout space before the image loads - those attributes are not a
   display-size cap. Without this rule the logo renders at that size, blowing
   out .site-header's `min-height: var(--nav-h, 76px)`. 46px tall (per
   design), width: auto to preserve the 2378:1496 aspect ratio (~73px wide,
   matching the shortcode's `sizes="74px"` hint). */
.site-header__logo { height: 46px; width: auto; }
/* Hidden by default: a toggle that does nothing without JS is worse than no
   toggle. nav.js reveals it (by adding .site-header--collapsible) the moment
   it has attached a working click handler. See the mobile block below. */
.site-header__toggle { display: none; }

.site-nav { display: flex; align-items: center; gap: var(--space-6); }

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-block: var(--space-2);
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  font: var(--text-label);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}
.nav__link:hover { color: var(--brass-300); border-bottom-color: transparent; }
.nav__link--active { color: var(--text-hi); border-bottom-color: var(--red-500); }

.nav__group { position: relative; }
.nav__group > summary { list-style: none; }
.nav__group > summary::-webkit-details-marker { display: none; }

.nav__menu {
  position: absolute;
  top: calc(100% + var(--space-3));
  left: 0;
  min-width: 240px;
  display: grid;
  padding-block: var(--space-2);
  background: var(--ink-900);
  border: 1px solid var(--line-metal);
  border-top: 2px solid var(--red-500);
  border-radius: 0 0 var(--radius-card, 3px) var(--radius-card, 3px);
  box-shadow: var(--shadow-raised);
}
.nav__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-3) var(--space-5);
  border-bottom: 0;
  color: var(--text-hi);
  font-family: var(--font-display);
  font-size: var(--size-body-sm);
  text-transform: uppercase;
  white-space: nowrap;
}
.nav__item:hover { background: var(--ink-800); color: var(--text-hi); }
.nav__item-sub { color: var(--text-muted); }

@media (max-width: 759px) {
  .site-header { flex-wrap: wrap; }
  .site-nav {
    flex-basis: 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-bottom: var(--space-5);
  }
  .nav__menu { position: static; box-shadow: none; border-top-width: 1px; }

  /* Progressive enhancement, inverted: the nav is visible by default, which is
     the working state with no JavaScript at all. Only once nav.js has attached
     its click handler does it mark the header `.site-header--collapsible`,
     which is what lets these two rules collapse the nav behind the toggle. */
  .site-header--collapsible .site-header__toggle { display: inline-flex; }
  .site-header--collapsible .site-nav { display: none; }
  .site-header--collapsible .site-nav--open { display: flex; }
}

/* ── Site footer ──────────────────────────────────────────────────── */
.site-footer {
  background: var(--ink-900);
  border-top: 1px solid var(--line-metal);
  padding-block: clamp(42px, 6vw, 56px) var(--space-7);
  font: var(--text-copy-sm);
  color: var(--text-body);
}
.site-footer__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: var(--space-8);
}
/* Same fix as .site-header__logo above: 56px tall (per design), width: auto
   to preserve the full logo's 2378:1496 aspect ratio (~89px wide, matching
   the shortcode's `sizes="89px"` hint; the header's 46px gives ~73px). */
.site-footer__logo { height: 56px; width: auto; }
.site-footer__blurb { margin-top: var(--space-5); color: var(--text-muted); max-width: 34ch; }
.site-footer__lines {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-4);
  color: var(--text-muted);
}
.site-footer__lines a { color: var(--text-muted); border-bottom: 0; }
.site-footer__lines a:hover { color: var(--brass-300); }
.site-footer__legal {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-hairline);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
}

/* pages.css */
/* Hava Kava — home page. Section, hero, events-header, event-card and
   location-card rules. Ported from the design file section by section; every
   inline style in the design becomes a class here (spec's own transcription
   rule), and the design's three lightweight components (Button, Badge, Tag,
   Divider) stay macros in macros/ui.njk rather than being restated as CSS. */

/* ── Shared section furniture ─────────────────────────────────────── */
.section-lede {
  font: var(--text-lede);
  color: var(--text-body);
  max-width: 58ch;
  margin: 0;
}

h2 { font-size: clamp(29px, 4.2cqi, 37px); margin: var(--space-4) 0; }

/* Every image inside a card fills its box rather than leaving letterboxing. */
.event-card img,
.location-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ── Hero ─────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  /* svh after the vh fallback: on iOS, vh is the viewport with the address bar
     retracted, so a vh hero is taller than the screen it first loads on and
     jumps when the bar moves. svh is the height actually visible on landing. */
  min-height: min(82vh, 760px);
  min-height: min(82svh, 760px);
  background: var(--wash-boiler);
  border-bottom: var(--border-hair) solid var(--line-metal);
  overflow: hidden;
  container-type: inline-size;
  display: flex;
  align-items: center;
}

.hero video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.85) brightness(0.85);
  pointer-events: none;
}

/* The scrim that keeps the headline readable over moving footage. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background: var(--wash-protect);
  pointer-events: none;
}

/* Hidden until nav.js has attached a working click handler, the same contract
   .site-header__toggle has: with no JavaScript the hero video never plays (it
   carries no autoplay attribute - nav.js starts it, gated on reduced motion),
   so a keyboard-reachable button offering to pause it is a mislabelled control
   that does nothing. nav.js adds .hero__video-toggle--ready. */
.hero__video-toggle {
  position: absolute;
  right: clamp(18px, 4cqi, 42px);
  bottom: var(--space-5);
  z-index: 2;
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  background: rgba(6, 7, 10, 0.6);
  border: var(--border-hairline);
  border-radius: 50%;
  color: var(--paper-100);
  cursor: pointer;
}
.hero__video-toggle--ready { display: flex; }
.hero__video-toggle:hover { background: rgba(6, 7, 10, 0.8); }

/* Both glyphs render (nav.js only ever toggles data-state, never the DOM),
   and CSS shows the one that matches: playing shows the pause glyph you'd
   press to stop it, paused shows the play glyph you'd press to start it. */
.hero__video-icon--play { display: none; }
.hero__video-toggle[data-state="paused"] .hero__video-icon--pause { display: none; }
.hero__video-toggle[data-state="paused"] .hero__video-icon--play { display: block; }

.hero__inner {
  position: relative;
  /* Height-aware as well as width-aware. On its own 9cqi gave a short, wide
     laptop screen (1333x711) 120px of padding above the badge, which helped
     push the locations below the fold. The svh term caps it on short screens
     and leaves tall ones exactly as they were. */
  padding-block: clamp(40px, min(9cqi, 9svh), 128px);
  display: grid;
  gap: var(--space-8);
  align-items: center;
  /* .hero is a flex container (it centres this vertically against min-height),
     which makes this a flex item - and a flex item is `flex: 0 1 auto`, so it
     shrink-wraps to its content instead of filling the line. .container's
     max-width is a cap, never a width, so without this the box collapsed to
     .hero__copy's 640px and .container's own margin-inline: auto then centred
     the collapsed box, putting the headline well right of where every other
     section on the page starts. */
  width: 100%;
}

/* Two columns once there is room for both: the copy, and the locations beside
   it. Queried against .hero (container-type: inline-size), the same box every
   cqi unit in this section already measures. */
@container (min-width: 960px) {
  .hero__inner {
    grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
    column-gap: clamp(32px, 5cqi, 96px);
  }
}

.hero__copy { max-width: 640px; }

.hero__title {
  margin: var(--space-5) 0 var(--space-6);
  padding-bottom: 0.12em;
  font-size: clamp(60px, min(14cqi, 15svh), 128px);
  line-height: 1.02;
  letter-spacing: var(--tracking-mega);
  color: var(--paper-100);
}
.hero__bang { color: var(--red-500); }

.hero__sub {
  margin: 0 0 var(--space-6);
  font-size: clamp(23px, min(3.6cqi, 5svh), 37px);
  line-height: 1.08;
  color: var(--text-hi);
  max-width: 20ch;
}

.hero__lede { font: var(--text-lede); color: var(--text-body); max-width: 46ch; }

.hero__ctas { display: flex; gap: var(--space-4); margin-top: var(--space-7); flex-wrap: wrap; }

.hero__note {
  margin: var(--space-5) 0 0;
  font: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ── Hero: locations ──────────────────────────────────────────────── */
/* Single column, these sit under the copy and pair up side by side when
   there is room; in the two-column hero they stack in the right column. */
.hero__locations {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}
@container (min-width: 960px) {
  .hero__locations { grid-template-columns: 1fr; }
}

/* Glass rather than the plate's opaque ink: these sit over moving footage,
   and the header already establishes glass as how chrome floats over it. */
.hero-location {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--glass);
  backdrop-filter: var(--blur-glass);
  -webkit-backdrop-filter: var(--blur-glass);
}
/* Stacked on purpose. Side by side, "Stuart" plus its badge fits a ticket's
   width and "Port St. Lucie" plus its badge does not, so the two tickets
   would break differently from each other. */
.hero-location__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}
.hero-location__name {
  font-family: var(--font-display);
  font-size: var(--size-title-sm);
  line-height: 1;
  text-transform: uppercase;
  color: var(--text-hi);
}
.hero-location__fact {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font: var(--text-copy-sm);
  color: var(--text-body);
}
.hero-location__fact svg { flex: none; margin-top: 3px; color: var(--brass-400); }
.hero-location__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-2);
}
/* A 44px target like the Directions button beside it. The base link
   underline is a border-bottom, which would sit at the bottom of that 44px box
   rather than under the number, so this one underlines the text itself. */
.hero-location__call {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  font: var(--text-label);
  letter-spacing: var(--tracking-mono);
  border-bottom: 0;
  text-decoration: underline;
  text-decoration-color: var(--line-metal);
  text-underline-offset: 4px;
}
.hero-location__call:hover { text-decoration-color: var(--red-500); }

/* ── Tonight ──────────────────────────────────────────────────────── */
/* Less air than a full section: it is a strip between the hero and "What's
   on", and with .section's 96px on both sides plus the next section's own top
   padding, one line of banner sat in ~290px of nothing. The bottom is zero
   because #events below already brings its own top padding. */
.section.tonight { padding-block: clamp(32px, 4vw, 48px) 0; }

/* One card fills the row; two (one per location) sit side by side; more wrap.
   Hidden cards are display: none, so they never hold a grid slot. */
.tonight__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr));
  gap: var(--space-5);
}

.tonight-card {
  display: grid;
  grid-template-columns: clamp(104px, 26%, 220px) minmax(0, 1fr);
  overflow: hidden;
}
/* events-live.js toggles `hidden` on these, and the rule above sets display,
   which beats the UA [hidden] rule (see CLAUDE.md). Listed in HIDDEN_TARGETS
   in test/css.test.js. */
.tonight-card[hidden] { display: none; }

.tonight-card__flyer {
  position: relative;
  aspect-ratio: 4 / 5;
  align-self: start;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid rgba(206,58,38,0.35);
}
.tonight-card__flyer--boiler { background: var(--wash-boiler); }
.tonight-card__flyer--ember  { background: var(--wash-ember); }
.tonight-card__flyer--plate  { background: var(--ink-800); }
.tonight-card__flyer img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tonight-card__placeholder { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--brass-300); }

.tonight-card__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: clamp(16px, 2.4vw, 28px);
}
.tonight-card__when { margin-top: var(--space-1); }
.tonight-card__name {
  font-size: clamp(23px, 2.6vw, 37px);
  line-height: 1.04;
}
.tonight-card__note { margin: 0; font: var(--text-copy-sm); color: var(--text-body); }
/* margin-top: auto pins the actions to the bottom, so two cards side by side
   line their buttons up even when one note runs longer. */
.tonight-card__actions {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: var(--space-2);
}
.tonight-card__directions { font: var(--text-label); letter-spacing: var(--tracking-mono); }

/* ── App strip ────────────────────────────────────────────────────── */
.app-strip__panel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--space-6);
  align-items: center;
  padding: clamp(24px, 4cqi, 42px);
}
.app-strip__title { margin: var(--space-3) 0; font-size: clamp(23px, 3.4cqi, 37px); max-width: 22ch; }
.app-strip__copy { font: var(--text-copy); color: var(--text-body); max-width: 52ch; margin: 0; }
.app-strip__ctas { display: flex; gap: var(--space-4); flex-wrap: wrap; }

/* -- Events: section header --------------------------------------- */
/*
   The intro and its actions sit side by side on a wide viewport and stack on a
   narrow one. `align-items: end` puts the tags and the All-events button on the
   lede's last line rather than floating them up against the eyebrow.

   The seven-cell weekly board and the "Coming up" strip that used to live here
   are gone - this section is the poster grid alone, per the design. See the
   comment in src/index.njk for why the tags are links rather than an in-place
   filter.
*/
.events-head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-5);
  margin-bottom: var(--space-7);
}
.events-head__intro { flex: 1 1 32ch; }
.events-head__intro .section-lede { margin-bottom: 0; }
.events-head__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

/* ── Event card ───────────────────────────────────────────────────── */
.events-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
  gap: var(--space-5);
  margin: var(--space-8) 0;
}

.event-card { display: flex; flex-direction: column; overflow: hidden; }
/* `[hidden]` is an author-origin selector here, so it beats the UA
   `[hidden] { display: none }` rule on origin as well as on specificity -
   without this, events-live.js's `card.hidden = true` (the location filter)
   sets the attribute but the card stays visible at full size. */
.event-card[hidden] { display: none; }

/* ── Location accents ─────────────────────────────────────────────── */
/* Event cards (the grid and the Tonight banner), the location cards and the
   hero's location tickets take their location's border and glow, so Stuart and Port St. Lucie read apart at
   a glance, as they do in the app. A location class only sets the three values; .loc-accent applies
   them. A location with no class of its own falls back to the standard brass
   hairline and no glow rather than an invalid border.

   `.plate.loc-accent` is (0,2,0), the same as .plate--link:hover, and this
   file loads after components.css, so a hovered card keeps its location
   colour instead of switching to the generic hover brass. The card's own drop
   shadow stays at the end of the list. */
.loc--stuart { --loc-line: var(--loc-stuart-line); --loc-ring: var(--loc-stuart-ring); --loc-glow: var(--loc-stuart-glow); }
.loc--psl    { --loc-line: var(--loc-psl-line);    --loc-ring: var(--loc-psl-ring);    --loc-glow: var(--loc-psl-glow); }
.plate.loc-accent {
  border-color: var(--loc-line, var(--line-metal));
  box-shadow:
    0 0 0 1px var(--loc-ring, transparent),
    0 0 18px var(--loc-glow, transparent),
    var(--shadow-card);
}

.event-card__flyer {
  position: relative;
  aspect-ratio: 4 / 5;
  display: flex;
  align-items: flex-end;
  border-bottom: var(--border-hairline);
  overflow: hidden;
}
.event-card__flyer--boiler { background: var(--wash-boiler); }
.event-card__flyer--ember  { background: var(--wash-ember); }
.event-card__flyer--plate  { background: var(--ink-800); }

.event-card__placeholder {
  position: relative;
  padding: var(--space-4);
  color: var(--brass-300);
  display: flex;
  align-items: center;
  gap: 8px;
}
/* Both badges sit top-right, Tonight under the date. The house flyers put the
   Hava Kava logo in the top-left corner, and a top-left date badge landed on
   it. */
.event-card__badges { position: absolute; top: 12px; right: 12px; display: flex; gap: 6px; }
.event-card__tonight { position: absolute; top: 40px; right: 12px; }
/* Over a real flyer the badges sit on a photograph, where their usual faint
   tint can vanish against a bright patch. Text and border keep their tone. */
.event-card__flyer .badge {
  background-color: rgba(6, 7, 10, 0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.event-card__body {
  padding: var(--space-5) var(--space-5) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  flex: 1;
}
.event-card__name { font-size: var(--size-title-sm); line-height: 1.08; }
.event-card__meta {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font: var(--text-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--brass-300);
}
.event-card__loc { color: var(--text-muted); }
.event-card__note { font: var(--text-copy-sm); color: var(--text-muted); margin: 0; }
.event-card__more {
  margin-top: auto;
  padding-top: var(--space-2);
  color: var(--brass-400);
  letter-spacing: var(--tracking-label);
}

/* ── Locations ────────────────────────────────────────────────────── */
.locations-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr));
  gap: var(--space-6);
  margin-top: var(--space-8);
}
.location-card { display: flex; flex-direction: column; overflow: hidden; }
.location-card__photo {
  position: relative;
  height: 240px;
  border-bottom: var(--border-hairline);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
/* A real photo fills the slot behind the badge. The shortcode wraps it in
   <picture>, which is the box that has to fill; `.location-card img` already
   makes the <img> cover that box. */
.location-card__photo picture { position: absolute; inset: 0; }
.location-card__photo--boiler { background: var(--wash-boiler); }
.location-card__photo--ember  { background: var(--wash-ember); }
.location-card__badge { position: absolute; top: 14px; left: 14px; z-index: 1; }
/* Over a photo the badge's faint tint can vanish, the same reason the event
   cards' badges get this backing. Text and border keep their tone. */
.location-card__badge .badge {
  background-color: rgba(6, 7, 10, 0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.location-card__placeholder {
  position: relative;
  padding: var(--space-5);
  color: var(--brass-300);
  display: flex;
  align-items: center;
  gap: 8px;
}
/* The body fills the card (cards in a row are already equal height), and
   margin-top: auto on the CTAs pins them to its bottom edge. Side-by-side
   cards then line up their Directions and Call buttons even though Stuart's
   weekly list is longer than Port St. Lucie's "coming soon". */
.location-card__body { flex: 1; padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-6); }
.location-card__facts { display: grid; gap: var(--space-4); margin-top: var(--space-5); }
.location-card__fact { display: flex; gap: var(--space-4); align-items: flex-start; color: var(--brass-400); }
.location-card__fact-main { font: var(--text-copy); color: var(--text-hi); }
.location-card__fact-sub { font: var(--text-caption); color: var(--text-muted); }

.location-card__weekly { padding: var(--space-5); }
.location-card__weekly-list { display: grid; margin-top: var(--space-3); }
.location-card__weekly-row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: var(--border-hairline);
}
.location-card__weekly-row:last-child { border-bottom: 0; }
.location-card__weekly-row--oneoff { color: var(--red-400); border-bottom: 0; }
.location-card__weekly-day { width: 40px; font: var(--text-meter); color: var(--brass-300); text-transform: uppercase; }
.location-card__weekly-row--oneoff .location-card__weekly-day { color: var(--red-400); }
.location-card__weekly-row a { flex: 1; border-bottom: 0; font-family: var(--font-display); text-transform: uppercase; color: var(--text-hi); line-height: 1.1; }
.location-card__weekly-row span:nth-child(2) { flex: 1; font-family: var(--font-display); text-transform: uppercase; color: var(--text-hi); line-height: 1.1; }
.location-card__weekly-time { font: var(--text-label); color: var(--text-muted); }
.location-card__oneoffs { margin-top: var(--space-4); }
.location-card__oneoffs-label { color: var(--red-400); }
.location-card__soon { font-size: var(--size-title-sm); color: var(--text-muted); margin: var(--space-3) 0 0; }
.location-card__soon-copy { font: var(--text-copy-sm); color: var(--text-muted); margin: var(--space-2) 0 0; }
.location-card__ctas { display: flex; gap: var(--space-4); flex-wrap: wrap; margin-top: auto; }

/* ── What is kava ─────────────────────────────────────────────────── */
.kava { background: var(--wash-boiler); border-top: var(--border-hair) solid var(--line-metal); border-bottom: var(--border-hair) solid var(--line-metal); }
.kava__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: clamp(32px, 5cqi, 72px);
  align-items: start;
}
.kava__lede { font: var(--text-lede); color: var(--text-hi); max-width: 52ch; }
.kava__copy { font: var(--text-copy); color: var(--text-body); max-width: 58ch; }
.kava__ctas { display: flex; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-6); }

.kava__ticket-head {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: var(--border-paper);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--copper-600);
}
.kava__ticket-body { padding: var(--space-6); display: grid; gap: var(--space-5); }
.kava__ticket-item { display: flex; gap: var(--space-4); }
.kava__ticket-num { font: var(--text-meter); color: var(--copper-600); }
.kava__ticket-title { font-family: var(--font-display); font-size: var(--size-body-lg); text-transform: uppercase; color: var(--ink-900); line-height: 1.1; }
.kava__ticket-text { font: var(--text-copy-sm); color: var(--ink-800); margin-top: 4px; }
.kava__ticket-foot { padding: var(--space-4) var(--space-6); border-top: var(--border-paper); font: var(--text-label); color: var(--text-inverse-muted); }

/* ── What we pour ─────────────────────────────────────────────────── */
/* 203px with a 14px gap fits five columns inside the full container width
   (5x203 + 4x14 = 1071px of 1076px; measured one row from 1170px), so five
   drinks share one row on laptops and desktops instead of four plus a lone
   fifth. 204px was exactly 1076px and rounding pushed it to four columns. The
   16px side padding leaves 169px inside a card: the widest name, "BOTANICAL"
   at --size-title-sm, measures 162px. Measured, not estimated: a 198px
   minimum overflowed at 1146px. Below this width the grid wraps as before. */
.serve-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 203px), 1fr));
  gap: var(--space-4);
  margin-top: var(--space-8);
}
.serve-item { padding: var(--space-6) 16px; }
.serve-item__head { display: flex; align-items: center; gap: var(--space-3); color: var(--brass-400); }
.serve-item__num { font: var(--text-eyebrow); letter-spacing: var(--tracking-label); }
.serve-item h3 { margin: var(--space-4) 0 var(--space-3); font-size: var(--size-title-sm); }
.serve-item p { font: var(--text-copy-sm); color: var(--text-muted); margin: 0; }

/* ── Snacks ───────────────────────────────────────────────────────── */
/* A continuation of "What we pour": no top padding, because #serve's bottom
   padding already separates them, and lighter cards than the drinks, since
   a snack is a name, not a description. */
.section.snacks { padding-top: 0; }
/* Fixed steps, not auto-fit, so four snacks never split 3+1: one column on
   phones, two from 600px, four from 1100px. Each step leaves at least 198px
   inside a card for the widest word, "MOZZARELLA" (192px). */
.snack-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin: var(--space-7) 0 0;
  padding: 0;
  list-style: none;
}
/* Number above the name, as on the drink cards, so a long name that wraps
   ("Mozzarella sticks") lays out the same as a short one. */
.snack-item { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-5); }
@media (min-width: 600px) { .snack-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .snack-grid { grid-template-columns: repeat(4, 1fr); } }
.snack-item__num { font: var(--text-eyebrow); letter-spacing: var(--tracking-label); color: var(--brass-400); }
.snack-item h3 { margin: 0; font-size: var(--size-title-sm); }
.snack-item p { margin: 0; font: var(--text-copy-sm); color: var(--text-muted); }

/* ── Happy hours ──────────────────────────────────────────────────── */
.happy-hour__head { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-6); flex-wrap: wrap; }
.happy-hour__soon { margin-top: var(--space-8); }
/* Two across, then wrapping to 2x2 for the four windows, then one per row on a
   phone. The 480px minimum is doing deliberate work: the design sized this
   ticket around a big display time (`clamp(37px, 5cqi, 60px)`), and the old
   340px minimum fitted three per row in a 1160px container - which with four
   windows left one card stranded on a second row, reading as a mistake rather
   than a layout. Dropping the minimum far enough to fit four across instead
   would squeeze "1:30 - 3:30PM" at the clamp's floor and cost the ticket the
   one thing that gives it its character. */
.happy-hour-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 480px), 1fr));
  gap: var(--space-6);
  margin-top: var(--space-8);
}
.happy-hour-card__head {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: var(--border-paper);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--copper-600);
}
.happy-hour-card__body { padding: var(--space-6); }
.happy-hour-card__time { font-family: var(--font-display); font-size: clamp(37px, 5cqi, 60px); line-height: 1; text-transform: uppercase; color: var(--ink-900); }
.happy-hour-card__days { margin-top: var(--space-3); font: var(--text-label); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--text-inverse-muted); }
.happy-hour-card__lines { margin-top: var(--space-5); display: grid; gap: var(--space-2); }
.happy-hour-card__line { display: flex; justify-content: space-between; padding: var(--space-2) 0; border-bottom: var(--border-paper); font: var(--text-copy-sm); color: var(--ink-800); }
.happy-hour-card__line:last-child { border-bottom: 0; }
.happy-hour-card__price { font-family: var(--font-mono); font-size: 14px; color: var(--ink-900); }

/* ── Events index ─────────────────────────────────────────────────── */
.events-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-6);
  flex-wrap: wrap;
}
.events-filter__tags { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.events-empty { padding: clamp(24px, 4vw, 42px); }

.lede { font: var(--text-lede); color: var(--text-body); max-width: 58ch; }

@media (max-width: 759px) {
  .location-card__weekly-row a,
  .location-card__weekly-row span:nth-child(2) { white-space: normal; }
}

/* ── Event detail page ───────────────────────────────────────────── */
.event-hero {
  position: relative;
  background: var(--wash-boiler);
  border-bottom: var(--border-hair) solid var(--line-metal);
  overflow: hidden;
  container-type: inline-size;
}
.event-hero__grid {
  padding-block: clamp(42px, 7cqi, 96px);
  display: grid;
  /* Source order puts the flyer (order 1) ahead of the copy (order 2), so a
     single-column mobile layout shows the flyer first - the same order the
     design uses at every width. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: clamp(32px, 5cqi, 72px);
  align-items: center;
}
.event-hero__copy { order: 2; }
.event-hero__back { display: inline-flex; align-items: center; gap: 8px; color: var(--text-metal); border-bottom: 0; }
.event-hero__badges { display: flex; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-5); }
.event-hero__copy h1 {
  margin: var(--space-5) 0 var(--space-4);
  font-size: clamp(47px, 7.5cqi, 88px);
  line-height: 0.96;
  max-width: 12ch;
  color: var(--paper-100);
}
.event-hero__when {
  display: flex;
  gap: var(--space-6);
  flex-wrap: wrap;
  font: var(--text-meter);
  font-size: var(--size-body-lg);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--brass-300);
}
.event-hero__lede { margin-top: var(--space-5); font: var(--text-lede); color: var(--text-hi); max-width: 46ch; }
.event-hero__ctas { display: flex; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-6); }
.event-hero__next { margin-top: var(--space-5); color: var(--text-muted); }
.event-hero__next span { color: var(--text-hi); }

.event-hero__flyer {
  order: 1;
  position: relative;
  aspect-ratio: 4 / 5;
  width: 100%;
  max-width: 420px;
  justify-self: center;
  background: var(--ink-900);
  border: var(--border-hair) solid var(--line-metal-strong);
  border-radius: var(--radius-plate);
  box-shadow: var(--shadow-raised);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
}
.event-hero__flyer img { width: 100%; height: 100%; object-fit: cover; }
.event-hero__placeholder {
  position: relative;
  padding: var(--space-5);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--brass-300);
  display: flex;
  align-items: center;
  gap: 8px;
}

.event-about {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr));
  gap: clamp(32px, 5cqi, 72px);
  align-items: start;
}

.host {
  display: flex;
  gap: var(--space-5);
  align-items: center;
  flex-wrap: wrap;
  margin-top: var(--space-6);
  padding: var(--space-5);
}
.host__mark {
  width: 56px;
  height: 56px;
  flex: none;
  background: var(--wash-ember);
  border: var(--border-hairline);
  border-radius: var(--radius-plate);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--brass-300);
}
.host > div { flex: 1; min-width: 200px; }
.host p { margin: var(--space-2) 0 0; font: var(--text-copy-sm); color: var(--text-body); }

.ticket { clip-path: var(--clip-ticket); }
.ticket__head {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: var(--border-paper);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--copper-600);
}
.ticket__facts { margin: 0; padding: var(--space-6); display: grid; gap: var(--space-5); }
.ticket__fact { display: flex; gap: var(--space-4); }
.ticket__n { font: var(--text-meter); color: var(--copper-600); width: 24px; flex: none; }
.ticket__fact dt { font-family: var(--font-display); font-size: var(--size-body-lg); text-transform: uppercase; color: var(--ink-900); line-height: 1.1; margin: 0; }
.ticket__fact dd { font: var(--text-copy-sm); color: var(--ink-800); margin: 4px 0 0; }
.ticket__foot { padding: var(--space-4) var(--space-6); border-top: var(--border-paper); font: var(--text-label); color: var(--text-inverse-muted); }

.gallery-head { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-6); flex-wrap: wrap; }
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
  grid-auto-flow: dense;
  gap: var(--space-4);
  margin-top: var(--space-8);
}
.gallery__item {
  margin: 0;
  position: relative;
  aspect-ratio: 1;
  background: var(--wash-boiler);
  border: var(--border-hairline);
  border-radius: var(--radius-card);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
}
.gallery__item--wide { grid-column: span 2; aspect-ratio: 16 / 9; }
.gallery__item:nth-of-type(3n+2) { background: var(--wash-ember); }
.gallery__item:nth-of-type(3n+3) { background: var(--ink-800); }
.gallery__item img { width: 100%; height: 100%; object-fit: cover; }

.other-nights-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: var(--space-5);
  margin-top: var(--space-7);
}
.other-night {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-5);
}
.other-night__meta { display: block; }
.other-night__name {
  display: block;
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--size-title-sm);
  line-height: 1.08;
  text-transform: uppercase;
}

/* ── Locations page: anchors ──────────────────────────────────────
   Task 13's `.location-card { scroll-margin-top: ... }` lived here, to keep the
   sticky header off /locations/#stuart and #psl. It is gone: base.css now sets
   `scroll-padding-top` on `html`, which solves the same problem for every
   anchor and every focus scroll on the site at once (whole-branch review,
   finding I7). Keeping both would have added the two offsets together and
   parked each card well below the header. */

/* ── App page: hero ────────────────────────────────────────────────
   Ported from the design's "Get the App.dc.html". */
.app-hero {
  position: relative;
  background: var(--wash-ember);
  border-bottom: var(--border-hair) solid var(--line-metal);
  overflow: hidden;
  container-type: inline-size;
}
.app-hero__inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: clamp(32px, 5cqi, 72px);
  align-items: center;
  padding-block: clamp(56px, 9cqi, 112px);
}
.app-hero__title {
  margin: var(--space-5) 0;
  font-size: clamp(47px, 8cqi, 96px);
  line-height: 0.96;
  letter-spacing: var(--tracking-mega);
  color: var(--paper-100);
  max-width: 12ch;
  text-transform: uppercase;
}
.app-hero__lede { font: var(--text-lede); color: var(--text-hi); max-width: 46ch; }
.app-hero__copy { font: var(--text-copy); color: var(--text-body); max-width: 50ch; }
.app-hero__ctas { display: flex; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-6); align-items: center; }
.app-hero__phone-wrap { display: flex; justify-content: center; }

/* The phone mockup frames a real app screenshot. The design's two install-card
   screenshot slots are left out until real captures exist. */
.phone-mock {
  position: relative;
  width: 100%;
  max-width: 300px;
  aspect-ratio: 9 / 18.5;
  background: var(--ink-900);
  border: var(--border-plate) solid var(--line-metal-strong);
  border-radius: 22px;
  box-shadow: var(--shadow-raised);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.phone-mock__notch { height: 28px; display: flex; justify-content: center; align-items: flex-start; padding-top: 8px; }
.phone-mock__notch span { display: block; width: 80px; height: 6px; border-radius: 999px; background: var(--ink-600); }
.phone-mock__screen {
  flex: 1;
  margin: 8px;
  background: var(--wash-boiler);
  border: var(--border-hairline);
  border-radius: var(--radius-card);
  overflow: hidden;
  position: relative;
  display: flex;
  flex-direction: column;
}
/* The screenshot fills the screen and anchors to the top, so a mock narrower
   than the capture trims the bottom of the schedule, never the header. */
.phone-mock__shot { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.phone-mock__screen picture { flex: 1; min-height: 0; display: block; }

/* ── App page: how it works ───────────────────────────────────────── */
.app-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: var(--space-5);
  margin-top: var(--space-8);
}
.step-card { padding: var(--space-6); }
.step-card__head { display: flex; align-items: center; gap: var(--space-3); color: var(--brass-400); }
.step-card__num { font: var(--text-eyebrow); letter-spacing: var(--tracking-label); }
.step-card h3 { margin: var(--space-4) 0 var(--space-3); font-size: var(--size-title-sm); }
.step-card p { font: var(--text-copy-sm); color: var(--text-muted); margin: 0; }

/* ── App page: install cards ──────────────────────────────────────── */
.install-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr));
  gap: var(--space-6);
  margin-top: var(--space-8);
}
.install-card { overflow: hidden; }
.install-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  border-bottom: var(--border-hairline);
  font: var(--text-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--text-metal);
}
.install-card__head span:first-child { display: flex; align-items: center; gap: 8px; }
.install-card__steps { padding: var(--space-6); display: grid; gap: var(--space-5); }
.install-card__step { display: flex; gap: var(--space-4); }
.install-card__num { font: var(--text-meter); color: var(--brass-400); width: 24px; flex: none; }
.install-card__step span:last-child { font: var(--text-copy); color: var(--text-body); }

/* ── App page: FAQ ─────────────────────────────────────────────────── */
.faq-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: var(--space-5);
  margin-top: var(--space-7);
}
.faq-card { padding: var(--space-6); }
.faq-card h3 { font-size: var(--size-title-sm); }
.faq-card p { margin: var(--space-3) 0 0; font: var(--text-copy-sm); color: var(--text-muted); }

/* ── App page: closing CTA ────────────────────────────────────────── */
.closing-cta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-6);
  flex-wrap: wrap;
  padding: clamp(24px, 4cqi, 42px);
}
.closing-cta h3 { margin: var(--space-3) 0 0; font-size: clamp(23px, 3.4cqi, 37px); }

/* ── 404 page ─────────────────────────────────────────────────────── */
.error-page {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-4);
  padding-block: clamp(24px, 6vw, 64px);
  max-width: 60ch;
}
.error-page h1 { margin: 0; font-size: clamp(33px, 5.2cqi, 52px); }
.error-page__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-4);
}

