
/* ===== fonts.css ===== */
/* Self-hosted Lato and Roboto.
   Generated by tools/import-fonts.sh from Elementor's local font cache,
   then trimmed. Do not edit by hand — re-run the script instead.

   URLs are relative to this file (../fonts/). They were previously absolute
   https://optrical.com/wp-content/uploads/... which sent every visitor back
   to the old WordPress site for fonts on every page load.

   font-display: swap keeps text visible while a face loads instead of
   blocking it. unicode-range is preserved, so browsers fetch only the
   subsets a page actually needs.

   Only the weights this design declares are kept, upright only:
     Lato   400, 700   (--f-head; 700 also backs the synthetic 600 headings)
     Roboto 400, 500, 700 (--f-body)
   Nothing on the site uses italic. If italic copy is ever added through the
   admin, the browser will slant the upright face; re-run the import and widen
   the keep-list here if that is not good enough. */

@font-face {
  font-display: swap;
  font-family: 'Lato';
  font-style: normal;
  font-weight: 400;
  src: url(../fonts/lato-8fd934da.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-display: swap;
  font-family: 'Lato';
  font-style: normal;
  font-weight: 400;
  src: url(../fonts/lato-05fdccf1.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-display: swap;
  font-family: 'Lato';
  font-style: normal;
  font-weight: 700;
  src: url(../fonts/lato-a97e77d0.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-display: swap;
  font-family: 'Lato';
  font-style: normal;
  font-weight: 700;
  src: url(../fonts/lato-bc192fa6.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-9f01c202.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-82ad1387.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-724acd83.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-aeb7f52d.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-4d1fb646.woff2) format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-b0264ac9.woff2) format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-bb0d2555.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-c6d65aea.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  src: url(../fonts/roboto-1abb80a1.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-9f01c202.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-82ad1387.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-724acd83.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-aeb7f52d.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-4d1fb646.woff2) format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-b0264ac9.woff2) format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-bb0d2555.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-c6d65aea.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  src: url(../fonts/roboto-1abb80a1.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-9f01c202.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-82ad1387.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-724acd83.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-aeb7f52d.woff2) format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-4d1fb646.woff2) format('woff2');
  unicode-range: U+0302-0303, U+0305, U+0307-0308, U+0310, U+0312, U+0315, U+031A, U+0326-0327, U+032C, U+032F-0330, U+0332-0333, U+0338, U+033A, U+0346, U+034D, U+0391-03A1, U+03A3-03A9, U+03B1-03C9, U+03D1, U+03D5-03D6, U+03F0-03F1, U+03F4-03F5, U+2016-2017, U+2034-2038, U+203C, U+2040, U+2043, U+2047, U+2050, U+2057, U+205F, U+2070-2071, U+2074-208E, U+2090-209C, U+20D0-20DC, U+20E1, U+20E5-20EF, U+2100-2112, U+2114-2115, U+2117-2121, U+2123-214F, U+2190, U+2192, U+2194-21AE, U+21B0-21E5, U+21F1-21F2, U+21F4-2211, U+2213-2214, U+2216-22FF, U+2308-230B, U+2310, U+2319, U+231C-2321, U+2336-237A, U+237C, U+2395, U+239B-23B7, U+23D0, U+23DC-23E1, U+2474-2475, U+25AF, U+25B3, U+25B7, U+25BD, U+25C1, U+25CA, U+25CC, U+25FB, U+266D-266F, U+27C0-27FF, U+2900-2AFF, U+2B0E-2B11, U+2B30-2B4C, U+2BFE, U+3030, U+FF5B, U+FF5D, U+1D400-1D7FF, U+1EE00-1EEFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-b0264ac9.woff2) format('woff2');
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AD, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F7FF, U+1F800-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FA89, U+1FA8F-1FAC6, U+1FACE-1FADC, U+1FADF-1FAE9, U+1FAF0-1FAF8, U+1FB00-1FBFF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-bb0d2555.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-c6d65aea.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-display: swap;
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  src: url(../fonts/roboto-1abb80a1.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ===== tokens.css ===== */
/* ==========================================================================
   Optrical design tokens
   Extracted from the live Elementor stylesheet. This file is the single
   source of truth for the brand and is copied verbatim into o4qr's
   static folder — do not add site-specific rules here.
   ========================================================================== */

:root {
  /* --- Brand ------------------------------------------------------------ */
  --c-navy:          #023151;  /* headings, nav links, primary button       */
  --c-navy-deep:     #00243D;  /* footer body                               */
  --c-navy-black:    #001A2C;  /* footer bottom bar                         */
  --c-blue-hover:    #0868AA;  /* primary button hover                      */
  --c-card-title:    #132C47;  /* card headings                             */

  --c-orange:        #F26429;  /* accent / button hover                     */
  --c-orange-alt:    #EE6333;
  --c-orange-deep:   #CF4A13;
  --c-orange-link:   #DD6600;  /* infobox title hover                       */

  /* --- Text ------------------------------------------------------------- */
  --c-text:          #4F5256;
  --c-text-muted:    #797C80;
  --c-eyebrow:       #C5C5C5;
  --c-nav-hover:     #707070;
  --c-footer-text:   #708492;
  --c-footer-icon:   #99A7B1;
  --c-steel:         #8FA3B0;

  /* --- Lines & surfaces -------------------------------------------------- */
  --c-border:        #E5E5E5;  /* card border                               */
  --c-rule:          #E9E9E9;  /* header divider                            */
  --c-surface:       #FFFFFF;
  --c-footer-rule:   rgba(153, 167, 177, 0.39);

  /* Tinted panels. One step each; do not add a fourth near-identical grey.  */
  --c-panel:         #F4F6F8;  /* section / card panel                      */
  --c-panel-alt:     #EDF1F4;  /* nested panel, mobile nav groups           */
  --c-field-border:  #D3D8DD;  /* form control border                       */

  /* --- Status ------------------------------------------------------------ */
  --c-notice-soon:     var(--c-orange);
  --c-notice-soon-bg:  linear-gradient(180deg, #FFF9F5 0%, #FFFFFF 100%);
  --c-notice-info:     var(--c-navy);
  --c-notice-info-bg:  #F5F8FA;
  --c-notice-warn:     #C77700;
  --c-notice-warn-bg:  #FFF6E5;
  --c-ok:              #2E7D32;
  --c-ok-bg:           #EDF7ED;
  --c-error:           #B3261E;

  /* --- Placeholder (missing image) --------------------------------------- */
  --c-ph-text:       #7C858E;
  --c-ph-bg:         #E8EBEE;
  --c-ph-border:     #C2C9D0;
  --c-ph-bg-dark:    #5A646E;

  /* --- Typography -------------------------------------------------------- */
  --f-head: "Lato", "Helvetica Neue", Arial, sans-serif;
  --f-body: "Roboto", "Helvetica Neue", Arial, sans-serif;

  --fs-hero:       48px;  /* home slider caption, Lato 600                   */
  --fs-banner:     42px;  /* interior page banner, Roboto 600                */
  --fs-section:    28px;  /* section heading, Lato 600                       */
  --fs-sub:        19px;  /* sub-heading, Lato 400                           */
  --fs-card-title: 18px;
  --fs-body:       16px;
  --fs-eyebrow:    16px;  /* Roboto 400 uppercase                            */

  --lh-prose:   34px;  /* body copy in prose blocks                          */
  --lh-card:    25px;  /* body copy inside cards                             */
  --lh-heading: 41px;  /* 28px section headings                              */

  /* --- Layout ------------------------------------------------------------ */
  --container:    1140px;
  --gutter:       15px;
  --nav-height:   80px;
  --banner-min-h: 300px;

  /* --- Spacing scale ----------------------------------------------------- */
  --sp-1:  5px;
  --sp-2: 10px;
  --sp-3: 15px;
  --sp-4: 20px;
  --sp-5: 25px;
  --sp-6: 30px;
  --sp-7: 40px;
  --sp-8: 46px;
  --sp-9: 60px;

  --prose-gap: 32px;   /* paragraph rhythm, from the parent theme            */

  /* --- Effects ----------------------------------------------------------- */
  --shadow-card:    0 0 13px 0 rgba(0, 0, 0, 0.11);
  --shadow-hover:   0 4px 22px 0 rgba(2, 49, 81, 0.16);
  --text-shadow-hero: 0 4px 16px rgba(0, 0, 0, 0.30);

  --radius-btn:         4px;
  --radius-btn-outline: 3px;

  --ease:       cubic-bezier(0.4, 0, 0.2, 1);
  --transition: 0.3s var(--ease);
}

/* Breakpoints are 1024px (tablet) and 767px (mobile), matching the
   Elementor configuration. CSS custom properties cannot be used inside
   media queries, so those values are written literally throughout. */

/* ===== base.css ===== */
/* ==========================================================================
   Optrical — base
   Reset, typography, layout primitives, header, footer, shared components.
   Depends on tokens.css. Section-specific rules live in sections.css.
   ========================================================================== */

/* --- Reset ---------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--f-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: var(--lh-prose);
  color: var(--c-text);
  background: var(--c-surface);
  -webkit-font-smoothing: antialiased;
}

img, picture, svg, video { max-width: 100%; height: auto; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

/* --- Typography ----------------------------------------------------------- */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--f-head);
  color: var(--c-navy);
  margin: 0;
  font-weight: 600;
}

