@tailwind base; @tailwind components; @tailwind utilities; * { margin: 0; padding: 0; box-sizing: border-box; } html { scroll-behavior: smooth; overflow-x: hidden; } body { font-family: 'Inter', sans-serif; color: #0F172A; background-color: #F8FAFC; line-height: 1.5; -webkit-font-smoothing: antialiased; overflow-x: hidden; } img { max-width: 100%; display: block; } .brand-logo-on-dark { filter: drop-shadow(0 1px 0 rgba(255, 255, 255, 0.6)) drop-shadow(1px 0 0 rgba(255, 255, 255, 0.45)); } a { color: #0EA5E9; text-decoration: none; } a:hover { text-decoration: underline; } /* Container - custom max-width */ .container { max-width: 1280px; margin: 0 auto; padding: 0 16px; } /* Section spacing - mobile first */ .section { padding: 4rem 0; } /* Desktop section spacing */ @media (min-width: 1024px) { .section { padding: 6rem 0; } } /* Hero section styling */ .hero { min-height: 70vh; display: flex; align-items: center; background: linear-gradient(135deg, #0B2A3C 0%, #071A2A 100%); color: white; padding: 4rem 0 5rem; } /* Light section background */ .section-alt { background: #EEF6FB; } @layer base { /* * Visible keyboard focus — WCAG 2.4.7 (Focus Visible) and 1.4.11 (Non-text * Contrast, which wants 3:1 for the indicator itself). * * Two rings, not one, and that is the whole point. This is a light-first * design with dark navy bands through it, so no single colour clears 3:1 * everywhere: primary-cyan manages 6.26:1 on navy and only 2.38:1 on white, * which is why the obvious `ring-primary-cyan` was not used. The white ring * carries the dark sections and the navy ring carries the light ones, and on * every background in the palette at least one of them clears 3:1 by a wide * margin — the worst case is 13.62:1. * * box-shadow rather than outline so both rings stack predictably and follow * each element's own border-radius. The transparent outline is the standard * escape hatch for Windows High Contrast / forced-colors mode, where * box-shadow is discarded and an outline is not. * * :focus-visible, not :focus, so a mouse click does not leave a ring behind. * :where() keeps specificity at zero, so any component can still override it. */ :where(a, button, [role="button"], summary, input, select, textarea):focus-visible { box-shadow: 0 0 0 2px #FFFFFF, 0 0 0 5px #0B2A3C; outline: 2px solid transparent; outline-offset: 2px; } } @layer components { /* * A standalone text link is 17 to 20px tall. A finger needs about 32, and the * device sweep found 491 links under that across the site: every footer * column, the privacy contents, the related-services lists, the back links. * * This grows the hit box by 8px above and below and then takes those 8px back * out of the layout, so the line the link sits on does not move. * * **The list it sits in must leave at least 16px between rows.** The negative * margin does not shrink the box, only its effect on layout, so at the 8px * spacing these lists used to have, each link's box reached 8px into a gap the * neighbour was already reaching 8px into. They overlapped, hit-testing gave * the whole gap to whichever painted last, and getBoundingClientRect still * read 33px — a checker satisfied by a target that was not really there. Every * caller therefore pairs this with space-y-4 or gap-y-4, which makes the row * pitch 33 and the boxes tile exactly. * * Not for a link inside a sentence: WCAG 2.5.8 exempts those, and the padding * would reach into the lines above and below it. * * `display` is deliberately inline-block rather than a padding-only rule. * Vertical padding on an inline box is painted and hit-tested but does not * enter the line box, so an inline link would report a taller rect while * overlapping its neighbours. Any caller that needs a different box (the * "Learn more" links are inline-flex) sets it with a Tailwind utility, which * wins on layer order. */ .tap-target { display: inline-block; padding-block: 0.5rem; margin-block: -0.5rem; } /* * reCAPTCHA v2's checkbox iframe is a fixed 304px and Google does not allow * it to be resized. Below ~360px that overflows the viewport and gets sliced * off by the overflow-x:hidden above — taking the branding and the privacy * and terms links with it. Scaling is the only lever available. * * The height is reduced by the same factor because transform does not affect * layout: without it the wrapper would keep reserving the full-size box and * the form would gain a strip of dead space under the widget. See #215. */ @media (max-width: 360px) { .recaptcha-scale { transform: scale(0.85); transform-origin: 0 0; height: 66px; /* 78px widget * 0.85, so the box matches what is drawn */ } } }