/*
 * Legibility corrections over the Webflow export.
 *
 * Loaded on every page, after webflow.css, so these win on equal specificity.
 * Only for defects that make text unreadable — not a place to restyle the site.
 *
 * `.paragraph.is-large` is set to var(--color-11), #afd3f0, a pale blue meant to
 * sit on a dark ground. It is used 1,399 times across 161 pages, and measured
 * against the ground actually painted behind it, exactly one of those uses works:
 *
 *   dark navy hero, book pages   11.03:1   passes
 *   green service cards (1,384)   2.07:1   fails
 *   about-us body copy                1.20:1   fails
 *   contact hours panel               2.26:1   fails
 *   providers panels             2.26 / 2.74  fails
 *
 * All of it is 16.5px at weight 400, so WCAG AA wants 4.5:1 for every one. The
 * default therefore becomes the clinic's own ink, which clears the bar on each
 * failing ground (4.80:1 on the green cards, 11.84:1 on the light blue), and the
 * pale blue is kept where it was right in the first place.
 *
 * The live Webflow site has the same defect. This is a deliberate departure from
 * strict parity, recorded in docs/adr/0009-legibility-over-parity.md.
 */

.paragraph.is-large {
  color: #0b2540;
}

/* The one ground the pale blue was designed for. */
.hero-4 .paragraph.is-large {
  color: #afd3f0;
}

/*
 * `.paragraph.is-medium` has the same defect with the sibling pale blue,
 * var(--color-10), #9ecbee, wherever it sits on a light ground: 1.46:1 on the
 * light blue. It is used 43 times on 8 pages, and 11 of those uses are light:
 * the contact page's intro, address and hours, the about-us contact dropdown
 * (gone since 2026-10-03, when /about-us took the shared header — ADR-0004,
 * "Re-porting /about-us"; the rule is generic and stays), and the intro
 * paragraph on /about-us and /services. The ink measures 11.8:1 to 13.2:1 on
 * each. Raised by the marketing team on 2026-09-29 (the contact page's
 * address and hours were the first they saw).
 */
.paragraph.is-medium {
  color: #0b2540;
}

/*
 * The other 32 uses are on dark photo cards, where the ink measured 1.0:1 to
 * 2.6:1, invisible: `.service-3` on /services (nine, five of them in tabs) and
 * /counselling-psychotherapy (twelve), and `.service-4` on /assessments (five)
 * and in the "Other Assessments" band of the autism, psychoeducation and
 * adhd-add-assessment pages (two each). Their ground is a photograph, darkened
 * from the left by a navy multiply gradient and seen through a nearly clear
 * glass panel. None of that is a background colour, so a check that walks
 * computed `background-color` up the tree reads the page's white. Measure these
 * from pixels, at phone width too, where the lighter parts of the photographs
 * come under the text.
 *
 * The pale blue was not enough here either. Through the `.opacity-80` wrapper
 * it reaches only about 2.3:1 on the lighter photographs, and no colour gets to
 * 4.5:1 through 80% opacity; white stops at about 3.7:1. So inside these cards
 * the paragraph is white and the wrapper is not dimmed. Averaged over each
 * paragraph's box, that is 4.76:1 or better at 1440 and at 390 wide.
 * Photographs are uneven, though. Where a light patch comes under a few words,
 * white alone left 1% of the text's 40 px cells at 1440 and 9% at 390 below
 * 4.5:1, down to 2.0:1. No text colour can lift those, so the glass is darker
 * as well (below).
 * The live Webflow site still shows the pale blue at 80% on the clear glass;
 * ADR-0009 records the departure.
 */
.service-3-link-block .paragraph.is-medium,
.service-4-link-block .paragraph.is-medium {
  color: #fff;
}

.service-3-link-block .opacity-80,
.service-4-link-block .opacity-80 {
  opacity: 1;
}