p { margin: 0 0 var(--prose-gap); }
p:last-child { margin-bottom: 0; }

a {
  color: var(--c-navy);
  text-decoration: none;
  transition: color var(--transition);
}
a:hover, a:focus-visible { color: var(--c-orange); }

:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: var(--sp-2) var(--sp-4);
  background: var(--c-navy);
  color: #fff;
}
.skip-link:focus { left: 0; color: #fff; }

.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;
}

/* --- Layout primitives ---------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--sp-8); }
.section--tight { padding-block: var(--sp-5); }
.section--flush { padding-block: 0; }

.section--navy {
  background: var(--c-navy);
  color: #fff;
}
/* Invert only the section's own headings. Cards keep a white surface, so
   their text must not inherit the inverted colour — scoping these to direct
   children of .container stops the leak. */
.section--navy > .container > .eyebrow { color: rgba(255, 255, 255, 0.60); }
.section--navy > .container > .heading,
.section--navy > .container > .prose   { color: #fff; }
.section--navy .card       { color: var(--c-text); }
.section--navy .card__title { color: var(--c-card-title); }
.section--navy .tile__title { color: #fff; }

.grid {
  display: grid;
  gap: var(--sp-6);
}
@media (min-width: 768px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1025px) {
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
  .grid--5 { grid-template-columns: repeat(5, 1fr); }
}
@media (min-width: 768px) and (max-width: 1024px) {
  .grid--4, .grid--5 { grid-template-columns: repeat(2, 1fr); }
}

/* --- Headings ------------------------------------------------------------- */

.eyebrow {
  font-family: var(--f-body);
  font-size: var(--fs-eyebrow);
  font-weight: 400;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--c-eyebrow);
  margin: 0 0 var(--sp-1);
}

.heading {
  font-family: var(--f-head);
  font-size: var(--fs-section);
  font-weight: 600;
  line-height: var(--lh-heading);
  color: var(--c-navy);
  margin: 0 0 var(--sp-5);
}
.heading:last-child { margin-bottom: 0; }

/* The live site wraps part of several headings in a <span> but never styles
   it. Given a two-tone treatment was clearly intended, the span gets the
   accent — the one deliberate departure from the current rendering. */
.heading span { color: var(--c-orange); }

.subheading {
  font-family: var(--f-head);
  font-size: var(--fs-sub);
  font-weight: 400;
  color: var(--c-navy);
  margin: 0 0 var(--sp-4);
}

.text-center { text-align: center; }

/*
 * Centred body copy still needs a readable measure. Across the full 1140px
 * container a paragraph runs to ~150 characters per line; centring then puts
 * every line at a different starting x, so the eye has to hunt for each new
 * line. Capping at 62ch lands in the 45-75 range that reads comfortably.
 * Headings and eyebrows are short and are deliberately left alone.
 */
/*
 * Body copy is capped at a readable measure wherever it appears. Across the
 * full 1140px container a paragraph runs to ~150 characters per line, well
 * past the 45-75 that reads comfortably.
 *
 * Centred text gets `margin-inline: auto` so the column stays centred; the
 * left-aligned case keeps its left edge and simply stops short of the right.
 *
 * Two selectors for the centred case because the class lands in two places:
 * heading_prose puts .text-center on the container and .prose on a child,
 * while steps, news_list, plans_table and contact_form put both on the same
 * element. A descendant selector alone silently misses the second group.
 */
.prose { max-width: 62ch; }

.text-center .prose,
.prose.text-center,
.cta .prose {          /* .cta centres via text-align, not the helper class */
  margin-inline: auto;
}

.prose { font-family: var(--f-head); line-height: var(--lh-prose); }
.prose ul { margin: 0 0 var(--prose-gap); padding-left: 1.25em; }
.prose li { margin-bottom: var(--sp-2); }
.prose strong { color: var(--c-navy); }

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-block;
  font-family: var(--f-body);
  font-size: 15px;
  line-height: 1.4;
  text-align: center;
  padding: 13px 26px;
  border: 0;
  border-radius: var(--radius-btn);
  background: var(--c-navy);
  color: #fff;
  transition: background-color var(--transition), color var(--transition);
}
.btn:hover, .btn:focus-visible {
  background: var(--c-blue-hover);
  color: #fff;
}

.btn--outline {
  padding: 12px 30px;
  border: 1px solid var(--c-navy);
  border-radius: var(--radius-btn-outline);
  background: var(--c-surface);
  color: var(--c-navy);
}
.btn--outline:hover, .btn--outline:focus-visible {
  background: var(--c-navy);
  color: #fff;
}

.btn--contact {
  font-size: var(--fs-body);
  padding: 8px 13px;
  border: 1px solid var(--c-steel);
  border-width: 0 1px 4px 1px;
  border-radius: 0;
  background: var(--c-surface);
  color: var(--c-steel);
}
.btn--contact:hover, .btn--contact:focus-visible {
  background: var(--c-orange);
  border-color: var(--c-orange);
  color: #fff;
}

/* --- Cards ---------------------------------------------------------------- */

.card {
  display: flex;
  flex-direction: column;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  box-shadow: var(--shadow-card);
  padding: var(--sp-2);
  transition: box-shadow var(--transition), transform var(--transition);
}
.card:hover { box-shadow: var(--shadow-hover); }

