/*------------------------------------------------------------------
[Dooms-Deboudt — authored overrides]

Loaded LAST, after every template stylesheet, so these rules win without
editing Poolrex source. Everything here is site-specific work, not template.

All values come from the DESIGN.md scales. The two error reds are the one
deliberate addition: the incumbent #ff0000 measures 3.6:1 on the navy form
panel, below AA, so an accessible pair replaces it and is documented in
DESIGN.md alongside the legacy token.

1. Focus visibility
2. Form labels, values and errors
3. Form status block
4. Header actions at every breakpoint
5. Quote band photograph
6. Reduced motion
7. Homepage: About -> Projecten gap
8. Homepage: Projecten band
9. Services: Diensten -> Testimonials gap
-------------------------------------------------------------------*/

/* 1. FOCUS VISIBILITY
   custom.css:56 sets `outline: none` globally on a, button and input with no
   replacement. Restore a visible focus ring everywhere, tinted per surface. */

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--primary--color);
    outline-offset: 3px;
    border-radius: 5px;
}

/* On the navy quote panel and the footer, navy-on-navy is invisible. */
.form-box a:focus-visible,
.form-box button:focus-visible,
.form-box input:focus-visible,
.form-box textarea:focus-visible,
.footer-con a:focus-visible,
.footer-con button:focus-visible,
.copyright a:focus-visible {
    outline-color: var(--white--color);
}

/* Yellow surfaces need the dark ring back. */
.generic-btn a:focus-visible,
.quote-btn a:focus-visible,
.submit-btn:focus-visible,
.read_more:focus-visible {
    outline-color: var(--primary--color);
    outline-offset: 4px;
}

/* Two elements strip their own focus at a specificity the generic rule above
   cannot reach: mobile.css:946 `.navbar-toggler:focus` (0,2,0) and
   custom.css:1641 `#back-to-top-btn:focus` (1,1,0), against (0,1,1) for
   `button:focus-visible`. These match that specificity and win on order.
   The hamburger matters most — below 992px it is the only route to the nav. */
.navbar-toggler:focus-visible {
    outline: 3px solid var(--primary--color);
    outline-offset: 4px;
}

#back-to-top-btn:focus-visible {
    outline: 3px solid var(--primary--color);
    outline-offset: 3px;
}

/* The toggler is a 24px-wide absolutely positioned box holding three 2px bars,
   which lands at roughly 24x24. Vertical padding takes it to 24x44 without
   moving the icon, since the element is right-anchored and centred. */
.navbar-toggler {
    padding: 10px 0;
}

/* 1a. STICKY HEADER
   Keeps both conversion paths — the call button and the quote pill — reachable
   at any scroll depth on a nine-section page, which previously only the mobile
   action bar (<=767px) provided. That left 768-1199px with no persistent
   access to either.

   Notes on the mechanics:
   - .header-con is `w-100 float-left`; the float is cleared because a floated
     sticky element is inconsistently handled. w-100 keeps the full width.
   - A background is mandatory: the header declares none, so it would otherwise
     be transparent over the content scrolling beneath it.
   - The shadow is the system's one documented ambient glow, not a new recipe.
   - z-index 300 clears every value in the template (max 106 outside the
     loader) and the action bar at 200. Bootstrap already sets
     `.navbar { position: relative }`, so the mobile collapse menu's containing
     block is unchanged by this. */

/* Every section in this template is `w-100 float-left` and nothing ever clears
   them, so <body> did not contain its own floats and its content height
   collapsed to roughly the header alone. A sticky element can only travel
   within its containing block, so the header unstuck immediately. flow-root
   makes <body> contain the floats without the `overflow` that would break
   sticky outright. This is the declaration that makes the rule below work. */
body {
    display: flow-root;
}

/* Display headings carried no tracking and no wrap control, which is what made
   them read as raw rather than set. Two corrections, both on the h1 only, so
   the homepage hero and the sub-banner titles stay identical:

   Tracking: type drawn for body sizes looks loose once it is 90px tall, because
   the sidebearings scale with it. -0.02em closes that up — well inside the
   -0.04em floor, and expressed in em so it tracks every step of the ramp down
   to 34px without a rule per breakpoint.

   Balance: "Wie zijn we?" was breaking to a lone "we?" and "Welkom in onze
   shop!" splits four words across two lines. text-wrap: balance evens the lines
   instead of filling the first and orphaning the rest. Browsers without it fall
   back to normal wrapping, which is exactly today's behaviour, so nothing
   regresses. It is limited to headings; the spec caps balancing at a few lines
   and it is wrong for running copy. */