/*
 * The darker glass: 40% of the navy --color-1 (#011626), layered as an image
 * over Webflow's own green glass (--alt-color-10-opacity), which stays, as do
 * its border and blur. It is the one panel these cards have, so the title,
 * the eyebrow and the "See More" label sit on it too. With it, every 40 px
 * cell along the subtitles clears 4.5:1 at 1440 and at 390, the lowest at
 * 4.69:1 (Parent Training on /services, 390 wide), and so does every cell of
 * the "See More" labels. The mint titles gain as well. At phone width a few
 * of their cells stayed under the 3:1 that large text needs, so below 480px
 * the glass is darker still (the next rule).
 */
.service-3-content,
.service-4-layout {
  background-image: linear-gradient(rgb(1 22 38 / 40%), rgb(1 22 38 / 40%));
}

/*
 * On phones the glass is darker: 65% of the navy below 480px, not 40%. The
 * navy multiply gradient over each photograph darkens it from the left only,
 * and below 480px Webflow stretches the panel across the card, so the ends of
 * the title lines sit over the photograph's lighter right side. On the 40%
 * glass, 18 of the mint titles' 313 cells at 390 wide stayed under 3:1, the
 * lowest at 1.69:1 (Attachment-Informed Therapy, /counselling-psychotherapy).
 * On 65% none does. The lowest is 3.24:1 at 390, and 3.17:1 at 375, the
 * lowest of the six phone widths measured from 360 to 479. The mint stays.
 * From 480px up nothing changes, and some title cells there are still under
 * 3:1 (ticket 33). `screen and` matches Webflow's own 479px band, so the two
 * switch at the same width.
 */
@media screen and (max-width: 479px) {
  .service-3-content,
  .service-4-layout {
    background-image: linear-gradient(rgb(1 22 38 / 65%), rgb(1 22 38 / 65%));
  }
}

/*
 * `.service-4-button-title` ("See More") is `display: none` at 992px and up,
 * with no `:hover` rule or interaction anywhere that ever turns it back on —
 * checked directly in webflow.css and the page's data-w-id bindings. Below
 * 991px a media query already restores it. So on every normal desktop width
 * the card's only visible control is a bare arrow inside a full-size glass
 * panel still padded and sized for a label that never renders: the button
 * that was designed to read "SEE MORE ↓" instead reads as an unlabelled,
 * oversized box.
 *
 * This is the assessments index and the "Other Assessments" band on the
 * autism, psychoeducation and adhd-add-assessment pages. Restoring the label
 * needs no other change: `.service-4-button` keeps the same flex-column,
 * 20em, 3em-padding box from 992px up, sized for the label already.
 *
 * The live Webflow site has the same defect. This is a deliberate departure
 * from strict parity, recorded in docs/adr/0018-service-card-button-label.md.
 */

.service-4-button-title {
  display: block;
  position: relative;
}

/*
 * The hero's text waited for Webflow's interaction runtime.
 *
 * Every ported hero writes its eyebrow, heading, lede and button block with
 * `style="opacity:0"`, for the runtime to fade and slide in on scroll-into-view
 * — which, for the hero, is at once. The runtime lives in a 562 KB chunk the
 * page script injects after DOMContentLoaded, and on a slow connection that
 * request queues behind everything else the page fetches: on /about-us, four
 * background videos. Measured at 400 kbit/s with a 400 ms round trip, the
 * heading of /providers appeared 10.7 s after DOMContentLoaded and the heading
 * of /about-us not within 30 s. Once the page-load overlay was gone (above, in
 * ADR-0009), that reader saw a photograph with no words on it.
 *
 * lib/hero-visible.js marks each of those elements `data-hero-visible` in the
 * output. Both declarations are `!important` on purpose: the first beats the
 * inline `opacity:0` the template carries, and both beat what the runtime
 * writes inline when its chunk finally arrives — its slideInBottom preset sets
 * opacity 0 and translateY(100px) and animates them away, which over the hero
 * would blink the words out and slide them back in. With these rules it runs
 * and changes nothing the reader sees. Nothing below the hero is touched; those
 * animations are kept. No hero class in webflow.css has a transform of its
 * own, so `transform:none` removes only the animation's.
 *
 * The live Webflow site has the same defect. This is a deliberate departure
 * from strict parity, recorded in docs/adr/0009-legibility-over-parity.md
 * (2026-10-04).
 */