.card__media { margin: 0; }
.card__media img { width: 100%; }

.card__body {
  padding: var(--sp-4) var(--sp-2);
  display: flex;
  flex-direction: column;
  flex: 1;
}

.card__title {
  font-family: var(--f-head);
  font-size: var(--fs-card-title);
  font-weight: 600;
  line-height: 1.4;
  color: var(--c-card-title);
  margin: 0 0 var(--sp-3);
}

.card__text {
  font-size: var(--fs-body);
  line-height: var(--lh-card);
  margin: 0 0 var(--sp-4);
}
.card__text:last-child { margin-bottom: 0; }

.card__action { margin-top: auto; align-self: flex-start; }

/* --- Tiles (image + caption, linked) -------------------------------------- */

.tile { display: block; }
.tile__media { overflow: hidden; margin: 0 0 var(--sp-2); }
.tile__media img {
  width: 100%;
  transition: transform 0.5s var(--ease);
}
.tile:hover .tile__media img { transform: scale(1.04); }
.tile__title {
  font-family: var(--f-head);
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--c-navy);
  margin: var(--sp-4) 0 0;
  transition: color var(--transition);
}
.tile:hover .tile__title { color: var(--c-orange-link); }

/* --- Footer --------------------------------------------------------------- */

.site-footer {
  background: var(--c-navy-deep) url("../img/bg-footer.png") no-repeat bottom right;
  color: var(--c-footer-text);
  font-size: var(--fs-body);
  padding-block: var(--sp-9) var(--sp-7);
}
.site-footer a { color: var(--c-footer-text); }
.site-footer a:hover, .site-footer a:focus-visible { color: var(--c-orange); }

.footer-grid {
  display: grid;
  gap: var(--sp-7);
}
@media (min-width: 768px) {
  .footer-grid { grid-template-columns: 23.35% 51.8% 24.5%; }
}

.footer-heading {
  position: relative;
  font-family: var(--f-head);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.05em;
  line-height: 1.4;
  /* Was the same muted grey as the links below it, so it read as another list
     item rather than a heading. White plus an accent rule separates them. */
  color: #FFFFFF;
  margin: 0 0 var(--sp-5);
  padding-bottom: var(--sp-3);
}
.footer-heading::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 38px;
  height: 2px;
  background: var(--c-orange);
}

/*
 * Marks a link that leaves optrical.com. The arrow is decorative — the
 * accessible name comes from the aria-label on the same element — so it is
 * dimmed rather than coloured, and never wraps onto its own line.
 */
.ext {
  display: inline-block;
  margin-left: 3px;
  font-size: 0.85em;
  opacity: 0.7;
  white-space: nowrap;
}

.footer-menus { display: flex; gap: var(--sp-7); flex-wrap: wrap; }
.footer-menu { list-style: none; margin: 0; padding: 0; }
.footer-menu li { margin-bottom: var(--sp-2); }

.footer-contact { list-style: none; margin: 0; padding: 0; }
.footer-contact li {
  display: flex;
  align-items: center;
  gap: 13px;
  line-height: 40px;
}
.footer-contact .icon { width: 14px; color: var(--c-footer-text); flex: 0 0 14px; }

.footer-social {
  display: inline-flex;
  gap: var(--sp-1);
  margin-top: var(--sp-3);
}
.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  color: var(--c-footer-icon);
  transition: background-color var(--transition), color var(--transition);
}
.footer-social a:hover, .footer-social a:focus-visible {
  background: var(--c-orange-deep);
  color: #fff;
}

.footer-bar {
  background: var(--c-navy-black);
  border-top: 1px solid var(--c-footer-rule);
  color: var(--c-footer-text);
  text-align: center;
  padding-block: var(--sp-4);
  font-size: var(--fs-body);
}
.footer-bar p { margin: 0; }


/* --- Missing images ------------------------------------------------------- */
/* Anything referenced but not yet present in assets/ renders as a grey field
   carrying the expected path, so gaps are obvious and the filename is to hand.
   Nothing here has any effect once the file exists. */

.media-img { width: 100%; object-fit: cover; object-position: left top; }

/* Rendered at the file's own proportions — nothing cropped, nothing stretched.
   Used for screenshots and diagrams, where losing an edge loses meaning. */
.media-img--natural {
  height: auto;
  object-fit: contain;
  object-position: left top;
}

.img-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: var(--sp-3);
  text-align: center;
  color: var(--c-ph-text);
  background-color: var(--c-ph-bg);
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.55) 0 10px,
    rgba(255, 255, 255, 0)   10px 20px
  );
  border: 1px dashed var(--c-ph-border);
}
.img-ph__label {
  font-family: var(--f-body);
  font-size: 13px;
  line-height: 1.45;
  word-break: break-all;
  max-width: 100%;
}

/* Background-image blocks: banner, hero slide. */
[data-img-missing] {
  position: relative;
  background-color: var(--c-ph-bg-dark);
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.07) 0 14px,
    rgba(255, 255, 255, 0)   14px 28px
  );
}
[data-img-missing]::after {
  content: "missing: " attr(data-img-missing);
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  padding: 6px 12px;
  font-family: var(--f-body);
  font-size: 12px;
  line-height: 1.4;
  color: #fff;
  background: rgba(0, 0, 0, 0.55);
  word-break: break-all;
}


.footer-logo__img { width: 190px; }
.site-footer .img-ph { padding: 4px; }
.site-footer .img-ph__label { font-size: 10px; }

.footer-address {
  font-style: normal;
  line-height: 1.7;
  margin-top: var(--sp-3);
  color: var(--c-footer-text);
}

/* ===== header.css ===== */
/* ==========================================================================
   Optrical — header
   Two bands: a dark utility strip carrying the positioning line and the
   consumer-facing actions, and a white navigation row that sticks on scroll.
   Depends on tokens.css.
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--c-surface);
  /*
   * Scroll anchoring tries to keep the content under the reader steady when
   * something above it resizes — which is exactly what the utility strip
   * does on every collapse. The browser's correction and the strip's own
   * height change then chase each other. The JS thresholds below already
   * keep the page steady deliberately, so the automatic compensation is
   * turned off here rather than left to fight it.
   */
  overflow-anchor: none;
}

/*
 * Anything an anchor can land on clears the sticky row. Without this the
 * heading a fragment link targets ends up underneath the header.
 */
:target,
.section[id] { scroll-margin-top: 96px; }

/* --- Utility strip --------------------------------------------------------- */

.header-utility {
  background: var(--c-navy-deep);
  color: rgba(255, 255, 255, 0.72);
  font-size: 14px;
  overflow: hidden;
  max-height: 46px;
  transition: max-height 0.3s var(--ease), opacity 0.25s var(--ease);
}

.header-utility__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: 46px;
}

/* The positioning line does the balancing work in one sentence: films and
   digital services, named together, above everything else on the page. */
.header-utility__tag {
  font-family: var(--f-head);
  letter-spacing: 0.02em;
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.header-utility__tag b { color: #fff; font-weight: 600; }

.header-utility__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  flex: 0 0 auto;
}

.u-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px var(--sp-2);
  color: rgba(255, 255, 255, 0.78);
  font-family: var(--f-head);
  font-size: 14px;
  white-space: nowrap;
  border-radius: 3px;
  transition: color var(--transition), background-color var(--transition);
}
.u-link:hover, .u-link:focus-visible {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}
.u-link svg { width: 15px; height: 15px; flex: 0 0 15px; }