h1 {
    letter-spacing: -0.02em;
    text-wrap: balance;
}

/* Removing the photographic help band from the about page left two Pool Mist
   sections touching — the figures band and the team band — and this system
   separates sections tonally, with no rules or dividers, so the boundary
   between them disappeared entirely.

   Scoped to the about page rather than changed on `.team-con` itself: the
   homepage uses that band too, and there it is followed by a white
   `.project-con`, so turning it white globally would move the same merged-band
   problem onto the homepage. `.services`, `.shop` and `.contact` already carry
   body classes for exactly this kind of page-scoped correction; about.html now
   carries one too. */
.about .team-con {
    background: var(--white--color);
}

/* With that band turned white, the team cards were white on white and had only
   the ambient glow holding them up — the tonal step that carries all depth in
   this system had nothing left to step against. Inverting it restores the
   relationship rather than inventing a new one: a Pool Mist tile on a white
   band is the same single step as the white-on-Pool-Mist cards everywhere else,
   just the other way up. Navy would have stood out harder, but three navy tiles
   directly above the navy footer would have run together the way the two Pool
   Mist bands did.

   All of this is scoped to .about. index.html runs identical team markup on a
   Pool Mist band, where a Pool Mist card would vanish completely and the larger
   sizes were not asked for.

   The hover border is the statistic card's device (1px transparent, resolving
   to Pool Surface Blue) rather than a new one. */
.about .team-box-item {
    flex: 0 1 300px;
    background: var(--grey--color);
    border: 1px solid transparent;
    transition: all 0.5s ease-in-out;
}

.about .team-box-item:hover {
    border-color: var(--secondary--color);
}

/* Transparent, not white: the monogram panel should read as part of the tile
   rather than punch a white rectangle into the top of it. */
.about .team-monogram {
    height: 240px;
    background: transparent;
}

/* 130px echoes the 129px white badge on the About photograph, and the initials
   move from the Stat step to the Headline step — the ramp's next stop up, not
   an invented size to match the circle's growth. */
.about .team-monogram span {
    width: 130px;
    height: 130px;
    font-size: 44px;
    line-height: 44px;
}

.about .team-content {
    padding: 34px 24px;
}

/* The 22px below the role was spacing for the social list that used to sit
   under it; nothing follows it now, so it only made the card bottom-heavy. */
.about .team-content span {
    margin-bottom: 0;
}

.header-con {
    position: sticky;
    top: 0;
    z-index: 300;
    /* Bootstrap's .float-left is `float: left !important`, so this needs the
       same weight to land. */
    float: none !important;
    background: var(--white--color);
    box-shadow: 2px 2px 67px rgb(44 162 252 / 7%);
}

/* Anchored sections would otherwise land underneath the pinned header.
   :target covers every fragment on the site — #offerte, the service anchors,
   the project anchors — without enumerating them. */
:target {
    scroll-margin-top: 104px;
}

@media screen and (max-width: 1199px) {
    :target {
        scroll-margin-top: 88px;
    }
}

/* 1b. HERO QUALIFIER
   Answers the two questions a cold visitor arrives with — "what exactly do you
   do?" and "komen jullie tot bij mij?" — at the moment of the primary action. */

.banner-meta {
    max-width: 46ch;
    margin: 26px 0 0;
    font-size: 16px;
    line-height: 26px;
    font-weight: 500;
}

/* 1c. TEAM CARDS
   The template shipped three identical grey "255 x 255" placeholders under the
   owners' real names. Until real photographs exist, an initial in the system's
   own medallion reads as designed rather than as broken. */

.team-intro {
    max-width: 52ch;
    margin: 16px auto 0;
}

/* The panel must be the card's own white, not the section's. .team-con is
   var(--grey--color) and so was this — identical values, so the top 220px of
   every card dissolved into the band behind it and the cards read as three
   floating circles. White restores the silhouette; the documented ambient glow
   separates the card from the pale-blue section the way every other card in
   the system does. */
.team-box-item {
    box-shadow: 2px 2px 67px rgb(44 162 252 / 7%);
}

.team-monogram {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 220px;
    border-radius: 20px 20px 0 0;
    background: var(--white--color);
}

.team-monogram span {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 110px;
    height: 110px;
    border-radius: 50%;
    background: var(--primary--color);
    color: var(--white--color);
    font-size: 32px;
    font-weight: 700;
    line-height: 32px;
    transition: all 0.4s ease-in-out;
}