[data-hero-visible] {
  opacity: 1 !important;
  transform: none !important;
}

/*
 * ---------------------------------------------------------------------------
 * 2026-10-04: type sizes, from the pre-migration audit (§4.1)
 * ---------------------------------------------------------------------------
 *
 * Webflow sizes the whole site in em from `body { font-size: .833vw }`, with
 * a fixed 11px floor at 991px and under and from 1440px up, and 13px from
 * 1920px. Between 992px and 1439px the floor is missing: an iPad on its side
 * (1024px) gets an 8.53px body, and everything scales with it. Measured at
 * 1024 on the built site before this rule: paragraphs 12.79–13.65px, form
 * labels 11.94px, the "Required" tags 8.53px, breadcrumbs 6.82px, footer
 * links 12.79px, the search field 12.8px. The same floor the other bands
 * have, `max(.833vw, 11px)`, lifts them to the sizes a 1440px desktop shows:
 * measured after, paragraphs 16.5–24.2px, labels 14px (the rule below),
 * "Required" 11px, footer links 16.5px, the article body 17.6px.
 *
 * Only to 1199px, not 1439px. From 1200px the header shows its eight links,
 * sized by their own `.833vw` and already a pixel tight at 1200 (ADR-0012
 * hands 992–1199px to the MENU button for that reason). A larger body there
 * widens the BOOK APPOINTMENT button beside them, which is sized by the
 * body, and at 1200 "SERVICES" and "COUNSELLING" lost their first letter.
 * Between 1200 and 1439px .833vw is 10 to 12px, paragraphs 17 to 20px, and
 * ADR-0012's rule holds: nothing changes at 1200px and up. Em-based layouts
 * in the band grow with the body; the pages were checked at 1024 after.
 */
@media screen and (min-width: 992px) and (max-width: 1199px) {
  body {
    font-size: max(0.833vw, 11px);
  }
}

/*
 * Breadcrumbs are `.8em` of an `.833vw` body: 6.82px at 1024 and 8.8px on
 * phones and tablets. 12px, the smallest the site sets anywhere else, on
 * every touch-screen width; from 1200px they stay as the desktop pages were
 * signed off.
 */
@media screen and (max-width: 1199px) {
  .breadcrumb-text {
    font-size: max(0.8em, 12px);
  }
}

/*
 * Body copy under 16px on phones. Webflow's 479px band sets these smaller
 * than its own 16.5px paragraph: `.section-intro-dark` 1.3em (14.3px),
 * `.paragraph-24` and `.sub-heading-hero` 1.25em (13.75px, the counselling
 * intro), `.testimonial-card-body` a fixed 15px, and the Assessment pages'
 * "What's included" items (`.identify-item-text`, 14.3px). Each is a
 * paragraph a parent reads on a phone, so each becomes 16px. Measured at 375
 * on /assessment/autism/ and /counselling-psychotherapy/ before and after.
 */
@media screen and (max-width: 767px) {
  .section-intro-dark,
  .identify-item-text,
  .paragraph-24,
  .sub-heading-hero,
  .testimonial-card-body,
  .testimonial-card-body-2 {
    font-size: 16px;
  }
}

/*
 * The enquiry forms' labels on phones. Below 768px `.form-block` is .8em, so
 * `.field-label` (1.5em of its field wrap) is 13.2px and `.field-label-
 * required` ("Required", at the field's right; 1em of the body) is 8.8px. The
 * label becomes 14px, and the tag 11px, in a box the same height and place as
 * before (its offsets were in its own em, so they are fixed here in px: 2em
 * line-height at 8.8px is 17.6px, 3.2em from the bottom is 28px, 2em from the
 * right is 17.6px). Only below 768px: from 768px the body is 11px (Webflow's
 * own floor to 991px, the rule above to 1199px, .833vw from 1200px), which
 * already makes the tag 11px and the label 15.4–16.5px, at Webflow's own
 * offsets (3.2em = 35.2px from the bottom, 2em = 22px from the right). The
 * first cut of this rule ran to 1199px and, with these px offsets, moved the
 * tag down and right on tablets (review of 2026-10-04).
 */