.u-link--icon { padding: 6px; }

/* Verify is the one consumer-facing action on a business site, so it gets
   the accent rather than blending into the other utility links. */
.u-verify {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  font-family: var(--f-head);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  color: #fff;
  background: var(--c-orange);
  border-radius: 3px;
  transition: background-color var(--transition), transform var(--transition);
}
.u-verify:hover, .u-verify:focus-visible {
  color: #fff;
  background: var(--c-orange-deep);
}
.u-verify svg { width: 15px; height: 15px; flex: 0 0 15px; }

/* --- Navigation row -------------------------------------------------------- */

.header-main { border-bottom: 1px solid var(--c-rule); background: var(--c-surface); }

.header-main__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: 86px;
  transition: min-height 0.3s var(--ease);
}

.site-logo { flex: 0 0 auto; margin-right: auto; }
.site-logo__img { width: 189px; }
.site-logo .img-ph { padding: 4px; }
.site-logo .img-ph__label { font-size: 10px; }

.header-cta { flex: 0 0 auto; }
.header-cta .btn {
  padding: 11px 24px;
  font-family: var(--f-head);
  font-weight: 600;
  font-size: 15px;
}

/* --- Sticky state ---------------------------------------------------------- */

.site-header[data-stuck="true"] .header-utility {
  max-height: 0;
  opacity: 0;
}
.site-header[data-stuck="true"] .header-main {
  box-shadow: 0 2px 20px rgba(2, 49, 81, 0.10);
  border-bottom-color: transparent;
}
.site-header[data-stuck="true"] .header-main__inner { min-height: 66px; }

/* --- Nav links ------------------------------------------------------------- */

.nav__list {
  display: flex;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__item { position: relative; }

.nav__link {
  position: relative;
  display: inline-block;
  font-family: var(--f-head);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--c-navy);
  padding: 10px 13px 12px;
  transition: color var(--transition);
}
.nav__link:hover, .nav__link:focus-visible { color: var(--c-navy); }

/* The underline shifts navy to orange as it draws in — a quiet nod to the
   colour-shifting micro-optic films the company actually makes. */
.nav__link::before {
  content: "";
  position: absolute;
  left: 13px;
  right: 13px;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--c-navy) 0%, var(--c-orange) 100%);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.35s var(--ease);
}
.nav__item:hover > .nav__link::before,
.nav__link:focus-visible::before,
.nav__item--current > .nav__link::before { transform: scaleX(1); }

.nav__item--current > .nav__link { color: var(--c-navy); font-weight: 600; }

.nav__expand { display: none; border: 0; background: transparent; color: var(--c-navy); padding: var(--sp-2); font-size: 12px; }

.nav-toggle {
  display: none;
  width: 46px;
  height: 46px;
  padding: 10px;
  border: 1px solid var(--c-rule);
  border-radius: var(--radius-btn);
  background: transparent;
  color: var(--c-navy);
}
.nav-toggle:hover { border-color: var(--c-steel); }

/* --- Dropdowns ------------------------------------------------------------- */

.nav__sub {
  list-style: none;
  margin: 0;
  padding: var(--sp-2) 0;
  min-width: 248px;
  background: var(--c-surface);
  /* No top edge: the hover underline already draws a line just above this
     panel, and a second rule a few pixels below it reads as a mistake. The
     shadow separates the panel from the header; the accent moves to the base. */
  border: 1px solid var(--c-rule);
  border-top: 0;
  border-bottom: 2px solid var(--c-orange);
  box-shadow: 0 14px 34px rgba(2, 49, 81, 0.14);
}
.nav__sublink {
  display: block;
  font-family: var(--f-head);
  font-size: 15px;
  color: var(--c-navy);
  padding: 10px var(--sp-4);
  border-left: 2px solid transparent;
  transition: background-color var(--transition), color var(--transition), border-color var(--transition);
}
.nav__sublink:hover, .nav__sublink:focus-visible {
  background: var(--c-panel);
  color: var(--c-navy);
  border-left-color: var(--c-orange);
}
.nav__sublink.is-current { color: var(--c-orange); font-weight: 600; border-left-color: var(--c-orange); }

@media (min-width: 1101px) {
  .nav__item--has-children > .nav__link { padding-right: 24px; }
  .nav__item--has-children > .nav__link::after {
    content: "";
    position: absolute;
    right: 12px;
    top: 50%;
    width: 6px;
    height: 6px;
    margin-top: -4px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
    opacity: 0.55;
    transition: transform var(--transition), opacity var(--transition);
  }
  .nav__item--has-children:hover > .nav__link::after { opacity: 1; transform: rotate(225deg); margin-top: -1px; }

  .nav__sub {
    position: absolute;
    top: 100%;
    left: 4px;
    z-index: 30;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity 0.22s var(--ease), transform 0.22s var(--ease), visibility 0.22s var(--ease);
  }
  .nav__item--has-children:hover > .nav__sub,
  .nav__item--has-children:focus-within > .nav__sub {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
  }
}

/* --- Below 1100px ---------------------------------------------------------- */

@media (max-width: 1100px) {
  .nav-toggle { display: inline-flex; align-items: center; justify-content: center; }

  .nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    background: var(--c-surface);
    border-top: 1px solid var(--c-rule);
    box-shadow: 0 16px 28px rgba(2, 49, 81, 0.12);
    max-height: calc(100vh - 120px);
    overflow-y: auto;
  }
  .nav[data-open="true"] { display: block; }

  .nav__list { flex-direction: column; align-items: stretch; }
  .nav__item { border-bottom: 1px solid var(--c-rule); }
  .nav__item--has-children { display: grid; grid-template-columns: 1fr auto; align-items: center; }

  .nav__link { padding: 15px var(--gutter); font-size: 16px; }
  .nav__link::before { display: none; }

  /*
   * The tap target was already 48px, but the chevron inside it was set at
   * 12px by the desktop rule and read as a stray speck next to 16px nav
   * links. Size and weight it so it is unmistakably a control, and give it a
   * tinted disc so the affordance is visible before anyone taps.
   */
  .nav__expand {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    margin-right: 6px;
    font-size: 20px;
    line-height: 1;
    color: var(--c-navy);
    border-radius: 50%;
    background: var(--c-panel);
    transition: transform var(--transition), background var(--transition);
  }
  .nav__expand > span { display: block; transform: translateY(-1px); }
  .nav__expand[aria-expanded="true"] {
    transform: rotate(180deg);
    background: var(--c-orange);
    color: #fff;
  }

  .nav__sub {
    grid-column: 1 / -1;
    display: none;
    border: 0;
    border-top: 1px solid var(--c-rule);
    border-bottom: 0;
    box-shadow: none;
    background: var(--c-panel);
    padding: var(--sp-1) 0;
    min-width: 0;
  }
  .nav__sub[data-open="true"] { display: block; }
  .nav__sublink { padding-left: var(--sp-7); }
}