.team-box-item:hover .team-monogram span {
    background: var(--secondary--color);
    transform: translateY(-5px);
}

/* 1e. CONTACT PAGE
   The contact page now uses the homepage's quote-band structure
   (.mian-form-con > .form-box > .form-item), which retires the second input
   system DESIGN.md flagged as unresolved template drift — .form_style fields
   at 25px with a blue focus border versus the pill fields at 26.5px with a
   yellow one. One form language site-wide.

   Nothing on the site renders .contact-con or .contact_info any more, so the
   template's rules for both are dead; they are left in place because they are
   template source, not authored code. */

/* The quote form's grid puts two fields per row and spans the last one. A
   sixth field — the contact page's Onderwerp — needs the same span without
   being last. */
.contact-form ul li.field-wide {
    grid-column: 1 / -1;
}

/* The contact page has no hero since its sub-banner was removed, so the quote
   band's headline is the page's <h1>. Only the tag changed — the global h1 is
   the 90px hero scale, which this panel was never built to hold, so the
   heading keeps the 44px Headline step and its six responsive drops verbatim
   from custom.css/mobile.css `h2`. Colour and margin come from `.form-con h2`,
   which the tag no longer matches, so they are restated here.

   If a hero is ever restored to this page, its title becomes the <h1> and this
   heading goes back to <h2> — delete this block with it. */
.form-con h1 {
    font-size: 44px;
    font-weight: 700;
    line-height: 53px;
    margin-bottom: 24px;
    color: var(--white--color);
}

@media screen and (max-width: 1440px) {
    .form-con h1 {
        font-size: 40px;
        line-height: 48px;
        margin-bottom: 14px;
    }
}

@media screen and (max-width: 1199px) {
    .form-con h1 {
        font-size: 36px;
        line-height: 40px;
    }
}

@media screen and (max-width: 991px) {
    .form-con h1 {
        font-size: 30px;
        line-height: 36px;
        margin-bottom: 12px;
    }
}

@media screen and (max-width: 767px) {
    .form-con h1 {
        font-size: 26px;
        line-height: 28px;
    }
}

@media screen and (max-width: 575px) {
    .form-con h1 {
        font-size: 24px;
        line-height: 26px;
    }
}

/* 2. FORM LABELS, VALUES AND ERRORS */

.field-label {
    display: block;
    font-size: 14px;
    font-weight: 700;
    line-height: 14px;
    margin-bottom: 9px;
    margin-left: 0;
    color: var(--primary--color);
    /* mobile.css centres .form-con (<=767px) and .contact_info (<=991px); a
       label must stay aligned with the text inside its own field. */
    text-align: left;
}

/* Labels sit flush with the field's left edge rather than over its placeholder
   text. Matching the placeholder would mean tracking the input's padding, which
   both forms restyle at four breakpoints (24px->14px here, 26px->16px on the
   contact page) and which resolves differently for floated and non-floated
   field groups. Flush-left needs none of that: every label lines up with every
   field, at every width, whatever the container does. */
.contact-form .field-label{
    padding-left: 0 !important;
}

/* custom.css styles EVERY span inside these forms as an absolutely positioned
   red validation error (.contact-form span, .contact-con .contact_info span).
   The hint is part of the label, not an error, so it has to opt out of all of
   it — and needs the specificity to beat those two rules. */
.contact-form .field-label__hint{
    position: static;
    display: inline;
    height: auto;
    margin: 0;
    padding: 0;
    left: auto;
    font-size: 14px;
    line-height: 14px;
    font-weight: 400;
    color: inherit;
    opacity: 0.75;
}

/* States what happens after the button is pressed, at the moment of highest
   hesitation, and keeps the phone path open beside the form. */
.form-promise {
    margin-bottom: 32px;
    font-weight: 600;
}

.form-box .form-promise {
    color: var(--white--color);
}

/* Poolside Sun never appears as text, so the link carries its weight through
   an underline rather than a colour shift. */
.form-promise a {
    color: inherit;
    font-weight: 700;
    text-decoration: none;
    border-bottom: 1px solid currentColor;
}

.form-promise a:hover {
    border-bottom-color: transparent;
}

/* The quote form sits on the navy panel. */
.form-box .field-label {
    color: var(--white--color);
}