@media screen and (max-width: 767px) {
  label.field-label {
    font-size: 14px;
  }
  .field-label-required {
    font-size: 11px;
    line-height: 18px;
    bottom: 28px;
    right: 18px;
  }
}

/*
 * The two invisible lines the audit measured at 1.02:1.
 *
 * /questions/: the hero's subtitle ("Find answers to common questions…") is
 * `.paragraph.opacity-80` inside `.hero-2`, and `.paragraph` is the navy
 * `--color-3` (#024275) at 80% on the hero's navy `--color-2` (#022b4c):
 * 1.02:1. /contact/ sets the same line in `--color-13` (#d1e3f5). So does
 * this: 11.6:1 at 80%.
 *
 * /service/<slug>/, all eleven: the intro paragraph is `.paragraph.is-extra-
 * large`, `--color-13` (#d1e3f5), inside `.with-bg-alt-color-15`, the mint
 * `--alt-color-15` (#c7ebde): 1.02:1 on every one. The ink used above for
 * `.is-large` and `.is-medium`, #0b2540, measures 12.9:1 on the mint. The
 * class's other 42 uses are on light grounds at 70% navy (5.18:1) or on the
 * provider heroes' navy at full strength (11:1), and keep their colour.
 */
.hero-2 .paragraph.opacity-80 {
  color: #d1e3f5;
}

.with-bg-alt-color-15 .paragraph.is-extra-large {
  color: #0b2540;
}

/*
 * ---------------------------------------------------------------------------
 * 2026-10-04: the enquiry forms' invalid fields (audit §4.2)
 * ---------------------------------------------------------------------------
 *
 * On /contact/, /questions/ and the seven Assessment pages an empty submit
 * showed one native bubble on the first empty field and nothing on the other
 * four: no `aria-invalid`, no message, and the same green underline a valid
 * field has. src/js/enquiry.js now marks each failing control
 * `aria-invalid="true"`, writes one message under it (`p.r-field-error`,
 * tied to the control by `aria-describedby`) and gives the wrapper
 * `.form-field` the class `is-invalid`. These rules draw that state.
 *
 * The red is #b3261e: 6.5:1 on white, 6.1:1 on the field's ground on
 * /contact/ and the Assessment pages (rgb(244,249,247), the field's 5% tint
 * over the section's white) and 5.2:1 on /questions/, whose form sits on
 * the mint (rgb(217,233,227)); measured from pixels behind the message at
 * 375 wide. The colour is not the only signal: the
 * message is text, and it replaces the "Required" tag at the field's right,
 * which says less than the message does and is positioned from the box's
 * bottom edge, where the message now sits. `.form-field` is a flex row that
 * centres the control, so the message wraps onto a row of its own.
 *
 * The underline is 2px rather than Webflow's 1px while the field is wrong,
 * and keeps the red on hover and focus, where webflow.css would put the
 * green back (equal specificity; this file loads after it). Nothing here
 * applies until the script has marked a field, so a reader with scripts off
 * sees the form as before, with the browser's own validation.
 */
.form-field.is-invalid {
  flex-wrap: wrap;
}

.form-field.is-invalid .field-label-required {
  display: none;
}

.text-field[aria-invalid="true"],
.text-field[aria-invalid="true"]:hover,
.text-field[aria-invalid="true"]:focus,
.text-field[aria-invalid="true"]:focus-visible {
  border-bottom-color: #b3261e;
  border-bottom-width: 2px;
}

.r-field-error {
  flex: 0 0 100%;
  width: 100%;
  margin: 0.6em 0 0;
  color: #b3261e;
  font-size: max(14px, 1.3em);
  font-weight: 500;
  line-height: 1.4;
}

.r-field-error:empty {
  display: none;
}