@media (max-width: 860px) {
  .header-utility__tag { display: none; }
  .header-utility__inner { justify-content: flex-end; }
}
@media (max-width: 560px) {
  .u-link span, .u-verify span { display: none; }
  .u-verify { padding: 6px 10px; }
  .header-main__inner { min-height: 70px; }
  .header-cta .btn { padding: 9px 16px; font-size: 14px; }
  .site-logo__img { width: 150px; }
}

/* --- Dropdown group headings --------------------------------------------- */

.nav__group {
  margin: var(--sp-2) 0 4px;
  padding: 0 var(--sp-4);
  /* An empty group is a plain rule; a named one is a small caption. */
  border-top: 1px solid var(--c-rule);
  padding-top: var(--sp-2);
}
.nav__group:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.nav__group span {
  display: block;
  font-family: var(--f-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--c-eyebrow);
}
@media (max-width: 1100px) {
  .nav__group { padding-left: var(--sp-6); background: var(--c-panel-alt); }
}

/* --- Dropdown dividers ---------------------------------------------------- */
/* A rule with no caption. .nav__group carries its own border-top, so the two
   are never emitted back to back — prune() keeps only the last of a run. */

.nav__divider {
  height: 1px;
  margin: var(--sp-2) 0;
  background: var(--c-rule);
}
.nav__divider + .nav__group { border-top: 0; padding-top: 0; margin-top: 0; }

/* --- Entries that are not links ------------------------------------------- */
/* Same metrics as .nav__sublink so the column does not step in or out, but
   muted and inert: no hover, no pointer, no focus. */

.nav__sublink--static {
  color: var(--c-steel);
  cursor: default;
  font-weight: 600;
}

/* --- Badges --------------------------------------------------------------- */

.nav__badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--c-panel-alt);
  color: var(--c-navy);
  font-family: var(--f-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  vertical-align: 1px;
  white-space: nowrap;
}
@media (max-width: 1100px) {
  .nav__divider { margin-left: var(--gutter); margin-right: var(--gutter); }
}

/* ===== sections.css ===== */
/* ==========================================================================
   Optrical — section renderers
   One block per section type in app/sections/. Depends on tokens.css + base.css.
   ========================================================================== */

/* --- page_banner ---------------------------------------------------------- */

.banner {
  position: relative;
  display: flex;
  align-items: center;
  min-height: var(--banner-min-h);
  background: var(--c-navy) center / cover no-repeat;
  isolation: isolate;
}
.banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--c-navy);
  opacity: 0.5;
  z-index: -1;
}
.banner__title {
  font-family: var(--f-body);
  font-size: var(--fs-banner);
  font-weight: 600;
  line-height: 1.2;
  color: #fff;
  margin: 0;
}
@media (max-width: 767px) {
  .banner { min-height: 190px; }
  .banner__title { font-size: 30px; }
}

/* --- hero_simple ---------------------------------------------------------- */

/*
 * One still hero. Shares the banner's overlay approach so the two read as the
 * same family, but is taller and left-aligned: this one carries a headline,
 * a sentence and a call to action rather than a page title alone.
 */