/* The breadcrumb is the contact page's only orientation signal: it has no
   sub-banner, and the nav item that used to carry `active` is gone, so nothing
   else names the page. It sits above the eyebrow rather than below the heading
   as it does in the sub-banner on other pages — a breadcrumb orients before the
   content, and here it is also the only thing that says "Contacteer ons" on a
   page whose heading says "Vraag een offerte".

   custom.css authored these rules for the sub-banner, where `.sub-banner-title *`
   painted every descendant white. That rule does not reach inside the quote
   band, so the link needs its own colour; the pill border, separator and active
   item are already white and carry over unchanged. Hover follows `.form-promise a`
   above — an underline, not a colour shift, because Poolside Sun never appears
   as text and Pool Surface Blue is the incumbent's own contrast defect. */
.form-con .breadcrumb-con {
    margin-bottom: 26px;
}

.form-con .breadcrumb-item a {
    color: var(--white--color);
    text-decoration: none;
}

.form-con .breadcrumb-item a:hover {
    color: var(--white--color);
    border-bottom: 1px solid currentColor;
}

/* The placeholder was set to the same colour as the value, so a filled field
   and an empty one looked identical. Now that every field carries a real
   label, the distinction moves to the value: typed text is navy and bold,
   placeholder text stays grey. Both clear AA on white. */
.contact-form ul li input,
.contact-form ul li textarea{
    color: var(--primary--color);
    font-weight: 600;
}

.contact-form ul li input::placeholder,
.contact-form ul li textarea::placeholder{
    color: var(--text--color);
    font-weight: 400;
    opacity: 1;
}

/* Validation errors were absolutely positioned and overlaid the next field.
   Let them reflow, and give them contrast on the surface they land on. */
.contact-form span.error{
    position: static !important;
    display: block;
    height: auto;
    left: auto;
    margin-top: 8px;
    padding-left: 0;
    font-size: 14px;
    line-height: 20px;
    font-weight: 600;
    text-align: left;
    color: #c81e1e;
}

.form-box .contact-form span.error {
    color: #ff8a8a;
}

.contact-form ul li{
    position: relative;
}

/* 3. FORM STATUS BLOCK
   Replaces the 5-second toast with a persistent, announced result. */

.form-status {
    display: none;
    margin-top: 24px;
    padding: 20px 24px;
    border-radius: 15px;
    font-size: 16px;
    line-height: 26px;
}

.form-status.is-visible {
    display: block;
}

.form-status--success {
    color: var(--primary--color);
    background: var(--white--color);
}

.form-status--error {
    color: var(--white--color);
    background: #c81e1e;
}

.form-status a {
    font-weight: 700;
    color: inherit;
}

/* 4. HEADER ACTIONS AT EVERY BREAKPOINT
   mobile.css hid .phone-num below 1199px and .quote-btn below 575px, which left
   the header with no contact affordance at all on phones. Both are restored in
   mobile.css; these rules make them fit. */

.header-action {
    display: none;
    width: 46px;
    height: 46px;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: 16px;
    text-decoration: none;
    transition: all 0.3s ease-in-out;
}

.header-action--call {
    color: var(--white--color);
    background: var(--primary--color);
}

.header-action--call:hover,
.header-action--call:focus {
    color: var(--white--color);
    background: var(--secondary--color);
}

/* The quote pill keeps a readable label at every width — it shortens, it never
   becomes a bare arrow. */
.quote-btn__short {
    display: none;
}

/* Below 575px the written-out number does not fit beside the logo and the
   hamburger, so it becomes a round call button and the pill shortens. Both
   paths stay reachable; only their form changes. These live here rather than in
   mobile.css because this file loads later and media queries add no
   specificity — split across files, the base rule would win. */
@media screen and (max-width: 575px) {
    .header-btn {
        gap: 10px;
        margin-left: 0;
    }

    .header-action {
        display: inline-flex;
    }

    .phone-num {
        display: none;
    }

    .quote-btn a {
        padding: 15px 20px;
        font-size: 14px;
    }

    .quote-btn a i {
        padding-left: 8px;
    }

    .quote-btn__long {
        display: none;
    }

    .quote-btn__short {
        display: inline;
    }
}

/* 5. QUOTE BAND PHOTOGRAPH
   .form-img is an empty div and both template background rules for it are
   commented out (custom.css:788, custom.css:895), leaving 46.6% of the
   highest-intent band on the page as bare navy at every width >=768px.
   DESIGN.md documents this slot as "form left, photography right, edge to
   edge"; quote_large.jpg was already in the repo, unused. mobile.css:1699
   still hides the column below 768px, which is correct. */

.form-img {
    background: url(../images/originals/quote_large.jpg) no-repeat center;
    background-size: cover;
}

/* 6. REDUCED MOTION
   The wave, the sonar pulse, the AOS reveals and three autoplaying carousels
   all ran unconditionally. Honour the OS preference. */

