Queue-North-Website/src/index.css

159 lines
4.9 KiB
CSS

@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 */
}
}
}