.hero-simple {
  position: relative;
  display: flex;
  align-items: center;
  /*
   * 460, down from 560. The original height was set to clear a five-line
   * headline plus a standfirst plus a note under the button. The copy is two
   * lines now, and at 560 the surplus read as an empty band rather than as a
   * generous one.
   */
  min-height: 460px;
  background: var(--c-navy) center / cover no-repeat;
  isolation: isolate;
}
.hero-simple::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--c-navy);
  opacity: 0.55;
  z-index: -1;
}
.hero-simple[data-overlay="true"]::before { opacity: 0.7; }
.hero-simple__inner {
  max-width: 780px;
  padding-block: var(--sp-9);
  color: #fff;
}
.hero-simple__eyebrow { color: #fff; opacity: 0.85; }
.hero-simple__heading {
  font-family: var(--f-head);
  font-size: var(--fs-hero);
  font-weight: 700;
  line-height: 1.25;
  color: #fff;
  margin: 0 0 var(--sp-5);
  text-shadow: var(--text-shadow-hero);
}
.hero-simple__body {
  font-size: var(--fs-sub);
  line-height: 1.6;
  color: #fff;
}
.hero-simple__body p { color: #fff; }
.hero-simple__actions { margin-top: var(--sp-6); }
.hero-simple__note {
  margin-top: var(--sp-3);
  font-size: 15px;
  color: #fff;
  opacity: 0.8;
}
@media (max-width: 900px) {
  .hero-simple { min-height: 340px; }
  .hero-simple__heading { font-size: 30px; }
}

/* --- hero_slider ---------------------------------------------------------- */

.hero {
  position: relative;
  overflow: hidden;
  background: var(--c-navy);
}
.hero__track { display: grid; }
.hero__slide {
  grid-area: 1 / 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 500px;
  background: center / cover no-repeat;
  opacity: 0;
  transition: opacity 0.8s var(--ease);
  pointer-events: none;
}
.hero__slide[data-active="true"] { opacity: 1; pointer-events: auto; }
.hero__slide[data-overlay="true"]::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
}
/*
 * The captions cross-fade on their own clock, not the slide's.
 *
 * Every slide shares one grid cell, so a symmetric 0.8s opacity fade left the
 * outgoing and incoming captions both partly visible for several hundred ms —
 * "See it" over "Trust it" rendered as overlapping, illegible text. The
 * outgoing caption now clears first, and the incoming one waits for it. The
 * background images still cross-fade over the full 0.8s, which is what makes
 * the transition feel smooth; only the text is sequenced.
 */
.hero__slide .hero__caption {
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}
.hero__slide[data-active="true"] .hero__caption {
  opacity: 1;
  transition: opacity 0.4s var(--ease) 0.4s;
}
@media (prefers-reduced-motion: reduce) {
  .hero__slide,
  .hero__slide .hero__caption,
  .hero__slide[data-active="true"] .hero__caption { transition-duration: 0.01ms; transition-delay: 0s; }
}
.hero__caption {
  position: relative;
  max-width: 760px;
  padding: var(--sp-9) var(--sp-7);
  text-align: center;
  font-family: var(--f-head);
  font-size: var(--fs-hero);
  font-weight: 700;
  line-height: 1.5;
  letter-spacing: 1px;
  color: #fff;
  text-shadow: var(--text-shadow-hero);
}
@media (max-width: 900px) {
  .hero__slide { min-height: 320px; }
  .hero__caption { font-size: 29px; padding: var(--sp-6) var(--sp-4); }
}

.hero__dots {
  position: absolute;
  left: 0; right: 0; bottom: var(--sp-2);
  display: flex;
  justify-content: center;
  gap: 8px;
}
.hero__dot {
  width: 16px; height: 16px;
  padding: 0;
  border: 2px solid rgba(255, 255, 255, 0.5);
  border-radius: 50%;
  background: transparent;
  transition: background-color var(--transition), border-color var(--transition);
}
.hero__dot[aria-current="true"],
.hero__dot:hover { background: #fff; border-color: #fff; }

.hero__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px; height: 40px;
  border: 0;
  background: transparent;
  color: rgba(255, 255, 255, 0.8);
  font-size: 28px;
  line-height: 1;
}
.hero__arrow:hover { color: #fff; }
.hero__arrow--prev { left: 15px; }
.hero__arrow--next { right: 15px; }
@media (max-width: 900px) { .hero__arrow { display: none; } }

/* --- split ---------------------------------------------------------------- */

.split {
  display: grid;
  gap: var(--sp-7);
  align-items: center;
}
/*
 * Two columns from 768px up. Both children are vertically centred against
 * each other by `align-items: center` on .split above — the figure is a fixed
 * box and the body is whatever height its copy needs, so whichever is shorter
 * sits centred rather than hanging at the top of the row.
 *
 * Below this breakpoint the split is a single column and alignment does not
 * apply.
 */
@media (min-width: 768px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split[data-media="left"] .split__body  { order: 2; }
  .split[data-media="left"] .split__media { order: 1; }
}
/*
 * A split with no image is a single column, and its prose is capped rather
 * than run to the full 1140px — an unconstrained measure is the readability
 * problem the rest of the stylesheet already guards against. Centred, so it
 * does not read as a two-column layout that lost half its content.
 */
.split--text { grid-template-columns: 1fr; }   /* line 219 is earlier, so this wins on order */
.split--text .split__body { max-width: 72ch; margin-inline: auto; }

.split__body > :last-child { margin-bottom: 0; }
.split__cta { margin-top: var(--sp-5); }

/*
 * The figure is a fixed box — the same proportions a missing-image placeholder
 * occupies — so section heights stay consistent whether or not a file has
 * landed, and every split across the site presents the same size frame.
 *
 * The image inside is NOT scaled by default: it renders at its own pixel size,
 * anchored top-left, and anything past the edge is clipped by the figure. That
 * keeps screenshot text legible at 1:1 rather than shrunk to fit.
 *
 * The figure keeps its own height rather than stretching to match the copy
 * beside it, and sits vertically centred in the row — `align-self: center`
 * rather than `stretch` (which would distort the aspect-ratio box) or
 * `start` (which pinned it to the top whenever the copy ran taller).
 */
.split__media {
  position: relative;
  align-self: center;
  margin: 0;
  aspect-ratio: 567 / 378;
  overflow: hidden;
  background: var(--c-panel);
}
.split__media > .img-ph { width: 100%; height: 100%; }

/* Opt-in: fill the box, cropping the overflow. */
.split__media > .media-img--cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* Whole image visible, letterboxed against the figure background. */
.split__media > .media-img--contain {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
}
/*
 * Default. No scaling whatsoever — the image renders at its own pixel size,
 * centred in the figure, and anything past the edges is clipped by the
 * figure's overflow:hidden.
 *
 * Centring is deliberate: a mismatched image then shows an even margin (too
 * small) or loses all four edges equally (too large), which reads immediately
 * as "wrong size" rather than looking like an intentional top-left crop. That
 * makes the artwork problem visible so a correctly sized file can replace it.
 *
 * Absolute + translate rather than object-position, because at intrinsic size
 * the img is a block in normal flow — object-position only moves content
 * inside a box that has been given a size, which this one has not.
 */
.split__media > .media-img--actual {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: block;
  width: auto;
  height: auto;
  /*
   * Shrink-to-fit, not scale-to-fill. An image at or under the figure's size
   * still renders at exactly 1:1 — which is the whole point of this mode, and
   * why these are max-* rather than width/height. Anything larger is scaled
   * down until both axes fit, keeping its aspect ratio, so no edge is lost.
   * Previously this was max-width:none and the overflow was simply clipped,
   * which cost every oversized diagram its outer margins.
   */
  max-width: 100%;
  max-height: 100%;
  /*
   * `contain`, not `none`. The max-* rules above size the element, but
   * object-fit governs how the file is painted inside it: `none` paints at
   * intrinsic pixels and clips, which reintroduced the crop the moment the
   * element was made smaller than the image. `contain` never upscales past the
   * element's own box, so an image small enough to keep its natural box still
   * paints 1:1 and only oversized ones are reduced.
   */
  object-fit: contain;
}

/*
 * Letterbox fill. Whenever the image is fitted inside the figure rather than
 * filling it, the leftover band shows behind it.
 *
 * Pale grey, not the footer navy it used to be: most of the artwork fitted
 * this way is a diagram on a white ground, and against navy the band read as
 * a heavy mount around a small picture rather than as the edge of the frame.
 * Grey also states where the figure actually is, which white-on-white did not.
 *
 * The inset ring is what makes the boundary visible in the common case, where
 * the image scales to fill the box almost exactly and no band is left to see.
 * It is drawn on the figure rather than as a border so it costs no layout —
 * a real border would eat 2px out of an aspect-ratio box.
 *
 * :has() rather than a class on the figure, because the fit mode is decided by
 * media_img() on the image itself. Browsers without :has() keep --c-panel,
 * which is the previous behaviour and perfectly legible.
 */
.split__media:has(> .media-img--actual),
.split__media:has(> .media-img--contain) {
  background: var(--c-panel-alt);
}
/*
 * The outline goes on the image, not on the figure. An inset shadow on the
 * parent is painted underneath the absolutely positioned image, so in the
 * common case — artwork scaling to fill the box almost exactly — it would be
 * hidden by the very thing it is meant to outline. outline rather than border
 * so it costs no layout inside a box-sizing: border-box aspect-ratio frame,
 * and -1px offset keeps it flush inside the edge rather than straddling it.
 */
.split__media > .media-img--actual,
.split__media > .media-img--contain {
  outline: 1px solid var(--c-border);
  outline-offset: -1px;
}
.split__media::after { display: none; }
.split__media::after {
  content: "";
  position: absolute;
  right: -18px;
  bottom: -18px;
  width: 120px; height: 90px;
  z-index: -1;
  background-image: radial-gradient(var(--c-border) 1.5px, transparent 1.5px);
  background-size: 12px 12px;
}
@media (max-width: 767px) { .split__media::after { display: none; } }

/*
 * Zoomable figures. The button is added by site.js and covers the figure, so
 * the whole image is the hit area. Only the class is styled here — without
 * JS the class never appears and none of this applies.
 */
.split__media--zoomable { cursor: zoom-in; }
.split__media-zoom {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
}
/* A magnifier badge, so it reads as openable rather than as a dead image. */
.split__media-zoom::after {
  content: "⤢";
  position: absolute;
  right: 10px;
  bottom: 10px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(2, 49, 81, 0.78);
  color: #fff;
  font-size: 15px;
  line-height: 1;
  opacity: 0;
  transition: opacity var(--transition);
}
.split__media--zoomable:hover .split__media-zoom::after,
.split__media-zoom:focus-visible::after { opacity: 1; }
.split__media-zoom:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: -2px;
}
/* Touch has no hover, so the badge is always visible there. */
@media (hover: none) {
  .split__media-zoom::after { opacity: 1; }
}

/* --- lightbox -------------------------------------------------------------- */

/*
 * The dialog is a flex column: image area first, caption pinned beneath it.
 * Sizing the panel to its content (fit-content) rather than a fixed width
 * stops a small image from sitting in a large empty box, while the max-*
 * values keep a big one inside the viewport.
 */
.lightbox {
  position: relative;         /* positioning context for the close button */
  max-width: min(94vw, 1400px);
  max-height: 92vh;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: var(--c-surface);
  overflow: hidden;           /* the image area scrolls, not the panel */
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4);
  /* Centre the panel itself — dialog defaults to margin:auto only when the
     UA stylesheet is left alone, and max-height above can defeat it. */
  margin: auto;
}
.lightbox::backdrop { background: rgba(0, 0, 0, 0.72); }