@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    html {
        scroll-behavior: auto;
    }

    .generic-btn a:hover,
    .quote-btn a:hover,
    .submit-btn:hover {
        transform: none;
    }

    /* The blanket rule above collapses the loader's own ballPulseDouble
       keyframe, whose 0% and 100% frames are both scale(0) — so the dots ended
       invisible and a reduced-motion visitor got a blank white full-screen
       overlay at z-index 99999 until window.load. Showing the page immediately
       is both calmer and faster; the mask only ever hid a flash of unstyled
       content on a static site. */
    .loader-mask {
        display: none !important;
    }
}

/* ==========================================================================
   7. HOMEPAGE: ABOUT -> PROJECTEN GAP
   .about-con carries `padding-bottom: 182px !important`, and on the homepage
   .project-con's top padding is 80px (blog.css redefines .padding-top unscoped
   and loads after mobile.css, so the 140px rhythm never applies here). That put
   262px of empty page between the About block and Onze Projecten.

   The 182px is not arbitrary: .about-small-img is absolutely positioned at
   `bottom: -57px`, so the 216px circular portrait hangs below the block and
   needs clearance. The template itself allows only 70px at <=991px against that
   same 57px overhang, so 90px is more generous than its own tightest step while
   cutting the desktop gap by a third.

   Scoped with :not(.aboutpage-con) because about.html carries that extra class
   on the same section, and its About block is followed by a different section
   at a different rhythm. Every step is restated: this selector outranks
   mobile.css's .about-con at all widths, so an unrestated breakpoint would
   inherit the desktop value rather than the template's smaller one.
   ========================================================================== */

.about-con:not(.aboutpage-con) {
    padding-bottom: 90px !important;
}

@media screen and (max-width: 1440px) {
    .about-con:not(.aboutpage-con) {
        padding-bottom: 85px !important;
    }
}

@media screen and (max-width: 1199px) {
    .about-con:not(.aboutpage-con) {
        padding-bottom: 80px !important;
    }
}

/* The template's own values below here are already tight; kept as they were. */
@media screen and (max-width: 991px) {
    .about-con:not(.aboutpage-con) {
        padding-bottom: 70px !important;
    }
}

@media screen and (max-width: 767px) {
    .about-con:not(.aboutpage-con) {
        padding-bottom: 40px !important;
    }
}

/* ==========================================================================
   8. HOMEPAGE: PROJECTEN BAND
   Onze Projecten takes the same Pool Mist fill as Onze Diensten. It had no
   background rule of its own and so rendered white, directly beneath a white
   .about-con — and this system separates sections tonally, with no rules or
   dividers, so there was nothing marking where one ended and the other began.
   That adjacency appeared when the team band was removed from between them.

   With this the homepage alternates cleanly from top to bottom: photograph,
   Pool Mist, white, Pool Mist, navy footer.

   .project-con exists only on index.html, so no scoping is needed.
   ========================================================================== */

.project-con {
    background: var(--grey--color);
}

/* ==========================================================================
   9. SERVICES: DIENSTEN -> TESTIMONIALS GAP
   Two adjacent sections each contributed a full 140px rhythm unit, so 280px of
   empty white sat between the last service card and "Wat Onze Klanten Zeggen".
   Both bands are white, so nothing marked the boundary either — it read as one
   long pause rather than two sections.

   The Diensten side gives up almost all of its trailing padding. 20px sits
   below the ramp's smallest step (40px), so that one declaration holds at every
   breakpoint without restating anything.

   The testimonials side keeps the larger share, because it opens with an
   eyebrow and a heading and a heading wants more space above it than below —
   but it no longer keeps a full rhythm unit. Its steps are restated down to
   40px at <=991px, which is exactly what the ramp already gives there and at
   every width below, so the ladder ends cleanly rather than pinning small
   screens to a desktop value.

   Result: 100px at desktop down to 60px on a phone, from 280/80.
   Both classes exist only on services.html, so no scoping is needed.
   ========================================================================== */

.main-services-con {
    padding-bottom: 20px;
}

.tesimonials-con {
    padding-top: 80px;
}

@media screen and (max-width: 1440px) {
    .tesimonials-con {
        padding-top: 60px;
    }
}

@media screen and (max-width: 1199px) {
    .tesimonials-con {
        padding-top: 50px;
    }
}

/* Matches the ramp's own value here and below, so nothing is pinned. */
@media screen and (max-width: 991px) {
    .tesimonials-con {
        padding-top: 40px;
    }
}
