/* Carenetic design system
   Foundations, chrome and shared components. One file, one place to change a value.
   Composition that exists on a single page stays in that page. */

/* @font-face: generated from assets/fonts/fonts.css by scripts/perf/fetch-fonts.mjs --sync-css. Do not edit. */
/* Self-hosted copies of the Google Fonts Archivo + Newsreader variable fonts.
   Generated by scripts/perf/fetch-fonts.mjs from:
   https://fonts.googleapis.com/css2?family=Archivo:ital,wdth,wght@0,62..125,100..900;1,62..125,100..900&family=Newsreader:ital,opsz,wght@0,6..72,300..700;1,6..72,300..700&display=swap
   Axis ranges trimmed by scripts/perf/instance-fonts.py (descriptors left as published).
   Do not edit by hand; re-run both scripts. */
/* Archivo italic vietnamese (from archivo/v25/k3kSo8UDI-1M0wlSfdzYI2HEEaM.woff2) */
@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(/assets/fonts/archivo-italic-vietnamese.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;
}
/* Archivo italic latin-ext (from archivo/v25/k3kSo8UDI-1M0wlSfdzYImHEEaM.woff2) */
@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(/assets/fonts/archivo-italic-latin-ext.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;
}
/* Archivo italic latin (from archivo/v25/k3kSo8UDI-1M0wlSfdzYLGHE.woff2) */
@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(/assets/fonts/archivo-italic-latin.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;
}
/* Archivo normal vietnamese (from archivo/v25/k3kQo8UDI-1M0wlSfdboLnnA.woff2) */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(/assets/fonts/archivo-normal-vietnamese.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;
}
/* Archivo normal latin-ext (from archivo/v25/k3kQo8UDI-1M0wlSfdfoLnnA.woff2) */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(/assets/fonts/archivo-normal-latin-ext.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;
}
/* Archivo normal latin (from archivo/v25/k3kQo8UDI-1M0wlSfdnoLg.woff2) */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(/assets/fonts/archivo-normal-latin.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;
}
/* Newsreader italic vietnamese (from newsreader/v26/cY9CfjOCX1hbuyalUrK439vCgYhCFpY.woff2) */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url(/assets/fonts/newsreader-italic-vietnamese.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;
}
/* Newsreader italic latin-ext (from newsreader/v26/cY9CfjOCX1hbuyalUrK439vCgIhCFpY.woff2) */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url(/assets/fonts/newsreader-italic-latin-ext.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;
}
/* Newsreader italic latin (from newsreader/v26/cY9CfjOCX1hbuyalUrK439vCjohC.woff2) */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url(/assets/fonts/newsreader-italic-latin.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;
}
/* Newsreader normal vietnamese (from newsreader/v26/cY9AfjOCX1hbuyalUrK439HyjJBG.woff2) */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(/assets/fonts/newsreader-normal-vietnamese.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;
}
/* Newsreader normal latin-ext (from newsreader/v26/cY9AfjOCX1hbuyalUrK439DyjJBG.woff2) */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(/assets/fonts/newsreader-normal-latin-ext.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;
}
/* Newsreader normal latin (from newsreader/v26/cY9AfjOCX1hbuyalUrK4397yjA.woff2) */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(/assets/fonts/newsreader-normal-latin.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: end */

/* Metric-matched fallbacks: a local font scaled so text runs the width of the web font, so the
   swap when Archivo and Newsreader arrive does not rewrap a line or move anything below it.
   Measured against the site's own copy; the method is at the top of the script. */
/* @font-face fallbacks: generated by scripts/perf/font-fallbacks.mjs --write. Do not edit. */
@font-face { font-family: "Archivo Fallback"; font-style: normal; font-weight: 100 500; src: local("Arial"), local("ArialMT"); size-adjust: 98.41%; ascent-override: 89.22%; descent-override: 21.34%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Archivo Fallback"; font-style: normal; font-weight: 501 650; src: local("Arial Bold"), local("Arial-BoldMT"); size-adjust: 95.64%; ascent-override: 91.80%; descent-override: 21.96%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Archivo Fallback"; font-style: normal; font-weight: 651 900; src: local("Arial Bold"), local("Arial-BoldMT"); size-adjust: 98.75%; ascent-override: 88.91%; descent-override: 21.27%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Archivo Fallback"; font-style: italic; font-weight: 100 900; src: local("Arial Italic"), local("Arial-ItalicMT"); size-adjust: 98.78%; ascent-override: 88.89%; descent-override: 21.26%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Archivo Fallback"; font-style: normal; font-weight: 100 500; font-stretch: 101% 125%; src: local("Arial"), local("ArialMT"); size-adjust: 98.41%; ascent-override: 89.22%; descent-override: 21.34%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Archivo Fallback"; font-style: normal; font-weight: 501 900; font-stretch: 101% 125%; src: local("Arial Bold"), local("Arial-BoldMT"); size-adjust: 104.53%; ascent-override: 84.00%; descent-override: 20.09%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Archivo Fallback Roboto"; font-style: normal; font-weight: 100 900; src: local("Roboto"), local("Roboto-Regular"); size-adjust: 98.63%; ascent-override: 89.02%; descent-override: 21.29%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Newsreader Fallback"; font-style: normal; font-weight: 300 450; src: local("Georgia"); size-adjust: 91.12%; ascent-override: 80.67%; descent-override: 29.08%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Newsreader Fallback"; font-style: normal; font-weight: 451 700; src: local("Georgia"); size-adjust: 91.88%; ascent-override: 80.00%; descent-override: 28.84%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Newsreader Fallback"; font-style: italic; font-weight: 300 700; src: local("Georgia Italic"), local("Georgia-Italic"); size-adjust: 83.20%; ascent-override: 88.34%; descent-override: 31.85%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Newsreader Fallback Noto"; font-style: normal; font-weight: 300 450; src: local("Noto Serif"), local("NotoSerif-Regular"); size-adjust: 84.45%; ascent-override: 87.03%; descent-override: 31.38%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Newsreader Fallback Noto"; font-style: normal; font-weight: 451 700; src: local("Noto Serif"), local("NotoSerif-Regular"); size-adjust: 85.15%; ascent-override: 86.31%; descent-override: 31.12%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Newsreader Display Fallback"; font-style: normal; font-weight: 300 700; src: local("Georgia"); size-adjust: 92.94%; ascent-override: 79.09%; descent-override: 28.51%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Newsreader Display Fallback Large"; font-style: normal; font-weight: 300 700; src: local("Georgia"); size-adjust: 95.77%; ascent-override: 76.75%; descent-override: 27.67%; line-gap-override: 0%; 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, U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, 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, U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
/* @font-face fallbacks: end */

:root {
  --ground: #FCFCFB;
  --ground-alt: #F3F3F1;
  --raised: #FFFFFF;
  --sunk: #EEEEEB;
  --surface-dark: #1A1A35;
  --surface-dark-2: #232345;
  --border-dark: #31315A;
  --text: #000000;
  --text-dim: #4E4F66;
  --text-faint: #696A82;
  /* Labels and captions on dark, at 7:1 (WCAG AAA) on --surface-dark-2 and 7.9:1 on
     --surface-dark. Graphics and strokes on dark keep the quieter step below, which
     is not text and was never read. */
  --text-invert-dim: #ADB0CC;
  --graphic-invert-dim: #8E92B4;
  --text-invert: #C6C9E0;
  --peri-300: #7C9BE0;
  --peri-500: #4A76D2;
  --peri-600: #3A5FB5;
  --peri-700: #2F4C93;
  --peri-wash: #EEF1FB;
  --card-hover: #E8EDFB;
  --card-hover-val: #FBE6E1;
  --val-500: #E54C39;
  /* The brand orange, darkened just enough for a white 16px label: 4.52:1. */
  /* The page action's fill and the closing CTA's card: the brand orange darkened only as
     far as white 16px type needs for AA, 4.52:1 (Miles, 2026-09-26: a 7:1 red was too far
     from the brand). --val-700 is its hover. */
  --val-600: #D83E2D;
  --val-700: #A93122;
  /* Orange text on light grounds. The brand orange is 3.3-3.9:1 on them; this is the lightest
     step of its hue that clears 4.5:1 on every one, the card hover tints included. */
  --val-ink: #CA2F20;
  --val-tint: #FCEDE9;
  /* Done. Status only: a resolved ticket, never a link, button or accent. */
  --ok-ink: #1B7348;
  --ok-tint: #E6F4EC;
  --line: rgba(0,0,0,0.10);
  --sev-crit: #E9503C;
  --sev-high: #E9A13B;
  --sev-med: #7C9BE0;
  --sev-low: #8E92B4;
  --line-2: rgba(0,0,0,0.16);
  /* Form-control borders only. --line-2 is 1.45:1 against the page, and a control's
     boundary needs 3:1 (WCAG 2.2 1.4.11). Dividers keep --line-2: they are decoration,
     and 1.4.11 does not apply to them. */
  --field-line: #86879C;
  --radius: 4px;
  --ease-settle: cubic-bezier(.4, 0, 0, 1);
  --shadow-card: 0 1px 0 rgba(0,0,0,0.05), 0 14px 34px rgba(0,0,0,0.06);
  /* A link card lifted under the pointer or focus. */
  --shadow-lift: 0 24px 44px rgba(26,26,53,0.13);
  --measure: 620px;
  --disp: "Archivo", "Archivo Fallback", "Archivo Fallback Roboto", system-ui, sans-serif;
  --serif: "Newsreader", "Newsreader Fallback", "Newsreader Fallback Noto", Georgia, serif;
  --serif-display: "Newsreader", "Newsreader Display Fallback", "Newsreader Fallback Noto", Georgia, serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --measure-display: 860px;
  --sev-crit-ink: #ED6C5B;
  --sev-low-ink: #9EA2C2;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: auto; -webkit-text-size-adjust: 100%; }
body {
    font-family: var(--disp);
    background: var(--ground);
    color: var(--text);
    font-size: 17px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }
.wrap { max-width: 1120px; margin: 0 auto; padding: 0 44px; }
.display {
    font-family: var(--serif-display);
    font-optical-sizing: auto;
    font-weight: 500;
    font-size: 55px;
    line-height: 1.07;
    letter-spacing: -0.011em;
    color: var(--text);
  }
/* Newsreader's optical sizing draws display wider than the headings, and wider again at 55px
   above 900px, so display takes its own fallback, scaled for each size. */
@media (min-width: 901px) { :root { --serif-display: "Newsreader", "Newsreader Display Fallback Large", "Newsreader Fallback Noto", Georgia, serif; } }
.h2 {
    font-family: var(--serif);
    font-optical-sizing: auto;
    font-weight: 500;
    font-size: 37px;
    line-height: 1.14;
    letter-spacing: -0.008em;
    color: var(--text);
    max-width: var(--measure);
  }
.h3 {
    font-stretch: 108%;
    font-weight: 600;
    font-size: 20px;
    line-height: 1.3;
    letter-spacing: -0.003em;
    color: var(--text);
  }
.tone { color: var(--peri-600); }
.on-dark .display, .on-dark .h2, .on-dark .h3 { color: #fff; }
.on-dark .tone { color: var(--peri-300); }
.sub { font-size: 19px; line-height: 1.6; color: var(--text-dim); }
.on-dark .sub { color: var(--text-invert); }
.on-dark .body-copy, .on-dark .lede { color: var(--text-invert); }
.on-dark .body-copy strong { color: #fff; }
.body-copy { font-size: 17px; line-height: 1.66; color: var(--text-dim); }
.body-copy strong { color: var(--text); font-weight: 700; }
.lede { font-size: 18px; line-height: 1.6; color: var(--text-dim); max-width: var(--measure); }
.on-dark .eyebrow { color: var(--peri-300); }
.on-dark .eyebrow::before { background: var(--peri-300); }
/* The text link. Two lines drawn as backgrounds rather than a text-decoration: a
   faint one the full width at rest, and one in the link's own colour that grows
   over it on hover from the side the pointer came in, and withdraws toward the
   side it left, on the buttons' curve. Both sit 2px into the bottom padding,
   measured from the content box, so a link given more padding for its tap
   target keeps the line in the same place. carenetic.js sets --ux; with no
   script the line grows from the left. */
a.textlink {
    color: var(--val-ink);
    --tl-rest: rgba(202,47,32,0.35);
    text-decoration: none;
    font-weight: 600;
    padding-bottom: 2px;
    background-image: linear-gradient(currentColor, currentColor), linear-gradient(var(--tl-rest), var(--tl-rest));
    background-size: 0 1.5px, 100% 1.5px;
    background-position: var(--ux, left) calc(100% + 2px), left calc(100% + 2px);
    background-repeat: no-repeat;
    background-origin: content-box; background-clip: padding-box;
    transition: background-size .3s ease-in-out;
  }
a.textlink:hover, a.textlink:focus-visible { background-size: 100% 1.5px, 100% 1.5px; }
.on-dark a.textlink { color: var(--peri-300); --tl-rest: rgba(124,155,224,0.4); }
.btn {
    display: inline-block;
    font-family: var(--disp);
    font-stretch: 100%;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: 0.005em;
    padding: 14px 30px;
    border-radius: var(--radius);
    text-decoration: none;
    color: #fff;
    background: var(--val-600);
    /* A <button> brings the browser's border and arrow cursor; a link brings neither. */
    border: 0; cursor: pointer;
    /* The hover. A diamond in the deeper shade, the shape of the mark, grows out of
       the point where the pointer came in until it covers the button, and shrinks
       back to the point where it left. It is a pseudo-element the button clips,
       under the label (isolation plus the negative z-index), and it animates on
       transform only, so the work stays on the compositor. With no script it grows
       from the centre; carenetic.js sets --fx, --fy and --fd so it grows from the
       pointer instead. Keyboard focus fills it from the centre. */
    position: relative; overflow: hidden; isolation: isolate;
    transition: background .18s ease;
  }
.btn::before {
    content: ""; position: absolute; left: var(--fx, 50%); top: var(--fy, 50%);
    width: var(--fd, 640px); height: var(--fd, 640px); z-index: -1; pointer-events: none;
    background: var(--val-700);
    transform: translate(-50%, -50%) rotate(45deg) scale(0);
    transition: transform .4s ease-in-out;
  }
.btn:hover::before, .btn:focus-visible::before { transform: translate(-50%, -50%) rotate(45deg) scale(1); }
.cta-zone { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.after-btn { margin-top: 0; font-size: 16px; color: var(--text-dim); }
.on-dark .after-btn { color: var(--text-invert); }
.note { margin-top: 26px; font-size: 15px; line-height: 1.55; color: var(--text-faint); }
.on-dark .note { color: var(--text-invert-dim); }
.slab {
    padding: 4px 0 0;
    position: relative;
  }
.slab-num {
    font-stretch: 112%; font-weight: 600;
    font-size: 60px; line-height: 1; letter-spacing: -0.02em;
    color: var(--text); font-variant-numeric: tabular-nums;
  }
.slab-num .unit { font-size: 26px; color: var(--peri-600); font-weight: 600; letter-spacing: 0; vertical-align: middle; }
.slab-lead .slab-num { font-size: 60px; }
.slab-label { margin-top: 12px; font-size: 15px; line-height: 1.4; color: var(--text-dim); }
/* The ledger slab: each figure ranged left on a hairline, a 44px periwinkle tick where
   the line starts. With .draw-x on the grid (and SlabCountUp on the page) the lines draw
   in left to right, one figure after another, and each tick follows its line. It rules
   whatever the container's children are, so a list of rows (the homepage questions)
   takes it as readily as a row of figures. */
.slab-ledger > * { position: relative; text-align: left; padding-top: 26px; }
.slab-ledger > *::after, .slab-ledger > *::before {
    content: ""; position: absolute; left: 0; transform-origin: left;
  }
.slab-ledger > *::after { right: 0; top: 0; height: 1px; background: var(--line-2); }
.slab-ledger > *::before { top: -1px; width: 44px; height: 3px; background: var(--peri-500); z-index: 1; }
.slab-ledger > *:nth-child(2) { --draw-d: .15s; }
.slab-ledger > *:nth-child(3) { --draw-d: .3s; }
.slab-ledger > *:nth-child(4) { --draw-d: .45s; }
.slab-ledger > *:nth-child(5) { --draw-d: .6s; }
.slab-ledger > *:nth-child(n+6) { --draw-d: .75s; }
html.motion .slab-ledger.draw-x > *::after, html.motion .slab-ledger.draw-x > *::before { transform: scaleX(0); }
html.motion .slab-ledger.draw-x.drawn > *::after {
    transform: scaleX(1); transition: transform .9s var(--ease-settle) var(--draw-d, 0s);
  }
html.motion .slab-ledger.draw-x.drawn > *::before {
    transform: scaleX(1); transition: transform .5s var(--ease-settle) calc(var(--draw-d, 0s) + .45s);
  }
@media (prefers-reduced-motion: reduce) {
  html.motion .slab-ledger.draw-x > *::after, html.motion .slab-ledger.draw-x > *::before { transform: none; }
}
/* On dark the hairline is --border-dark; the tick stays --peri-500. */
.on-dark .slab-ledger > *::after, .cs-dark .slab-ledger > *::after { background: var(--border-dark); }
/* Rows on the ledger take its rule in place of their plain divider. */
.slab-ledger > .faq-item + .faq-item { border-top: 0; }
/* ─── FAQ row ───────────────────────────────────────────────────────────────
   The house pattern (kit: FAQ): the question on the short column and the answer beside it,
   one to two, 44px apart, the question in the serif at 21px (19px below 900). Extracted from
   the Website Support page on 2026-09-28 for About; the service pages, Contact and the
   homepage still declare the same rules inline until that refactor reaches them. */
.faq-item { display: grid; grid-template-columns: 1fr 2fr; gap: 44px; padding: 26px 0; }
.faq-q {
    font-family: var(--serif); font-optical-sizing: auto;
    font-weight: 500; font-size: 21px; line-height: 1.28; letter-spacing: -0.004em; color: var(--text);
  }
.faq-a { font-size: 16px; line-height: 1.66; color: var(--text-dim); }
@media (max-width: 900px) {
  .faq-item { grid-template-columns: 1fr; gap: 10px; }
  .faq-q { font-size: 19px; }
}
.skip-link {
    position: absolute; top: -100%; left: 16px; z-index: 200;
    background: var(--surface-dark); color: #fff; padding: 10px 18px;
    border-radius: var(--radius); text-decoration: none; font-weight: 600;
  }
.skip-link:focus { top: 12px; }
a:focus-visible, button:focus-visible {
    outline: 3px solid var(--peri-500); outline-offset: 3px; border-radius: 3px;
  }
.on-dark a:focus-visible { outline-color: var(--peri-300); }
/* Scroll boxes (wide tables) take focus so a keyboard can scroll them; they show the same ring. */
[tabindex="0"]:focus-visible { outline: 3px solid var(--peri-500); outline-offset: 3px; }
/* The drawer is a white panel inside the dark header, so its links take the light ring:
   --peri-300 is 2.8:1 on white, under the 3:1 a focus indicator needs. */
@media (max-width: 900px) { .on-dark .nav-links > a:focus-visible { outline-color: var(--peri-500); } }
.rv, .rv-child { opacity: 1; }
html.reveal .rv, html.reveal .rv-child { opacity: 0; transform: translateY(6px); will-change: opacity, transform; }
html.reveal .rv.in, html.reveal .rv-child.in {
    opacity: 1; transform: none;
    transition: opacity .26s var(--ease-settle) var(--rvd,0ms),
                transform .26s var(--ease-settle) var(--rvd,0ms);
  }
html.reveal .rule-el::before { transform: scaleX(0); }
html.reveal .rule-el.in::before { transform: scaleX(1); transition: transform .3s ease .08s; }
.site-nav { background: var(--surface-dark); position: relative; z-index: 50; }
.site-nav .wrap {
    display: flex; align-items: center; justify-content: space-between;
    padding: 22px 44px; position: relative;
  }
.nav-logo { height: 35px; width: auto; display: block; }
.nav-logo .mark { fill: var(--peri-300); }
.nav-logo .word { fill: #fff; }
.nav-links { display: flex; align-items: center; gap: 30px; align-self: stretch; margin-left: auto; }
.nav-links > a {
    color: var(--text-invert); text-decoration: none;
    font-size: 16px; font-weight: 500; letter-spacing: 0.002em;
    position: relative;
    transition: color .2s ease;
  }
/* The nav marker: a 1.5px line under the link that grows in from the side the
   pointer came in and withdraws toward the side it left, on the buttons' curve, so
   the nav answers the pointer the way the buttons do. carenetic.js sets --ux to
   left or right at each crossing; with no script it grows from the left. The line
   stays full under the current section. The current page itself is
   aria-current="page"; a page inside the section is "true". */
.nav-links > a::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -7px; height: 1.5px;
    background: var(--peri-300);
    transform: scaleX(0); transform-origin: var(--ux, left);
    transition: transform .3s ease-in-out;
  }
.nav-links > a:hover, .nav-links > a[aria-current] { color: #fff; }
.nav-links > a:hover::after, .nav-links > a:focus-visible::after, .nav-links > a[aria-current]::after { transform: scaleX(1); }
.nav-links a.btn::after { display: none; }
.nav-links a.btn { color: #fff; }
.nav-links a.btn:hover { color: #fff; }
.nav-actions { display: flex; align-items: center; gap: 14px; margin-left: 30px; }
/* In the drawer each link already carries a diamond at its left. The current
   section's turns periwinkle and its label with it; the hover marker stays off. */
@media (max-width: 900px) {
  .nav-links > a::after { display: none; }
  .nav-links > a[aria-current] { color: var(--peri-700); }
  .nav-links > a[aria-current]::before { background: var(--peri-600); }
}
.nav-toggle {
    display: none; align-items: center; justify-content: center;
    width: 44px; height: 44px; margin-right: -10px;
    background: none; border: 0; cursor: pointer;
  }
.nav-toggle .bars { position: relative; display: block; width: 22px; height: 2px; background: #fff; transition: background .18s ease; }
.nav-toggle .bars::before, .nav-toggle .bars::after {
    content: ""; position: absolute; left: 0; width: 22px; height: 2px; background: #fff;
    transition: transform .22s var(--ease-settle);
  }
.nav-toggle .bars::before { top: -7px; }
.nav-toggle .bars::after { top: 7px; }
.site-nav.open .nav-toggle .bars { background: transparent; }
.site-nav.open .nav-toggle .bars::before { transform: translateY(7px) rotate(45deg); }
.site-nav.open .nav-toggle .bars::after { transform: translateY(-7px) rotate(-45deg); }

/* ─── Nav menu ────────────────────────────────────────────────────────────────
   A primary item with a menu (Services) is three siblings in the nav: its own
   link, a disclosure button, and the panel the button controls. The link still
   goes to the section's page; the button opens the panel. Siblings rather than a
   wrapper, so the drawer rules every page carries for `.nav-links > a` style the
   parent link like the others.

   Wide: a full-width panel on --raised under the dark bar, the intro on the left
   and the section's pages as cards on the right, in the /services/ grid's order.
   It opens on click, on Enter or Space, and on mouse hover with a short intent
   delay; Escape, a click outside, or focus leaving it closes it (NavMenu.astro).
   It fades in while its content settles 6px, the Reveal travel and timing.

   Drawer: the button sits at the right of the parent row at 44 by 44 and the
   pages drop in beneath it as an indented list, names only.

   With no script the button stays hidden and the wide panel opens on hover and
   keyboard focus instead, so every page in it is still reachable. */
.nav-sub-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; margin-left: -26px; padding: 0;
    background: none; border: 0; border-radius: 3px; cursor: pointer;
    color: var(--text-invert);
    transition: color .2s ease;
  }
.nav-sub-toggle[hidden] { display: none; }
.nav-chev {
    width: 12px; height: 8px; display: block; fill: none;
    stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
    transition: transform .26s var(--ease-settle);
  }
.nav-sub-toggle[aria-expanded="true"] .nav-chev { transform: rotate(180deg); }
.nav-mega-list { list-style: none; }
/* The panel is a white ground inside the dark header, so everything in it takes
   the light-ground colours and ring, over the header's own `.nav-links` and
   `.on-dark` rules (and the copies of them some pages still carry). */
.site-nav .nav-mega a { font-size: inherit; font-weight: inherit; letter-spacing: normal; }
.site-nav .nav-mega .nav-mega-link::after, .site-nav .nav-mega .textlink::after { content: none; }
.on-dark .nav-mega a:focus-visible { outline: 3px solid var(--peri-500); outline-offset: 3px; }
.site-nav .nav-mega-link { display: block; text-decoration: none; color: var(--text); }
.site-nav .nav-mega-link:hover .nav-mega-name,
.site-nav .nav-mega-link[aria-current] .nav-mega-name { color: var(--peri-700); }
.on-dark .nav-mega a.textlink { color: var(--val-ink); --tl-rest: rgba(202,47,32,0.35); font-weight: 600; }
.nav-mega-name { display: block; font-stretch: 108%; font-weight: 600; color: var(--text); transition: color .2s ease; }

@media (min-width: 901px) {
  /* The panel runs the width of the bar, so it hangs off the header rather than the
     centred column inside it. */
  header.site-nav > .wrap { position: static; }
  .on-dark .nav-sub-toggle:focus-visible { outline-color: var(--peri-300); }
  .nav-sub-toggle:hover, .nav-sub-toggle[aria-expanded="true"] { color: #fff; }
  /* While its menu is open the parent reads as hovered: white, with its line drawn. */
  .nav-links > .nav-parent:has(+ .nav-sub-toggle[aria-expanded="true"]) { color: #fff; }
  .nav-links > .nav-parent:has(+ .nav-sub-toggle[aria-expanded="true"])::after { transform: scaleX(1); }
  .nav-mega {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 60;
    background: var(--raised);
    box-shadow: 0 26px 52px rgba(0,0,0,0.30);
    visibility: hidden; opacity: 0;
    transition: opacity .26s var(--ease-settle), visibility 0s linear .26s;
  }
  /* A strip over the bar's lower padding, so the pointer can travel from the link
     down to the panel without leaving it. Only there while the panel is open. */
  .nav-mega::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 22px; }
  .nav-mega-inner {
    max-width: 1120px; margin: 0 auto; padding: 36px 44px 42px;
    display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 48px;
    transform: translateY(-6px);
    transition: transform .26s var(--ease-settle);
  }
  .nav-mega.open,
  .site-nav:not(.menu-ready) .nav-parent:hover + .nav-sub-toggle + .nav-mega,
  .site-nav:not(.menu-ready) .nav-parent:focus + .nav-sub-toggle + .nav-mega,
  .site-nav:not(.menu-ready) .nav-mega:hover,
  .site-nav:not(.menu-ready) .nav-mega:focus-within {
    visibility: visible; opacity: 1; transition-delay: 0s;
  }
  .nav-mega.open .nav-mega-inner,
  .site-nav:not(.menu-ready) .nav-parent:hover + .nav-sub-toggle + .nav-mega .nav-mega-inner,
  .site-nav:not(.menu-ready) .nav-parent:focus + .nav-sub-toggle + .nav-mega .nav-mega-inner,
  .site-nav:not(.menu-ready) .nav-mega:hover .nav-mega-inner,
  .site-nav:not(.menu-ready) .nav-mega:focus-within .nav-mega-inner { transform: none; }
  .nav-mega-line {
    font-family: var(--serif); font-optical-sizing: auto;
    font-size: 22px; line-height: 1.32; font-weight: 500; letter-spacing: -0.004em;
    color: var(--text);
  }
  .nav-mega-intro .textlink { display: inline-block; margin-top: 18px; font-size: 15px; }
  .nav-mega-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
  .site-nav .nav-mega-link {
    height: 100%; padding: 18px 22px 20px;
    background: var(--raised); border: 1px solid var(--line-2); border-radius: var(--radius);
    transition: border-color .25s var(--ease-settle), background .25s var(--ease-settle);
  }
  .site-nav .nav-mega-link:hover, .site-nav .nav-mega-link[aria-current] { border-color: var(--peri-500); background: var(--peri-wash); }
  .nav-mega-name { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 17px; line-height: 1.3; }
  .nav-mega-go { flex: none; color: var(--peri-600); transition: transform .25s var(--ease-settle); }
  .site-nav .nav-mega-link:hover .nav-mega-go { transform: translateX(5px); }
  .nav-mega-said { display: block; margin-top: 6px; font-size: 15px; line-height: 1.45; color: var(--text-dim); }
}

@media (max-width: 900px) {
  /* The open drawer becomes a two-column grid only so the button can sit beside its
     link; every other row spans both columns and stacks as before. */
  .site-nav.open > .wrap > .nav-links { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0; }
  .nav-links > * { grid-column: 1 / -1; }
  .nav-links > .nav-parent { grid-column: 1; }
  .nav-links > .nav-sub-toggle { grid-column: 2; width: 44px; height: 44px; margin: 0; border-radius: 5px; color: var(--text); }
  .nav-links > .nav-sub-toggle:hover { color: var(--peri-700); }
  .nav-mega { display: none; }
  .nav-mega.open { display: block; }
  .nav-mega-intro, .nav-mega-go, .nav-mega-said { display: none; }
  .nav-mega-list { margin: 0 0 6px 34px; padding-left: 4px; border-left: 1px solid var(--line-2); }
  .site-nav .nav-mega-link { padding: 10px 16px 10px 14px; border-radius: 5px; }
  .nav-mega-name { font-size: 15px; line-height: 1.4; }
}
/* The header below 900: the links fold into a drawer behind the toggle, and the logo
   and "Book a call" shrink so both fit beside it at 320. Every page carried its own
   copy of these rules until 09-29, and all but the homepage and About set the button
   at 15px, which wrapped it to two lines against the logo at 320. They sit after the
   drawer's menu rules above because the page copies used to come after this sheet. */
@media (max-width: 900px) {
  .site-nav .wrap { padding: 18px 26px; }
  .site-nav .nav-logo { height: 29px; }
  .nav-toggle { display: inline-flex; }
  .nav-actions { margin-left: auto; gap: 6px; }
  .nav-actions .btn { padding: 11px 17px; font-size: 14px; white-space: nowrap; }
  .nav-links {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 70;
    display: none; align-self: auto; gap: 18px;
    background: var(--raised); border-top: 1px solid var(--line);
    box-shadow: 0 26px 52px rgba(0,0,0,0.30);
    padding: 10px 14px 18px; max-height: calc(100vh - 100%); overflow-y: auto;
  }
  .site-nav.open .nav-links { display: block; }
  .nav-links > a {
    display: block; position: relative; padding: 13px 16px 13px 34px; border-radius: 5px;
    font-stretch: 108%; font-size: 16px; font-weight: 600; color: var(--text);
  }
  .nav-links > a::before {
    content: ""; position: absolute; left: 15px; top: 20px;
    width: 8px; height: 8px; transform: rotate(45deg); background: var(--surface-dark);
  }
  .nav-links > a:hover { color: var(--peri-700); }
}
.hero { background: var(--surface-dark); padding: 76px 0 66px; position: relative; overflow: hidden; }

/* The conversion hero. The three pages that ask for something (Contact and the two
   free offers) sit the headline lower and give the form more room beneath it. */
.hero-conv { padding: 66px 0 74px; }

.hero-grid {
    display: grid; grid-template-columns: 1.15fr 0.85fr; gap: 60px;
    align-items: center; position: relative; z-index: 2;
  }
.hero .sub { margin-top: 24px; }
.hero .cta-zone { margin-top: 32px; }
.hero-photo-stage { position: relative; }
/* A photograph on a light ground, framed like the case study capture (.csf-shot): the card
   system's ground and shadow, no edge. It was the dark hero's frame, a --border-dark edge and a
   0.34 shadow, which on Careers' light top drew a navy outline and a shadow the band cut off. */
.hero-photo-slab {
    position: relative; z-index: 1; background: var(--raised);
    border-radius: var(--radius);
    overflow: hidden; box-shadow: var(--shadow-card);
  }
.hero-photo-slab img { width: 100%; height: 452px; object-fit: cover; display: block; }
/* The mark hung off the right edge of the homepage hero, behind the request queue. */
.hero-ghost {
    position: absolute; z-index: 0; pointer-events: none;
    right: -180px; top: 50%; transform: translateY(-50%);
    width: 620px; height: 620px; opacity: 0.09;
    -webkit-mask-image: linear-gradient(to bottom, #000 44%, transparent 90%);
    mask-image: linear-gradient(to bottom, #000 44%, transparent 90%);
  }
.hero-ghost path { fill: var(--peri-300); }
/* The band sat on --sunk between two other light greys and got scrolled past.
   Moved onto the dark surface, the same one .close-cta uses, so the testimonial reads as a
   deliberate stop rather than another grey step. */
.quote-band { background: var(--surface-dark); padding: 84px 0; position: relative; overflow: hidden; }
.quote-band figure { max-width: 44rem; position: relative; z-index: 2; }
.quote-band .quote-mark { width: 44px; height: 44px; margin-bottom: 22px; display: block; }
.quote-band .quote-mark path { fill: var(--peri-500); }
.quote-band .said {
    font-family: var(--serif); font-optical-sizing: auto;
    font-size: 29px; line-height: 1.4; font-style: normal; font-weight: 400;
    letter-spacing: -0.004em; color: #fff;
  }
.quote-band .quote-mark path { fill: var(--peri-300); }
.quote-band .who { margin-top: 26px; font-size: 15px; font-weight: 700; color: #fff; }
.quote-band .who span { display: block; font-weight: 500; color: var(--text-invert); margin-top: 3px; }
/* The client quote (.qb), for a quote whose client we can show: the client's logo knocked
   to white above the quote, the way every client mark is treated on dark, and the
   attribution on one ledger rule beneath it, name left and the mark right. With .draw-x
   on the figure (and SlabCountUp on the page) the rule draws in like the ledger slab. */
.quote-band.qb { padding: 88px 0; }
.quote-band.qb figure { max-width: none; }
.quote-band.qb .said { font-size: 33px; max-width: 30em; }
.qb-logo { display: block; width: 150px; max-width: 100%; height: auto; margin-bottom: 30px; filter: brightness(0) invert(1); opacity: .8; }
.qb-client {
    position: relative; margin-top: 44px; padding-top: 30px;
    display: flex; justify-content: space-between; align-items: center; gap: 22px;
  }
.qb-client::after, .qb-client::before { content: ""; position: absolute; left: 0; top: 0; transform-origin: left; }
.qb-client::after { right: 0; height: 1px; background: var(--border-dark); }
.qb-client::before { top: -1px; width: 44px; height: 3px; background: var(--peri-500); z-index: 1; }
html.motion .qb-fig.draw-x .qb-client::after, html.motion .qb-fig.draw-x .qb-client::before { transform: scaleX(0); }
html.motion .qb-fig.draw-x.drawn .qb-client::after { transform: scaleX(1); transition: transform .9s var(--ease-settle); }
html.motion .qb-fig.draw-x.drawn .qb-client::before { transform: scaleX(1); transition: transform .5s var(--ease-settle) .45s; }
@media (prefers-reduced-motion: reduce) {
  html.motion .qb-fig.draw-x .qb-client::after, html.motion .qb-fig.draw-x .qb-client::before { transform: none; }
}
.quote-band.qb .quote-mark { width: 44px; height: 44px; margin: 0; flex: none; }
.quote-band.qb .who { margin-top: 0; }
@media (max-width: 900px) {
  .quote-band.qb { padding: 64px 0; }
  .quote-band.qb .said { font-size: 29px; }
  .qb-client { margin-top: 36px; }
  .qb-logo { width: 140px; margin-bottom: 26px; }
}
@media (max-width: 560px) {
  .quote-band.qb .said { font-size: 24px; }
  .qb-client { flex-direction: column; align-items: flex-start; gap: 20px; }
}
/* ─── Case study. One content type, one shape, repeated (CaseStudy.astro, /results/) ──
   Identity (label, name, mark, one rule), the outcome as the headline, the scale, then
   the same three questions of every client, and an optional row of figures. The three
   parts and the figures stand on the ledger rule (.slab-ledger on .cs-arc and .cs-fig),
   the homepage's hairline and periwinkle tick, and draw in with .draw-x. Grounds come
   from .cs-dark / .cs-light, never from position, so reordering can't break the palette. */
.cs { padding: 74px 0 70px; }
.cs-dark { background: var(--surface-dark); }
.cs-light { background: var(--ground); }
.cs-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 20px 44px; padding-bottom: 18px; border-bottom: 1px solid var(--line-2);
  }
.cs-kicker {
    display: block; font-size: 12px; font-weight: 600; letter-spacing: 0.11em;
    text-transform: uppercase; color: var(--text-faint); margin-bottom: 9px;
  }
.cs-who { font-size: 23px; font-weight: 700; letter-spacing: -0.008em; line-height: 1.1; color: var(--text); }
.cs-mark { flex: none; }
/* Height per mark rather than one height for all: the aspect ratios are nothing alike. Full colour
   (Miles, 09-28: the marks were too faint at .66). These are the list-row heights, each in --mark-h; the
   block head runs them 1.6× (below), so the mark reads as the identity of the study rather than a footnote
   to it, and the case study on a service page 1.35× (.csf-head). */
.cs-mark img { width: auto; display: block; opacity: 1; }
.cs-mark img.m-pdp    { --mark-h: 22px; height: var(--mark-h); }
.cs-mark img.m-d365   { --mark-h: 22px; height: var(--mark-h); }
.cs-mark img.m-avp    { --mark-h: 44px; height: var(--mark-h); }
.cs-mark img.m-choice { --mark-h: 30px; height: var(--mark-h); }
.cs-mark img.m-arch   { --mark-h: 23px; height: var(--mark-h); }
.cs-mark img.m-butt   { --mark-h: 22px; height: var(--mark-h); }
.cs-mark img.m-cora   { --mark-h: 24px; height: var(--mark-h); }
.cs-mark img.m-fcc    { --mark-h: 50px; height: var(--mark-h); }
.cs-mark img.m-hrs    { --mark-h: 52px; height: var(--mark-h); }
.cs-mark img.m-medi   { --mark-h: 28px; height: var(--mark-h); }
.cs-mark img.m-trr    { --mark-h: 28px; height: var(--mark-h); }
.cs-mark img.m-lcl    { --mark-h: 28px; height: var(--mark-h); }
.cs-mark img.m-angell { --mark-h: 44px; height: var(--mark-h); }
.cs-head .cs-mark img.m-pdp    { height: 36px; }
.cs-head .cs-mark img.m-d365   { height: 36px; }
.cs-head .cs-mark img.m-avp    { height: 70px; }
.cs-head .cs-mark img.m-choice { height: 48px; }
.cs-head .cs-mark img.m-arch   { height: 37px; }
.cs-head .cs-mark img.m-butt   { height: 35px; }
.cs-head .cs-mark img.m-cora   { height: 38px; }
.cs-head .cs-mark img.m-fcc    { height: 80px; }
.cs-head .cs-mark img.m-hrs    { height: 83px; }
.cs-head .cs-mark img.m-medi   { height: 45px; }
.cs-head .cs-mark img.m-trr    { height: 45px; }
.cs-head .cs-mark img.m-lcl    { height: 45px; }
.cs-head .cs-mark img.m-angell { height: 70px; }
.cs-out {
    font-family: var(--serif); font-optical-sizing: auto; font-weight: 500;
    font-size: 34px; line-height: 1.14; letter-spacing: -.01em;
    color: var(--text); max-width: var(--measure); margin-top: 30px;
  }
.cs-scale { margin-top: 13px; font-size: 18px; line-height: 1.6; color: var(--text-dim); max-width: var(--measure); }
.cs-arc { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 40px; margin-top: 40px; }
.cs-arc.slab-ledger > .cs-mv { padding-top: 24px; }
.cs-mv dt { font-size: 14px; font-weight: 600; letter-spacing: .005em; line-height: 1.45; color: var(--peri-600); }
.cs-mv dd { margin: 10px 0 0; font-size: 17px; line-height: 1.6; color: var(--text-dim); }
/* Figures sit in the questions' three-column grid, so each lines up under a question. */
.cs-fig { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 40px; margin-top: 44px; }
.cs-fig .n { font-size: 44px; font-weight: 600; letter-spacing: -.025em; line-height: 1; color: var(--text); font-variant-numeric: tabular-nums; }
.cs-fig .n .u { font-size: 19px; letter-spacing: 0; color: var(--peri-600); }
.cs-fig .c { margin-top: 8px; font-size: 15px; line-height: 1.4; color: var(--text-dim); max-width: 16em; }
.cs-dark .cs-head { border-bottom-color: var(--border-dark); }
.cs-dark .cs-kicker { color: var(--text-invert-dim); }
.cs-dark .cs-who, .cs-dark .cs-out, .cs-dark .cs-fig .n { color: #fff; }
.cs-dark .cs-scale, .cs-dark .cs-mv dd, .cs-dark .cs-fig .c { color: var(--text-invert); }
.cs-dark .cs-mv dt, .cs-dark .cs-fig .n .u { color: var(--peri-300); }
/* Dark art on a transparent background disappears on this ground, so it is knocked to flat white. */
.cs-dark .cs-mark img { filter: brightness(0) invert(1); opacity: .95; }
/* The link from a block on /results/ to the study's own page: the block's last row, on the ledger
   rule like the rows above it, right-aligned at 17px so it isn't lost under the figures. */
.cs-open { margin-top: 36px; }
.cs-open > div { display: flex; justify-content: flex-end; }
.cs-open a { font-size: 17px; padding: 4px 0; }
/* Links into a case study are periwinkle on every ground (Miles, 09-28: the same link switching
   between orange and blue down the page read as two things). --peri-600 on the light grounds
   (5.9:1 on --ground, 5.5:1 on --ground-alt), --peri-300 on the dark block (6.2:1). The orange
   text link can't do this: 4.4:1 on --surface-dark. Orange stays the button's. */
.cs-open a.textlink, a.cs-row-link { color: var(--peri-600); --tl-rest: rgba(58,95,181,0.35); }
.cs-dark .cs-open a.textlink { color: var(--peri-300); --tl-rest: rgba(124,155,224,0.4); }
.cs-dark a.textlink { color: var(--peri-300); --tl-rest: rgba(124,155,224,0.4); }

/* Case study list (CaseStudyList.astro): the studies not shown in full, one row each on the ledger
   rule. The mark left at its .cs-mark height, the client, the outcome as the link to the study's own
   page, and the scale line under it. Stacks below 640. */
.cs-list { list-style: none; margin: 0; padding: 0; }
.cs-list > li { display: grid; grid-template-columns: 150px minmax(0, 1fr) auto; gap: 0 40px; align-items: start; padding-bottom: 30px; }
/* The row's own link, beside the text on the right and centred on it; below 640 it drops under the scale line. */
.cs-row-link { align-self: center; justify-self: end; font-size: 16px; padding: 4px 0; white-space: nowrap; }
.cs-list .cs-mark { padding-top: 6px; }
.cs-row-who { font-size: 15px; font-weight: 700; letter-spacing: -0.005em; line-height: 1.2; color: var(--text); }
.cs-row-out { margin-top: 8px; font-family: var(--serif); font-optical-sizing: auto; font-weight: 500; font-size: 24px; line-height: 1.2; letter-spacing: -0.005em; }
.cs-row-out a { color: var(--text); text-decoration: none; }
.cs-row-out a:hover, .cs-row-out a:focus-visible { color: var(--peri-700); text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1.5px; }
.cs-row-scale { margin-top: 8px; font-size: 16px; line-height: 1.55; color: var(--text-dim); max-width: var(--measure); }
@media (max-width: 640px) {
  .cs-list > li { grid-template-columns: 1fr; gap: 10px 0; }
  .cs-row-link { justify-self: start; margin-top: 2px; }
}
@media (max-width: 980px) {
  .cs-out { font-size: 27px; }
  /* Stacked, each part is a row on its own ledger rule. */
  .cs-arc { grid-template-columns: 1fr; gap: 0; }
  .cs-mv + .cs-mv { margin-top: 26px; }
  /* The mark goes above the name: sharing the row leaves too little width for a long name.
     Column-reverse keeps the mark first in the reading order it already had. */
  .cs-head { flex-direction: column-reverse; align-items: flex-start; gap: 14px; }
  .cs-fig { grid-template-columns: 1fr 1fr; gap: 0 26px; margin-top: 36px; }
  .cs-fig .n { font-size: 36px; }
}
/* ─── Case study on a service page ─────────────────────────────────────────────
   CaseStudyFeature.astro, one per service page and the same on each (Miles, 09-29, after
   Enterprise WordPress): a light band, the capture of the client's live site on the left as a
   statement card (--raised on the card shadow, no border; it links for a pointer only, the
   text link is the target), and the copy column on the right: the client's mark at 1.35× its
   list height, the Results label, the heading, the page's story, "Read the full case study"
   and the live site, then the study's figures on the ledger. The band takes --ground, or
   --ground-alt with .csf-alt, whichever its neighbours don't. Stacks at 900 with the copy
   first. Where it stops working: a study with no figures ends on its links, and a capture
   that isn't the 1232x1490 portrait the others are will change the band's height. */
.csf { padding: 88px 0; background: var(--ground); }
.csf-alt { background: var(--ground-alt); }
.csf-grid { display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(320px, .92fr); gap: 78px; align-items: center; }
.csf-shot { margin: 0; }
.csf-shot a { display: block; overflow: hidden; border-radius: var(--radius); background: var(--raised); box-shadow: var(--shadow-card); }
.csf-shot img { display: block; width: 100%; height: auto; }
.csf-shot figcaption { margin-top: 14px; color: var(--text-dim); font-size: 13px; line-height: 1.5; }
.csf-head .cs-mark { margin-bottom: 22px; }
.csf-head .cs-mark img { height: calc(var(--mark-h) * 1.35); }
.csf-head .cs-kicker { margin-bottom: 12px; }
.csf-head .h2 { max-width: var(--measure); text-wrap: balance; }
.csf-copy .body-copy { margin-top: 22px; }
.csf-copy .body-copy + .body-copy { margin-top: 15px; }
.csf-link { margin-top: 24px; }
.csf-link + .csf-link { margin-top: 8px; }
.csf-link .textlink { display: inline-block; padding: 3px 0; }
/* Two figures on the ledger, at the smaller size the column needs. */
.csf-figs { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin-top: 42px; }
.csf-figs .slab-num { font-size: 40px; }
.csf-figs .slab-num .unit { font-size: 20px; }
.csf-figs .slab-label { margin-top: 10px; font-size: 14px; }
@media (max-width: 1000px) {
  .csf-grid { gap: 52px; }
}
@media (max-width: 900px) {
  .csf { padding: 70px 0 66px; }
  .csf-grid { grid-template-columns: 1fr; gap: 38px; }
  /* Stacked, the copy keeps the reading measure and the capture stops short of the full width. */
  .csf-copy { max-width: var(--measure); }
  .csf-shot { order: 2; max-width: 560px; }
}
/* ─── Closing CTA. The band above the footer, written by ClosingCta.astro ─────────
   Miles chose it on 2026-09-24 from options explored on the homepage, and made it
   full width on 2026-09-29: an orange band edge to edge, a few loose diamonds in its
   padding, the copy left and the button stacked over one text link on the right, as
   wide as each other.

   The band is --val-600 because white type needs it: 4.52:1 there, 3.87:1 on --val-500.
   No blue reaches even the 3:1 large-text floor on either orange, so the heading accent
   is navy (3.74:1 at 32px). The button is the periwinkle one, since a --val-600 button
   would vanish into the band: the one place in a page that takes it.

   The diamonds live only in the padding: the scatter is masked 10px short of the copy,
   so one that drifts toward it on scroll slips out of sight at that edge. */
.close-cta { --pad: 76px; background: var(--val-600); padding: var(--pad) 0; position: relative; overflow: hidden; }
.close-cta > .wrap { position: relative; z-index: 1; }
.close-cta .dm-scatter {
    --edge: calc(var(--pad) - 10px);
    mask-image: linear-gradient(#000 var(--edge), transparent var(--edge), transparent calc(100% - var(--edge)), #000 calc(100% - var(--edge)));
  }
/* ─── Diamond list ──────────────────────────────────────────────────────────────
   Each item marked with a solid 13px diamond, the mark's shape, its colour rotating
   through the brand: --peri-500, --val-500, --surface-dark (--peri-300, --val-500 and
   white on dark). The homepage's reasons. --dm-top sets the diamond against the item's
   first line: 7px suits a 20px heading. */
.dm-list { list-style: none; }
.dm-list > li { position: relative; padding-left: 34px; }
.dm-list > li::before {
    content: ""; position: absolute; left: 3px; top: var(--dm-top, 7px);
    width: 13px; height: 13px; rotate: 45deg; background: var(--peri-500);
  }
.dm-list > li:nth-child(3n+2)::before { background: var(--val-500); }
.dm-list > li:nth-child(3n)::before { background: var(--surface-dark); }
.on-dark .dm-list > li:nth-child(3n+1)::before { background: var(--peri-300); }
.on-dark .dm-list > li:nth-child(3n)::before { background: #fff; }
/* ─── Value pillars ───────────────────────────────────────────────────────────
   What a service gets you, as statement cards: a card that says something rather than
   going somewhere, so the link card's ground (--raised, the card shadow) with no hover.
   Each opens on a 13px diamond, the mark's shape, rotating through the brand like the
   diamond list. Two across; .pg-5 sets five as two over three. On dark each card is the
   dark panel: --surface-dark-2, a --border-dark edge, no shadow. */
.pillar-grid { list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.pillar { position: relative; background: var(--raised); border-radius: var(--radius); box-shadow: var(--shadow-card); padding: 30px 32px 32px; }
.pillar::before { content: ""; display: block; width: 13px; height: 13px; rotate: 45deg; background: var(--peri-500); margin: 3px 0 22px 3px; }
.pillar:nth-child(3n+2)::before { background: var(--val-500); }
.pillar:nth-child(3n)::before { background: var(--surface-dark); }
.pillar h3 { font-family: var(--serif); font-optical-sizing: auto; font-weight: 500; font-size: 23px; line-height: 1.24; letter-spacing: -0.004em; color: var(--text); }
.pillar p { margin-top: 10px; font-size: 16px; line-height: 1.62; color: var(--text-dim); }
.pillar .num { font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.on-dark .pillar { background: var(--surface-dark-2); border: 1px solid var(--border-dark); box-shadow: none; }
.on-dark .pillar h3, .on-dark .pillar .num { color: #fff; }
.on-dark .pillar p { color: var(--text-invert); }
.on-dark .pillar:nth-child(3n+1)::before { background: var(--peri-300); }
.on-dark .pillar:nth-child(3n)::before { background: #fff; }
.pillar-grid.pg-5 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.pillar-grid.pg-5 > .pillar { grid-column: span 2; }
.pillar-grid.pg-5 > .pillar:nth-child(-n+2) { grid-column: span 3; }
/* .pg-ruled: the same claims with no cards, for a band that is itself white. Two across in
   a grid ruled by hairlines, a line across the top and between the cells, the diamond still
   taking its colour, and the claim in the sans at the .h3 size. */
.pillar-grid.pg-ruled { gap: 0; border-top: 1px solid var(--line-2); }
.pg-ruled .pillar { background: none; box-shadow: none; border-radius: 0; padding: 36px 44px 40px 0; }
.pg-ruled .pillar:nth-child(2n) { padding: 36px 0 40px 44px; border-left: 1px solid var(--line-2); }
.pg-ruled .pillar:nth-child(n+3) { border-top: 1px solid var(--line-2); }
.pg-ruled .pillar h3 { font-family: var(--disp); font-stretch: 108%; font-weight: 600; font-size: 20px; line-height: 1.3; letter-spacing: -0.003em; }
@media (max-width: 900px) {
  .pg-ruled .pillar, .pg-ruled .pillar:nth-child(2n) { padding: 30px 0 32px; border-left: 0; }
  .pg-ruled .pillar + .pillar { border-top: 1px solid var(--line-2); }
}
@media (max-width: 900px) {
  .pillar-grid, .pillar-grid.pg-5 { grid-template-columns: 1fr; }
  .pillar-grid.pg-5 > .pillar, .pillar-grid.pg-5 > .pillar:nth-child(-n+2) { grid-column: auto; }
  .pillar { padding: 26px 24px 28px; }
}
/* ─── Step spine ──────────────────────────────────────────────────────────────
   A four-step sequence, the homepage's: each step opens on a numbered navy diamond chip
   (the mark's shape), and a periwinkle line joins the four chips. With html.motion the
   first time the steps scroll in, carenetic.js adds .play: the line draws left to right
   and each chip fills from an outline as the line reaches it. The text never moves. JS
   off and reduced motion get the finished diagram. The line runs between the first and
   last chip centres, so it connects the steps rather than underlining them, and comes off
   below 1120, where the steps wrap. --spine-ground is the section's ground, which the
   outlined chip shows before it fills. The homepage adds its return bracket on top. */
.spine-bar { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); }
/* Each cell's gutter sits on its right, so every step's text starts on its column's edge. */
.spine-cell { position: relative; z-index: 1; padding: 34px 34px 0 0; }
/* The chip is a 34px square turned 45deg, so its points reach 7px past the box.
   The margin pulls the left point back onto the text edge. */
.step-chip {
    position: relative; display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; background: var(--surface-dark);
    transform: rotate(45deg); margin: 0 0 22px 7px;
  }
.step-chip span {
    transform: rotate(-45deg); color: #fff; font-weight: 600;
    font-size: 15px; font-variant-numeric: tabular-nums;
  }
.spine-cell .h3 { margin-bottom: 12px; }
.spine-connector {
    position: absolute; top: 51px; left: 0; right: 0; height: 2px;
    background: var(--peri-300); transform: scaleX(1); transform-origin: left; z-index: 0;
  }
/* Five steps: .sb-5, a narrower gutter so five columns still hold a line of text. */
.spine-bar.sb-5 { grid-template-columns: repeat(5, 1fr); }
.sb-5 .spine-cell { padding-right: 26px; }
/* Chip centre: its 7px margin plus half of the 34px chip. */
@media (min-width: 1121px) {
  .spine-connector { left: 24px; right: calc(25% - 24px); }
  .sb-5 .spine-connector { right: calc(20% - 24px); }
}
@media (min-width: 901px) and (max-width: 1120px) {
  .spine-bar, .spine-bar.sb-5 { grid-template-columns: repeat(2, 1fr); }
  /* cells are children 2 to 5, so the second row starts at child 4 */
  .spine-cell:nth-child(n+4) { border-top: 1px solid var(--line); margin-top: 8px; }
}
@media (max-width: 1120px) { .spine-connector { display: none; } }
@media (max-width: 900px) {
  .spine-bar, .spine-bar.sb-5 { grid-template-columns: 1fr; }
  .spine-cell { padding-right: 0; border-top: 1px solid var(--line); }
  .spine-connector + .spine-cell { border-top: none; }
}
@media (prefers-reduced-motion: no-preference) {
  html.motion .spine-bar:not(.play) .spine-connector { transform: scaleX(0); }
  html.motion .spine-bar:not(.play) .step-chip { background: var(--spine-ground, var(--ground)); box-shadow: inset 0 0 0 2px var(--peri-300); }
  html.motion .spine-bar:not(.play) .step-chip span { color: var(--peri-600); }
  html.motion .spine-bar.play .spine-connector { transition: transform 1.2s linear .15s; }
  html.motion .spine-bar.play .step-chip {
    transition: background .35s ease calc(.15s + var(--i) * .4s), box-shadow .35s ease calc(.15s + var(--i) * .4s);
  }
  html.motion .spine-bar.play .step-chip span { transition: color .35s ease calc(.15s + var(--i) * .4s); }
}
/* ─── Definition list ─────────────────────────────────────────────────────────
   A claim in the serif on a 17rem column, its explanation beside it on the first
   baseline. The Floppy mailer's services and the Security & compliance PHI section.
   A figure inside a definition takes .num. Stacks below 900. */
.def-list { display: grid; gap: 38px; }
.def { display: grid; grid-template-columns: minmax(0, 17rem) minmax(0, 1fr); gap: 0 56px; align-items: first baseline; }
.def dt { font-family: var(--serif); font-optical-sizing: auto; font-weight: 500; font-size: 23px; line-height: 1.24; color: var(--text); }
.def dd { font-size: 16px; line-height: 1.62; color: var(--text-dim); }
.def .num { font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
@media (max-width: 900px) { .def { grid-template-columns: 1fr; gap: 8px; } }
/* ─── Disqualifier ────────────────────────────────────────────────────────────
   Who shouldn't buy, said plainly and quietly: it should be read, not noticed. Straight on
   the --sunk band, the one ground reserved for it, with no card and no colour: a --line-2
   hairline across the top, the heading (and an optional line under it, .because) on the
   left, the reasons on the right, each on a 9px --surface-dark diamond with the deciding
   phrase in bold and a hairline between them. A paragraph (.disq-body) can stand where
   the list goes. Stacks at 900. (Miles, 2026-09-28: quieter than the card it was.) */
.disq { background: var(--sunk); padding: 72px 0; }
.disq-panel {
    border-top: 1px solid var(--line-2); padding-top: 30px;
    display: grid; grid-template-columns: 0.85fr 1.65fr; gap: 22px 56px; align-items: start;
  }
.disq-panel .h2 { font-size: 25px; line-height: 1.2; letter-spacing: -0.004em; max-width: none; text-wrap: balance; }
.disq-head .because { margin-top: 14px; font-size: 16px; line-height: 1.6; color: var(--text-dim); }
.disq-head .because strong { color: var(--text); font-weight: 600; }
.disq-panel ul { list-style: none; }
.disq-panel li { position: relative; padding-left: 26px; font-size: 17px; line-height: 1.6; color: var(--text-dim); }
.disq-panel li + li { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line); }
.disq-panel li::before {
    content: ""; position: absolute; left: 1px; top: 10px;
    width: 9px; height: 9px; rotate: 45deg; background: var(--surface-dark);
  }
.disq-panel li + li::before { top: 26px; }
.disq-panel li strong, .disq-body strong { color: var(--text); font-weight: 600; }
.disq-body p { font-size: 17px; line-height: 1.6; color: var(--text-dim); }
@media (max-width: 900px) {
  .disq { padding: 56px 0; }
  .disq-panel { grid-template-columns: 1fr; padding-top: 26px; }
  .disq-panel .h2 { font-size: 23px; }
}
/* ─── Status chip ─────────────────────────────────────────────────────────────
   One chip for every status tag: 11px caps on a tint of its own colour, at the 3px
   chip radius. .chip-status leads with a glyph in the saguaro's stroke (StatusChip.astro
   writes it), and the word always stays, so neither colour nor shape is the only signal.
   On dark the chip takes a colour's ink on --surface-dark rather than a tint (the
   homepage hero queue). A form's checkbox pills are .pill, not this. */
.chip {
    display: inline-block;
    font-size: 11px; font-weight: 600; letter-spacing: 0.07em; line-height: 1.2;
    text-transform: uppercase;
    padding: 4px 10px; border-radius: 3px;
  }
.chip-open, .chip-prog { background: var(--peri-wash); color: var(--peri-700); }
.chip-flag { background: var(--val-tint); color: var(--val-ink); }
.chip-done { background: var(--ok-tint); color: var(--ok-ink); }
.chip-status { display: inline-flex; align-items: center; gap: 5px; padding-left: 7px; white-space: nowrap; }
.chip-status svg {
    flex: none; width: 13px; height: 13px;
    fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  }
/* Twelve pixels is the floor for a label on a phone. */
@media (max-width: 900px) { .chip { font-size: 12px; } }

/* Loose diamonds, the mark's shape at its smallest, scattered on a dark band clear of its
   copy: the closing CTA's padding and the homepage hero's left margin. Each <i> is placed
   by --x and --y and coloured by --c, and stays clear of the copy at every width: that is
   the placer's job, so check it from 320 up. Decoration only, so the container is aria-hidden. */
.dm-scatter { position: absolute; inset: 0; pointer-events: none; }
.dm-scatter i { position: absolute; left: var(--x); top: var(--y); width: 18px; height: 18px; rotate: 45deg; background: var(--c); }
/* The scatter as confetti in the margin left of a dark hero's copy, with the orange added,
   and nowhere else in the hero: the homepage and About. Five, and only the first starts
   above the headline. --edge is the copy's left edge (the .wrap's content box). Each
   diamond sits at a fraction of the margin, never past its middle, so they keep well off
   the copy and spread as the page widens. Shown from 1220px, where the margin has room.
   Each drifts on scroll at its own speed (.pll, 0.10 to 0.26), always vertically. */
.hero-dms { z-index: 1; --edge: max(44px, (100% - 1120px) / 2 + 44px); }
.hero-dms i { display: none; --x: calc(var(--edge) * var(--f)); }
.hero-dms i:nth-child(1) { --f: 0.24; --y: 10%; --c: var(--peri-300); }
.hero-dms i:nth-child(2) { --f: 0.46; --y: 27%; --c: var(--val-500); }
.hero-dms i:nth-child(3) { --f: 0.1; --y: 37%; --c: var(--peri-500); }
.hero-dms i:nth-child(4) { --f: 0.49; --y: 59%; --c: #fff; }
.hero-dms i:nth-child(5) { --f: 0.27; --y: 90%; --c: var(--peri-500); }
@media (min-width: 1220px) { .hero-dms i { display: block; } }
.close-cta .cta-card { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: 34px; }
.close-cta .h2 { font-size: 32px; color: #fff; max-width: none; }
.close-cta .tone { color: var(--surface-dark); }
.close-cta .sub { margin-top: 10px; font-size: 17px; line-height: 1.5; color: #fff; max-width: 33em; }
.close-cta .cta-zone { flex-direction: column; flex-wrap: nowrap; align-items: stretch; justify-self: start; gap: 12px; }
.close-cta .btn { background: var(--peri-600); text-align: center; }
.close-cta .btn::before { background: var(--peri-700); }
.close-cta .after-btn { font-size: 15px; text-align: center; }
.close-cta a.textlink { color: #fff; --tl-rest: rgba(255,255,255,0.45); }
.close-cta a:focus-visible { outline-color: #fff; }
@media (max-width: 900px) {
  .close-cta { --pad: 64px; }
  .close-cta .cta-card { column-gap: 26px; }
  .close-cta .h2 { font-size: 28px; }
  .dm-scatter i { width: 15px; height: 15px; }
}
/* Below 760 the band stacks: copy, then the button over the link, both left. */
@media (max-width: 760px) {
  .close-cta .cta-card { grid-template-columns: 1fr; }
  .close-cta .cta-zone { margin-top: 26px; }
}
@media (max-width: 560px) {
  .close-cta .h2 { font-size: 26px; }
}
/* Off screen and in a hidden tab a looping scene costs nothing (AmbientLoops and the
   pages' own controllers set .rest). One rule, so a scene added later is covered. */
.rest, .rest *, .rest *::before, .rest *::after { animation-play-state: paused !important; }
@media (prefers-reduced-motion: reduce) {
  /* Reduced motion: no diamond, and the hover is the colour change alone. */
  .btn { transition: none; }
  .btn::before { display: none; }
  .nav-links > a::after, a.textlink { transition: none; }
  .nav-chev, .nav-mega, .nav-mega-inner, .nav-mega-link, .nav-mega-go { transition: none; }
  .btn:hover { background: var(--val-700); }
}

/* ─── Link card ───────────────────────────────────────────────────────────────
   Every card that is one link to somewhere else: the service cards, the doors, the
   worry and lens cards. Borderless on --raised with the card shadow. Under the pointer
   or keyboard focus it lifts 5px and a periwinkle rule draws along its foot. No border,
   so the rule meets the card's edges. `.link-card-primary` is the one loud card in a
   set (the homepage concept door): the page gives it its fill and the rule turns orange.
   The page keeps its own layout, padding and text colours; this owns ground, edge and
   hover. `translate` rather than `transform`, so the scroll reveal's transform and the
   lift never fight. */
.link-card {
    position: relative; isolation: isolate; overflow: hidden;
    background: var(--raised); border: 0; border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    transition: translate .3s var(--ease-settle), box-shadow .3s var(--ease-settle), background-color .2s ease;
  }
.link-card::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; z-index: 3;
    background: var(--peri-500); transform: scaleX(0); transform-origin: left;
    transition: transform .45s var(--ease-settle); pointer-events: none;
  }
.link-card-primary::after { background: var(--val-500); }
.link-card:is(:hover, :focus-visible, :has(:focus-visible)) { translate: 0 -5px; box-shadow: var(--shadow-lift); }
.link-card:is(:hover, :focus-visible, :has(:focus-visible))::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  /* No lift and no draw: the rule and the deeper shadow simply appear. */
  .link-card, .link-card::after { transition: none; }
  .link-card:is(:hover, :focus-visible, :has(:focus-visible)) { translate: none; }
}
.footer { background: var(--surface-dark); padding: 58px 0 40px; }
.footer-grid { display: grid; grid-template-columns: 1.7fr 1fr 1fr 1fr; gap: 40px; }
.footer .nav-logo { height: 30px; margin-bottom: 16px; }
.foot-line { color: var(--text-invert-dim); font-size: 15px; line-height: 1.5; }
/* The phone and email under the tagline. Links like the columns' links, stacked, so each is its own
   target. Their clicks are GA4 key events, so they stay on every page (CLAUDE.md §6). */
.foot-reach { font-style: normal; display: flex; flex-direction: column; align-items: flex-start; gap: 3px; margin-top: 16px; }
.foot-reach a { color: var(--text-invert); text-decoration: none; font-size: 15px; transition: color .15s ease; }
.foot-reach a:hover { color: #fff; }
.foot-head { color: #fff; font-size: 12px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; margin-bottom: 15px; }
.foot-col ul { list-style: none; }
.foot-col li { margin-bottom: 9px; }
.foot-col a { color: var(--text-invert); text-decoration: none; font-size: 15px; transition: color .15s ease; }
.foot-col a:hover { color: #fff; }
.footer-note {
    margin-top: 46px; padding-top: 22px; border-top: 1px solid var(--border-dark);
    color: var(--text-invert-dim); font-size: 14px;
    display: flex; justify-content: space-between; gap: 14px 28px; flex-wrap: wrap;
  }
/* Bolder and white so it outranks the copyright line opposite it. */
.foot-made {
    display: inline-flex; align-items: center; gap: 10px;
    color: #fff; font-weight: 600; font-size: 15px;
  }
.foot-made .cactus { width: 17px; height: 17px; flex: none; color: var(--peri-300); }
/* The copyright and Cookie settings, which every page carries whatever its footer columns (CLAUDE.md §6,
   the consent decision D9): withdrawing a yes has to be as easy to find as giving it. */
.foot-legal { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 22px; }
.foot-legal a { color: var(--text-invert); text-decoration: none; padding: 4px 0; transition: color .15s ease; }
.foot-legal a:hover { color: #fff; }

/* ─── Cookie consent ──────────────────────────────────────────────────────────
   The banner and Cookie settings (ConsentBanner.astro, kit: Chrome). The banner is a card fixed to the
   bottom left, a sheet across the bottom on a phone, on the footer's dark ground. It doesn't block the
   page and it never animates. While it shows, the footer grows by its height (--consent-h, measured by
   the banner's script) so the end of the page can scroll clear of it. */
.consent {
    position: fixed; z-index: 80; left: 24px; bottom: 24px; width: min(560px, calc(100% - 48px));
    background: var(--surface-dark); border: 1px solid var(--border-dark); border-radius: var(--radius);
    box-shadow: var(--shadow-lift); padding: 22px 24px 22px;
  }
.consent[hidden] { display: none; }
.consent-text { font-size: 15px; line-height: 1.55; color: var(--text-invert); }
.consent-text strong { color: #fff; font-weight: 600; }
.consent-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; margin-top: 16px; }
.consent a:focus-visible, .consent button:focus-visible { outline-color: var(--peri-300); }
/* The way to the detail: a button that reads as a link, quieter than the two choices. */
.consent-more {
    font-family: var(--disp); font-size: 15px; font-weight: 600; color: var(--peri-300);
    background: none; border: 0; padding: 12px 4px; cursor: pointer;
    text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 4px;
    text-decoration-color: rgba(124,155,224,0.4);
  }
.consent-more:hover { text-decoration-color: currentColor; }
html.consent-open { scroll-padding-bottom: calc(var(--consent-h, 0px) + 24px); }
html.consent-open .footer { padding-bottom: calc(40px + var(--consent-h, 0px) + 24px); }
@media (max-width: 560px) {
  .consent { left: 12px; right: 12px; bottom: 12px; width: auto; padding: 18px 18px 18px; }
  /* Accept and reject share the row at equal width, and the third way wraps under them. */
  .consent-actions .btn-choice { flex: 1 1 0; }
}

/* The choice button: the newsletter signup's outline button (kit: Forms), shared. Two sit side by side
   only where the visitor must be as free to pick one as the other (Accept all and Reject all), so neither
   takes the page action's orange. On light it fills with --text on hover, on dark with white. */
.btn-choice {
    font-family: var(--disp); font-size: 15px; font-weight: 600; line-height: 1.2;
    padding: 12px 20px; border: 1px solid var(--text); border-radius: var(--radius);
    background: none; color: var(--text); cursor: pointer; transition: background .15s ease, color .15s ease;
  }
.btn-choice:hover { background: var(--text); color: #fff; }
.on-dark .btn-choice { border-color: #fff; color: #fff; }
.on-dark .btn-choice:hover { background: #fff; color: var(--surface-dark); }

/* Cookie settings: a modal <dialog> on --raised, the form card's ground. */
.consent-dialog {
    width: min(560px, calc(100% - 32px)); max-height: calc(100% - 32px); margin: auto; padding: 0;
    border: 0; border-radius: var(--radius); background: var(--raised); color: var(--text);
    box-shadow: var(--shadow-lift); overflow: auto;
  }
.consent-dialog::backdrop { background: rgba(26,26,53,0.6); }
.consent-dialog-body { position: relative; padding: 30px 32px 32px; }
.consent-dialog-title { font-family: var(--serif); font-optical-sizing: auto; font-weight: 500; font-size: 27px; line-height: 1.2; letter-spacing: -.008em; padding-right: 44px; }
.consent-close {
    position: absolute; top: 14px; right: 14px; width: 44px; height: 44px;
    display: grid; place-items: center; background: none; border: 0; border-radius: var(--radius);
    color: var(--text-dim); cursor: pointer;
  }
.consent-close:hover { color: var(--text); background: var(--ground-alt); }
.consent-intro { margin-top: 10px; font-size: 16px; line-height: 1.6; color: var(--text-dim); }
.consent-cats { list-style: none; margin-top: 22px; border-top: 1px solid var(--line-2); }
.consent-cat { padding: 16px 0 18px; border-bottom: 1px solid var(--line-2); }
.consent-cat-head { display: flex; justify-content: space-between; align-items: center; gap: 16px; min-height: 30px; }
label.consent-cat-head { cursor: pointer; }
.consent-cat-name { font-size: 16px; font-weight: 600; color: var(--text); }
.consent-always { font-size: 14px; font-weight: 600; color: var(--text-faint); }
.consent-cat p { margin-top: 6px; font-size: 15px; line-height: 1.55; color: var(--text-dim); }
/* Global Privacy Control said no before the visitor did: the form status's quiet success, as a note. */
.consent-gpc { margin-top: 18px; padding: 14px 16px; border-left: 3px solid var(--peri-600); background: var(--peri-wash); color: var(--peri-700); font-size: 15px; line-height: 1.55; }
.consent-dialog-actions { margin-top: 24px; }
@media (max-width: 560px) {
  .consent-dialog-body { padding: 24px 22px 26px; }
  .consent-dialog-title { font-size: 24px; }
}
/* The switch: a track with the site's radius and the mark's diamond for a thumb, which crosses and turns
   white on --peri-600 when on. Its edge is --field-line, the 3:1 every control's boundary needs. */
.consent-switch {
    appearance: none; -webkit-appearance: none; flex: none; position: relative; margin: 0;
    width: 50px; height: 28px; border: 1.5px solid var(--field-line); border-radius: var(--radius);
    background: var(--ground); cursor: pointer; transition: background .15s ease, border-color .15s ease;
  }
.consent-switch::before {
    content: ""; position: absolute; top: 50%; left: 6px; width: 12px; height: 12px;
    background: var(--field-line); transform: translateY(-50%) rotate(45deg);
    transition: left .15s ease, background .15s ease;
  }
.consent-switch:hover { border-color: var(--peri-500); }
.consent-switch:checked { background: var(--peri-600); border-color: var(--peri-600); }
.consent-switch:checked::before { left: 29px; background: #fff; }
.consent-switch:focus-visible { outline: 3px solid var(--peri-500); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .consent-switch, .consent-switch::before, .btn-choice, .foot-legal a { transition: none; }
}

/* Embed gate. For an opt-in visitor (data-consent-gate, set by ConsentHead) a third-party embed that sets
   its own cookies waits for a click: the frame is hidden and its slot holds the gate's room from the
   first paint, and DeferredIframes puts the gate in it. With script off there is no gate, the Worker
   drops the <noscript> frame, and the page's link to the calendar's own page stands in. */
html[data-consent-gate] iframe[data-booking-embed][data-src] { display: none; }
html[data-consent-gate] :has(> iframe[data-booking-embed][data-src]) { position: relative; min-height: 220px; }
.embed-gate {
    position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 16px; padding: 28px 24px; text-align: center; background: var(--raised);
  }
.embed-gate p { max-width: 36ch; font-size: 16px; line-height: 1.55; color: var(--text-dim); }
/* ===== Website Support ===== */

  .sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
/* Interior hero, inherited from Services. */
  .display-int { font-size: 47px; }
.crumb {
    display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
    font-size: 13px; font-weight: 600; letter-spacing: 0.02em;
    color: var(--text-invert-dim); margin-bottom: 22px;
  }
.crumb a { color: var(--text-invert); text-decoration: none; }
.crumb a:hover { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.crumb .sep { width: 5px; height: 5px; background: var(--border-dark); transform: rotate(45deg); flex: none; }
/* --- Responsive tail. Last in the sheet so it wins on order, not on weight. --- */
/* Stacked footer links, and the secondary link under a closing band's button, are
   targets rather than prose. The 24px floor is a target-size rule, not a phone rule,
   so it applies at every width. These were scoped to the phone breakpoint on 8-19 and
   left an 18px and a 19px target standing on desktop. Padding on an inline link grows
   the hit box and moves nothing. */
.foot-col a, .foot-reach a, .after-btn .textlink { padding: 4px 0; }
/* A breadcrumb link is a navigation target, not a word in a sentence, so it takes
   the 24px floor. Padding grows the hit box and the negative margin keeps the row
   the same height it was. */
.crumb a { padding: 4px 0; margin: -4px 0; }
.faq-item + .faq-item { border-top: 1px solid var(--line); }

/* Comparison marker. The site has no icon library, so a table cell that means yes,
   no or partly says so in the one icon idiom the site does have: stroked, round
   capped, 1.7 weight, sized to the text beside it. The state is carried in text
   for a screen reader, because a mark alone announces as nothing. */
.mk { width: 16px; height: 16px; vertical-align: -3px; fill: none;
      stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.mk-yes  { color: var(--peri-600); }
.mk-no   { color: var(--text-faint); }
.mk-part { color: var(--sev-high); }

/* ─── Form card ───────────────────────────────────────────────────────────────
   The one form (kit: Forms): Contact, both free offers, Careers and every job page. The card is
   --raised on a page that is not, the controls are wells of --ground inside it. A page keeps only
   what is its own: the section around the card, and its textarea's height, which is set by how much
   it expects the reader to write (84px on Diagnostic Audit, 96px on the homepage concept, 132px
   here and on Contact). Selectors stay at the weight the pages' own copies had, so a page rule
   still wins on order. */
.form-card {
    background: var(--raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    padding: 32px 34px 36px;
  }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.field { display: block; border: 0; }
.field > span, .field > legend {
    display: block; margin-bottom: 7px; padding: 0;
    font-size: 14px; font-weight: 600; color: var(--text);
  }
/* Inline, not a flex sibling. Pushed to the far end of the row it detached from the label it
   qualifies and read as a column heading. */
.field .opt {
    font-style: normal; margin-left: 8px;
    font-size: 12px; font-weight: 600;
    letter-spacing: 0.07em; text-transform: uppercase; color: var(--text-faint);
  }
.field input:where([type="text"], [type="email"], [type="url"], [type="tel"]), .field textarea {
    display: block; width: 100%;
    font-family: var(--disp); font-size: 16px; line-height: 1.5; color: var(--text);
    background: var(--ground);
    border: 1px solid var(--field-line);
    border-radius: var(--radius);
    padding: 12px 14px;
    transition: border-color .15s ease;
  }
.field input:hover, .field textarea:hover { border-color: var(--peri-500); }
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--peri-500); }
.field textarea { resize: vertical; min-height: 132px; }
.form > .field + .field, .form > .field + .field-row, .form > .field-row + .field, .form > .field-row + .field-row { margin-top: 20px; }
.form .btn { margin-top: 26px; }
@media (max-width: 560px) {
  .form-card { padding: 26px 24px 30px; }
  .field-row { grid-template-columns: 1fr; gap: 20px; }
}

/* The form beside a quiet aside: the card at the reading measure, the aside in what's left. The
   free offers' "Rather start with a call?" and the careers pages' other roles. One column below 900. */
.ask-grid {
    display: grid; grid-template-columns: minmax(0, var(--measure)) 1fr;
    gap: 56px; align-items: start; margin-top: 34px;
  }
/* Scoped to the grid: /floppy/ has a section of its own called .quiet. */
.ask-grid > .quiet { background: var(--sunk); border-radius: var(--radius); padding: 26px 28px 28px; }
.ask-grid > .quiet h3 { margin-bottom: 10px; }
.ask-grid > .quiet p { font-size: 16px; line-height: 1.6; color: var(--text-dim); }
.ask-grid > .quiet .go { margin-top: 16px; font-size: 16px; }
.ask-grid > .quiet .go .textlink { padding: 4px 0; }
@media (max-width: 900px) {
  .ask-grid { grid-template-columns: 1fr; gap: 36px; }
}

/* ─── Careers and job pages ───────────────────────────────────────────────────
   Shared by /about/careers/ and every job page (JobPage.astro): the light top, the open roles on the
   ledger rule, the benefits grid (Benefits.astro) and the small-diamond bullet. */
.cr-top { background: var(--ground); padding: 56px 0 62px; position: relative; overflow: hidden; }
.cr-top .crumb { font-size: 14px; color: var(--text-faint); margin-bottom: 26px; }
.cr-top .crumb a { color: var(--text-faint); text-decoration: none; }
.cr-top .crumb a:hover { color: var(--peri-700); }
.cr-top p.one { margin-top: 14px; font-size: 19px; line-height: 1.55; color: var(--text-dim); max-width: var(--measure); }

/* Open roles, one row each on the ledger rule, the way the case study list runs: the title is the
   link, the terms under the lead, and the row's own link on the right, dropping under it below 640. */
.role-list { list-style: none; display: grid; gap: 30px; }
.role-list > li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 40px; align-items: center; }
.role-title { font-family: var(--serif); font-optical-sizing: auto; font-weight: 500; font-size: 27px; line-height: 1.2; letter-spacing: -0.005em; }
.role-title a { color: var(--text); text-decoration: none; }
.role-title a:hover, .role-title a:focus-visible { color: var(--peri-700); text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1.5px; }
.role-lead { margin-top: 8px; font-size: 17px; line-height: 1.6; color: var(--text-dim); max-width: var(--measure); }
.role-terms { margin-top: 10px; font-size: 14px; font-weight: 600; letter-spacing: 0.01em; color: var(--text-faint); }
/* A link to a role is periwinkle wherever it appears, like a link into a case study, so the row's
   link and the asides' role lists read as one kind of link. */
a.role-go { color: var(--peri-600); --tl-rest: rgba(58,95,181,0.35); }
.role-list .role-go { font-size: 16px; padding: 4px 0; white-space: nowrap; }
@media (max-width: 640px) {
  .role-list > li { grid-template-columns: 1fr; gap: 14px 0; }
  .role-go { justify-self: start; }
  .role-title { font-size: 24px; }
}

/* The bullet for a plain list on these pages: a 7px rotated square, smaller than the diamond
   list's 13px because each line is a fact rather than a reason. */
.ticks { list-style: none; }
.ticks li { position: relative; padding-left: 22px; font-size: 17px; line-height: 1.6; color: var(--text-dim); }
.ticks li + li { margin-top: 12px; }
.ticks li::before { content: ""; position: absolute; left: 2px; top: .62em; width: 7px; height: 7px; transform: rotate(45deg); background: var(--peri-500); }
.on-dark .ticks li { color: var(--text-invert); }
.on-dark .ticks li::before { background: var(--peri-300); }

/* Benefits: four columns, each standing on the ledger rule. Two across below 980, one below 640. */
.perks { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 40px 34px; margin-top: 40px; }
.perks .h3 { font-size: 18px; margin-bottom: 14px; }
.perks .ticks li { font-size: 16px; line-height: 1.5; }
.perks .ticks li + li { margin-top: 10px; }
.perks .ticks li::before { top: .52em; }
@media (max-width: 980px) { .perks { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .perks { grid-template-columns: 1fr; gap: 30px; } }

/* ===== Form states =====
   Submission feedback for the four real forms. Shared because they appear on 21 pages
   (contact, the two offers, and the newsletter on 18 insights routes), and the kit's rule is
   that anything on more than one page lives here rather than being copied into each.

   The rule these styles exist to satisfy: a failure has to be perceivable without colour.
   Every error state below pairs its colour with a text message, and the summary takes focus,
   so a screen reader announces it and a keyboard user lands on it. */

/* Placeholder hints ("https://", "you@yourgroup.com") are text and need 4.5:1. The browser's
   default grey is 4.49:1 on --ground, so set it rather than inherit it. */
::placeholder { color: var(--text-faint); opacity: 1; }

/* A field's focus is the same ring as every other control's. The old cue, a border shift and
   a 22% glow, measured 1.2:1 and 1.3:1 against what it replaced. */
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: 3px solid var(--peri-500); outline-offset: 3px; }

/* The honeypot. Off-screen rather than display:none, because a bot that skips hidden fields
   would otherwise skip this one too, which is the opposite of what it is for. Out of the
   tab order and out of the accessibility tree, so a person never reaches it either way. */
.hp {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.form-status {
  margin-top: 24px;
  padding: 14px 16px;
  border: 1px solid var(--field-line);
  border-left-width: 3px;
  border-radius: var(--radius);
  font-size: 15px;
  line-height: 1.55;
  background: var(--raised);
}
.form-status:focus-visible { outline: 3px solid var(--peri-500); outline-offset: 2px; }
.form-status[hidden] { display: none; }
.form-status .fs-title { font-weight: 600; }
.form-status ul { margin: 8px 0 0; padding-left: 20px; }
.form-status li + li { margin-top: 4px; }
.form-status a { color: inherit; }
.form-status.is-error { border-color: var(--val-ink); background: var(--val-tint); color: var(--val-ink); }
.form-status.is-ok { border-color: var(--peri-600); background: var(--peri-wash); color: var(--peri-700); }
/* In progress, and deliberately the quietest of the three: nothing has gone right or wrong yet.
   It carries text, not just a colour, because that is the only part a screen reader gets. */
.form-status.is-busy { border-color: var(--field-line); background: var(--ground-alt); color: var(--text-dim); }

/* Inline, beneath the control it belongs to, and tied to it with aria-describedby. Scoped to
   .field because the message is a span inside the label, and the form pages' own label rule
   (.field > span, 0-1-1) outranked a bare .field-error and set it in black with the label's margin. */
.field .field-error {
  display: block;
  margin: 7px 0 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--val-ink);
}
.field .field-error::before { content: "\26A0\FE0E"; margin-right: 6px; }
/* Hover and focus included, or the pages' periwinkle hover border would replace the error's. */
.field.has-error input,
.field.has-error input:hover,
.field.has-error input:focus,
.field.has-error textarea,
.field.has-error textarea:hover,
.field.has-error textarea:focus,
.field.has-error .fbox { border-color: var(--val-ink); }

/* Turnstile renders in here on first interaction with the form. No height is reserved: the widget
   brings its own, and reserving it would leave a blank gap on staging, where the test key renders
   an invisible widget. The shift this allows follows a focus or a tap, so it is outside the window
   Lighthouse counts towards CLS. */
.form-check:not(:empty) { margin-top: 24px; }

.btn[aria-busy="true"] { opacity: 0.75; cursor: progress; }
.btn[aria-busy="true"]::before { display: none; }