/*
 * Lock the page behind the modal. Without this the background scrolls under
 * the dialog on touch, and closing leaves the reader somewhere they never
 * chose. `position: fixed` with a negative top offset (set in JS) holds the
 * exact scroll position rather than snapping to the top, which is what a bare
 * `overflow: hidden` does on iOS.
 */
body.has-lightbox {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

.lightbox__body {
  display: flex;
  flex-direction: column;
  max-height: 92vh;
}

/*
 * The image sits in a padded, centred area. It scales DOWN to fit both axes
 * but is never enlarged past 1:1 — the point of the lightbox is to read
 * detail at native resolution, not to blow a small image up.
 */
.lightbox__figure {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: var(--sp-6);
  min-height: 0;              /* lets the flex child shrink instead of overflow */
  overflow: auto;
  background: var(--c-panel);
}
.lightbox__img {
  display: block;
  max-width: 100%;
  max-height: calc(92vh - 140px);   /* leaves room for padding + caption */
  width: auto;
  height: auto;
  object-fit: contain;
}
.lightbox__cap {
  flex: none;
  margin: 0;
  padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--c-border);
  font-size: 14px;
  line-height: 1.6;
  color: var(--c-text-muted);
  background: var(--c-surface);
}
/*
 * Fixed to the panel corner rather than floated into the content flow, so it
 * never sits on top of the image or pushes it off-centre.
 */
.lightbox__close {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: rgba(2, 49, 81, 0.82);
  color: #fff;
  font-size: 21px;
  line-height: 1;
  cursor: pointer;
}
@media (max-width: 640px) {
  .lightbox { max-width: 96vw; }
  .lightbox__figure { padding: var(--sp-4); }
  .lightbox__img { max-height: calc(92vh - 120px); }
}
.lightbox__close:hover { background: var(--c-navy); }
.lightbox__close:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: 2px;
}

/* --- rich_list ------------------------------------------------------------ */

/*
 * The list and the intro above it form one column: same width, same centred
 * position, so their left edges line up.
 *
 * Left at full container width the items ran to ~150 characters — the same
 * readability problem as unconstrained prose — while the intro was already
 * capped, so the two blocks looked unrelated.
 *
 * 70ch rather than prose's 62ch because each line carries a bold lead plus its
 * explanation. The intro is widened to match, scoped to this section only.
 */
.rich-list,
.section .rich-list-intro {
  max-width: 70ch;
  margin-inline: auto;
}
.rich-list {
  list-style: none;
  padding: 0;
  font-family: var(--f-head);
  line-height: var(--lh-prose);
}
.rich-list li {
  position: relative;
  padding-left: 1.4em;
  margin-bottom: var(--sp-2);
}
.rich-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(var(--lh-prose) / 2 - 3px);
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--c-orange);
}
.rich-list strong { color: var(--c-navy); }

/* --- value_cards ---------------------------------------------------------- */

.value-card {
  border: 1px solid var(--c-border);
  background: var(--c-surface);
  padding: var(--sp-6);
}
/*
 * The icon slot takes either an inline SVG (sized in px, inherits the accent
 * colour) or a literal glyph such as an emoji. The wrapper carries only the
 * spacing so the two cases stay the same height in a row of cards.
 */
.value-card__icon {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--c-orange);
  margin-bottom: var(--sp-4);
}
.value-card__icon > svg { width: 44px; height: 44px; }
/*
 * Emoji need the system colour fonts named explicitly — a web font earlier in
 * the chain can otherwise suppress the glyph on Android Chrome and some iOS
 * WebViews.
 */
.value-card__glyph {
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  font-size: 34px;
  line-height: 1;
}
.value-card__title {
  font-family: var(--f-head);
  font-size: var(--fs-card-title);
  font-weight: 600;
  color: var(--c-navy);
  margin: 0 0 var(--sp-3);
}

/* --- team_grid ------------------------------------------------------------ */

.team-card {
  border: 1px solid var(--c-border);
  background: var(--c-surface);
  padding: var(--sp-6) var(--sp-4);
  text-align: center;
}
.team-card__photo {
  width: 160px; height: 160px;
  margin: 0 auto var(--sp-4);
  border-radius: 50%;
  overflow: hidden;
}
.team-card__photo img { width: 100%; height: 100%; object-fit: cover; }
.team-card__name {
  font-family: var(--f-head);
  font-size: 20px;
  font-weight: 600;
  color: var(--c-navy);
  margin: 0 0 var(--sp-1);
}
.team-card__role {
  font-weight: 600;
  color: var(--c-navy);
  margin: 0 0 var(--sp-3);
}
/*
 * Bios vary from ~170 to ~590 characters. A grid row is as tall as its tallest
 * cell, so one long bio inflated all four cards and left the short ones sitting
 * in empty space.
 *
 * The bio is capped at roughly eight lines and scrolls within that box. Height
 * is set in `em` so it tracks the line-height rather than assuming a pixel
 * size — the cap stays eight lines whatever the font scales to.
 */
.team-card__bio {
  font-size: 15px;
  line-height: var(--lh-card);
  text-align: left;
  max-height: calc(var(--lh-card) * 8);
  overflow-y: auto;
  /*
   * Scrollbar only while pointing at the card. Always-on gutters put a grey
   * bar down every card including the short ones that do not overflow, which
   * reads as clutter. `stable` reserves the space either way so the text does
   * not reflow when the bar appears.
   */
  scrollbar-width: none;
  scrollbar-gutter: stable;
  overscroll-behavior: contain;   /* stop the page scrolling once the bio ends */
}
.team-card:hover .team-card__bio,
.team-card__bio:focus-visible {
  scrollbar-width: thin;
}
/* It is focusable (see team_grid.php), so it needs a visible focus ring. */
.team-card__bio:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: 3px;
}
/*
 * Touch has no hover, so the scrollbar hint never appears and the fade is the
 * only affordance. Swiping the bio works regardless — this just keeps the
 * scrollbar visible there instead of hidden behind a hover that never fires.
 */
@media (hover: none) {
  .team-card__bio { scrollbar-width: thin; }
  .team-card__bio::-webkit-scrollbar-thumb { background: var(--c-border); }
}
.team-card__bio::-webkit-scrollbar { width: 6px; }
.team-card__bio::-webkit-scrollbar-thumb { background: transparent; border-radius: 3px; }
.team-card:hover .team-card__bio::-webkit-scrollbar-thumb,
.team-card__bio:focus-visible::-webkit-scrollbar-thumb { background: var(--c-border); }

/*
 * A soft fade at the bottom edge signals there is more to read. It is removed
 * once the reader scrolls, using an animation timeline where supported; older
 * browsers simply keep the hint, which is harmless.
 */
.team-card__bio {
  --fade: linear-gradient(to bottom, #000 calc(100% - 22px), transparent 100%);
}
@supports (animation-timeline: scroll()) {
  .team-card__bio { mask-image: var(--fade); }
  .team-card__bio:hover, .team-card__bio:focus-visible { mask-image: none; }
}

/* --- cta ------------------------------------------------------------------ */

.cta { text-align: center; }
.cta__contact {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-4) var(--sp-6);
  margin-top: var(--sp-5);
}
.cta__contact span { display: inline-flex; align-items: center; gap: 8px; }

/*
 * The secondary way out of the call to action — the long-form page, for the
 * reader who wants the whole argument before making contact. Deliberately
 * quieter than the copy above it: it is an alternative to the ask, and at
 * equal weight it competes with the thing the section exists to do.
 */
.cta__aside {
  margin-top: var(--sp-4);
  font-size: 15px;
  color: var(--c-text-muted);
}

/* --- steps ---------------------------------------------------------------- */

.steps {
  list-style: none;
  counter-reset: step;
  margin: var(--sp-6) 0 0;
  padding: 0;
  display: grid;
  gap: var(--sp-6);
}
@media (min-width: 768px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.step { position: relative; padding-top: var(--sp-5); border-top: 2px solid var(--c-border); }
.step__num {
  display: block;
  font-family: var(--f-body);
  font-size: 13px;
  letter-spacing: 0.12em;
  color: var(--c-orange);
  margin-bottom: var(--sp-2);
}
.step__title {
  font-family: var(--f-head);
  font-size: var(--fs-card-title);
  font-weight: 600;
  color: var(--c-navy);
  margin: 0 0 var(--sp-2);
}
.step__body { font-size: 15px; line-height: var(--lh-card); margin: 0; }

/* --- plans ---------------------------------------------------------------- */

.plan {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--c-border);
  background: var(--c-surface);
  padding: var(--sp-6) var(--sp-5);
}
.plan--featured { border-color: var(--c-navy); box-shadow: var(--shadow-card); }
.plan__name {
  font-family: var(--f-head);
  font-size: 20px;
  font-weight: 600;
  color: var(--c-navy);
  margin: 0 0 var(--sp-2);
}
.plan__blurb { font-size: 15px; line-height: var(--lh-card); margin: 0 0 var(--sp-4); }
.plan__features {
  list-style: none;
  margin: 0 0 var(--sp-5);
  padding: 0;
  font-size: 15px;
  line-height: 1.6;
  flex: 1;
}
.plan__features li { position: relative; padding-left: 1.3em; margin-bottom: var(--sp-2); }
.plan__features li::before {
  content: "";
  position: absolute; left: 0; top: 0.55em;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--c-orange);
}
.plan__cta { align-self: flex-start; }
.plans__note { margin-top: var(--sp-6); font-size: 15px; }

/* --- contact -------------------------------------------------------------- */

.contact-grid { display: grid; gap: var(--sp-7); margin-top: var(--sp-6); }
@media (min-width: 768px) { .contact-grid { grid-template-columns: 1.4fr 1fr; } }

.contact-details__item { margin-bottom: var(--sp-5); }
.contact-details__label {
  font-family: var(--f-body);
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-eyebrow);
  margin: 0 0 4px;
}
.contact-details__value { margin: 0; font-size: var(--fs-body); line-height: 1.6; }

.form__row { display: flex; flex-direction: column; gap: 5px; margin: 0 0 var(--sp-3); }
.form__row label { font-size: 15px; color: var(--c-navy); font-weight: 600; }
.form__row input, .form__row textarea, .form__row select {
  width: 100%;
  padding: 9px 13px;
  border: 1px solid var(--c-field-border);
  border-radius: var(--radius-btn);
  background: #fff;
  font-family: inherit;
  font-size: var(--fs-body);
  line-height: 1.5;
  transition: border-color var(--transition);
}

/*
 * Name and email share a row on anything wider than a phone. Below 560px the
 * grid collapses to one column and they stack, which is what a thumb wants.
 */
.form__pair { display: grid; gap: 0 var(--sp-4); }
@media (min-width: 560px) { .form__pair { grid-template-columns: 1fr 1fr; } }

/*
 * The native select arrow is inconsistent across platforms and sits oddly
 * against the bordered inputs, so it is replaced with an inline SVG chevron.
 * Extra right padding keeps long option text clear of it.
 */
.form__row select {
  appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23023151' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  cursor: pointer;
}
.form__submit { margin: var(--sp-4) 0 0; }
.form__row input:focus, .form__row textarea:focus, .form__row select:focus {
  border-color: var(--c-navy);
  outline: 2px solid rgba(2, 49, 81, 0.15);
  outline-offset: 0;
}
.form__row textarea { resize: vertical; }
.form__err { font-size: 14px; color: var(--c-error); }
.form__trap { position: absolute; left: -9999px; }

.notice {
  padding: var(--sp-3) var(--sp-4);
  border-left: 4px solid;
  margin: 0 0 var(--sp-5);
  font-size: 15px;
  line-height: 1.6;
}
.notice--ok   { border-color: var(--c-ok); background: var(--c-ok-bg); }
.notice--warn { border-color: var(--c-orange); background: var(--c-notice-soon-bg); }

/* --- Concept card icons --------------------------------------------------- */

.card__icon {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: var(--sp-5) var(--sp-2) var(--sp-1);
}
.card-icon { width: 40px; height: 40px; color: var(--c-orange); }
.section--navy .card-icon { color: var(--c-orange); }

/* --- Announcement band ---------------------------------------------------- */

/*
 * Three kinds: soon (default), info and warn. Each states its own accent and
 * surface rather than inheriting one from the base rule, so adding a fourth
 * does not depend on knowing which kind the base happens to look like.
 */
.notice-band {
  position: relative;
  padding: var(--sp-7) var(--sp-6);
  border: 1px solid var(--c-border);
  border-left: 4px solid var(--c-notice-soon);
  background: var(--c-notice-soon-bg);
  box-shadow: var(--shadow-card);
}
.notice-band--soon { border-left-color: var(--c-notice-soon); background: var(--c-notice-soon-bg); }
.notice-band--info { border-left-color: var(--c-notice-info); background: var(--c-notice-info-bg); }
.notice-band--warn { border-left-color: var(--c-notice-warn); background: var(--c-notice-warn-bg); }

.notice-band__label {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--f-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-orange-deep);
  margin: 0 0 var(--sp-3);
}
.notice-band--soon .notice-band__label { color: var(--c-orange-deep); }
.notice-band--info .notice-band__label { color: var(--c-notice-info); }
.notice-band--warn .notice-band__label { color: var(--c-notice-warn); }

.notice-band__dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: currentColor;   /* inherits the label colour, so it matches the kind */
  box-shadow: 0 0 0 0 rgba(242, 100, 41, 0.55);
  animation: notice-pulse 2.4s infinite;
}
@keyframes notice-pulse {
  70%  { box-shadow: 0 0 0 11px rgba(242, 100, 41, 0); }
  100% { box-shadow: 0 0 0 0 rgba(242, 100, 41, 0); }
}
@media (prefers-reduced-motion: reduce) { .notice-band__dot { animation: none; } }

.notice-band__heading {
  font-family: var(--f-head);
  font-size: 30px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--c-navy);
  margin: 0 0 var(--sp-4);
}
.notice-band__body { font-family: var(--f-head); line-height: var(--lh-prose); max-width: 62ch; }
.notice-band__cta  { margin: var(--sp-5) 0 0; }

@media (max-width: 767px) {
  .notice-band { padding: var(--sp-5) var(--sp-4); }
  .notice-band__heading { font-size: 23px; }
}
