/*
Theme Name: Sotargruppen Child
Theme URI: https://www.sotargruppen.se
Description: Child theme for Sotargruppen. Fixes accessibility issues (WCAG 2.1 AA) without touching the parent theme.
Author: Sotargruppen V. Skaraborg
Template: sotargruppen
Version: 0.1.0
Text Domain: sotargruppen-child
*/

/*
 * The child theme's stylesheet. Loaded LAST, after the parent's CSS, Bootstrap and the fonts
 * (see sg_enqueue_assets in functions.php), so that the rules here can override the others.
 * The parent's styling is not loaded from here but via wp_enqueue_style.
 *
 * Every block must be self-contained so that it can be carried over to the new theme.
 */

/* ==========================================================================
   "Additional CSS" moved from the parent theme (the Customizer)
   WordPress stores the Customizer's Additional CSS PER THEME. When the child theme is
   activated, production's extra CSS therefore disappears (it belongs to `sotargruppen`, not
   to `sotargruppen-child`), and among other things the footer headings lost their styling.
   Found by the before/after screenshot comparison on the theme switch, 2026-10-08.

   The text is copied VERBATIM (same rules and values), only reformatted, so that it works
   regardless of what is in the database and so that it is version controlled.
   NOTE: do not change colors here without a contrast check. The one exception made so far is `.info-link:hover` below: it was orange TEXT
   (#ff863d, 2.41:1 on white) and is now --sg-brand-text (see "Colours" at the end of this file). The rule matches nothing today (no element has the
   class on the 69 addresses, measured 2026-10-15), so the change is precautionary and changes no pixel. The red error color is still open (work order 02).
   The original post remains in the database under the theme `sotargruppen`. It is not used
   while the child theme is active, so there is no duplication.
   ========================================================================== */
.info-link {
  text-decoration: underline;
}

.info-link:hover {
  color: var(--sg-brand-text) !important;
}

.footer-header {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
  font-weight: 500;
  line-height: 1.2;
  color: #000;
  font-family: 'Oswald', sans-serif;
}

.personnummer {
  width: 180px;
}

.wpcf7-not-valid-tip {
  color: #d60000 !important;
  font-weight: bold;
  font-size: 15px;
}

.wpcf7-not-valid {
  border: 2px solid #d60000 !important;
}

/* ==========================================================================
   Skip to content (WCAG 2.4.1 Bypass Blocks)
   The link is the first focusable element on the page. It is positioned off screen
   (moved up, not display:none, because it could not receive focus then) and
   slides in when it receives focus. Dark text on a white background gives high contrast
   regardless of what is behind it, and orange is deliberately not used as a text color.
   ========================================================================== */
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100000;
  padding: 0.75rem 1.25rem;
  background: #fff;
  color: #000;
  font-weight: 700;
  text-decoration: underline;
  transform: translateY(-120%);
}

.skip-link:focus {
  transform: translateY(0);
  /* A clear focus ring of its own on this link only, drawn INSIDE its white box (it sits at the edge of the screen
     where an outer ring would be cut off). The site-wide ring is in the "Visible keyboard focus" block below. */
  outline: 3px solid #000;
  outline-offset: -6px;
}

/* ==========================================================================
   Visually hidden, but still in the accessibility tree (WCAG 1.3.1 Info and Relationships)
   Used by the hidden <h1> that sg_hidden_h1() prints (inc/helpers.php) on pages whose content has no heading of its own.
   A STOPGAP, not a fix: the real fault is that the parent theme never prints a page's title. See "Dold rubrik" in README.md.

   THE TECHNIQUE IS THE POINT. The element is taken out of the flow and clipped to 1 x 1 px, so nothing is drawn and nothing
   moves, but a screen reader still finds it. `display: none` and `visibility: hidden` must NEVER be used for this: they
   remove the element from the accessibility tree too, and the heading would then be in the markup for nobody.
   tests/run.php fails if this rule ever uses either of them, and `npm run headings` counts the h1 in the accessibility
   tree and not only in the markup.
   `clip` is the old syntax and `clip-path` the current one; both are here so that no browser shows the element.
   ========================================================================== */
.sg-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   Call-to-action above the footer (footer.php; the text comes from the options page, field `innan_footer_cta`)

   1. NO EMPTY HEADING (WCAG 1.3.1). The title field is empty, and footer.php used to print an empty <h2> for it on every page,
      which a screen reader announces as "heading level 2" followed by nothing. It is now printed only when there is a title.
      That h2 took up 16 px (8 px padding + 8 px margin, measured 2026-10-13 on 11 pages in both views). Without it the text
      moved up by 8 or 16 px and, on 13 of 22 views, the page got 16 px shorter. `sg-cta-untitled` gives the 16 px back, so the
      page looks exactly as before. THIS IS A COMPENSATION, AND A DESIGN QUESTION THAT IS NOT DECIDED: whether the space should
      exist at all is for the new theme. It is here only to keep the look unchanged.

   2. LISTS WRITTEN AS HEADINGS. The text contains a list of services written as seven <h6> after an <h3>, so the heading outline
      skips from level 3 to 6. Tobias changes them to <h4> in wp-admin AFTER this stylesheet is live (they would otherwise grow
      from 16 to 24 px). Measured 2026-10-13: the h6 is 16 px, not the 12 px that the parent's own rule suggests, because Bootstrap
      is loaded after the parent and wins; h4 and h6 differ only in font size (the line height follows, it is a ratio). The rule gives
      an h4 WITHOUT a link the size of an h6. The h4 with a link ("Boka möte") keeps its size. Today the rule matches nothing.
      `:has()` is unknown to browsers older than 2022/2023; there the rule is ignored and the new h4 are shown larger (worse looking,
      not broken).
   ========================================================================== */
.sg-cta-untitled {
  padding-top: 1rem;
}

.sg-cta-text h4:not(:has(a)) {
  font-size: 1rem;
}

/* ==========================================================================
   Mobile menu button (header.php; keyboard and screen reader behaviour in js/menu-a11y.js, README: "Mobilmenyn")

   The burger is a real <button> now (the parent had an <a href="#menu">, which has no role, no state and no Space key). The parent styles it by the
   class `.menu-burger` (background, position, padding, display), not by the tag, so that CSS applies unchanged. What a <button> adds is the browser's
   own frame (a 2 px grey border, measured as a grey box around the three lines, 514 px that differed in the pixel comparison) and, after a mouse
   click, Bootstrap's `button:focus` outline, which an <a> never showed because a plugin removes `a:focus` outlines. Both are taken away here.
   Keyboard focus keeps its ring: the `:focus-visible` rule above (and `#menu.active button:focus-visible`) is what draws it.
   ========================================================================== */
button.menu-burger {
  border: 0;
  margin: 0;
}

button.menu-burger:focus:not(:focus-visible) {
  outline: none;
}

/* ==========================================================================
   Text blocks without a title (parts/text.php, the child's copy; README: "Förälderfiler som barntemat skriver över")

   The parent printed an empty <h2> for every text block whose title field is empty: 22 empty headings on 13 pages (WCAG 1.3.1). The copy
   prints the heading only when there is a title. The empty h2 took up 16 px (8 px padding + 8 px margin, measured 2026-10-14 in every
   one of the 22 blocks, both views); `sg-text-untitled` gives the 16 px back so that the pages look as before (pixel comparison on the
   13 pages, desktop and mobile). Like the call-to-action above, THIS IS A COMPENSATION AND A DESIGN QUESTION THAT IS NOT DECIDED.

   It is a MARGIN on purpose. A first version used `padding-top` and worked on 8 of the 13 pages but not on the 8 that use page-2.php,
   where the parent sets `.container.bg-cont-2 .text-section .container { padding: 0 2rem }` (specificity 0,4,0, so a padding here
   loses). The parent touches only the padding of this container, and the section around it has padding of its own, so the margin
   does not collapse out of it.
   ========================================================================== */
.sg-text-untitled {
  margin-top: 1rem;
}

/* ==========================================================================
   Cookie banner above the chat button (GDPR: refusing must be as easy as accepting; the contract requires a working mobile site)

   MEASURED 2026-10-14 on production (empty cookie jar, 360 / 390 / 414 / 1440 px, 3 x 3 sample points per control): the chat button
   (Lynes) is `position: fixed; z-index: 999999` INSIDE a shadow root, the consent banner is `position: fixed; z-index: 99999`. The
   button was therefore painted ABOVE the banner and covered the banner's own controls: "Neka" at 1 of 9 points and "Visa preferenser"
   at 3 of 9 on mobile ("Visa preferenser" at 3 of 9 on desktop too). A tap on the covered part opened the chat instead of making
   the choice.

   The banner has the class `cmplz-show` only while it is visible; when the visitor has chosen it becomes `cmplz-dismissed`. So this
   rule needs no JavaScript and no :has(), and it ends the moment the banner does. The chat button is not hidden or removed: it stays
   where it was and is on top again as soon as the visitor has chosen. While the banner is up it lies underneath the banner, which is
   a modal dialog, so the rest of the page is out of reach then anyway.

   NOTE: a rule on the chat's own host element (#widget-lynesContactWidget) does NOT work (measured): the host is a static, zero-height
   div, and the z-index sits on an element inside its shadow root. 2147483647 is the largest value; if Lynes ever uses the same
   value, the later element in the document wins and the overlap is back, which the Complianz guard (tools/complianz-check.js) measures.
   ========================================================================== */
.cmplz-cookiebanner.cmplz-show {
  z-index: 2147483647;
}

/* ==========================================================================
   Visible keyboard focus (WCAG 2.4.7 Focus Visible, 1.4.11 Non-text Contrast)

   MEASURED 2026-10-08 with `npm run focus`: before this block 1151 of 1224 keyboard stops (94 %) showed NO visible focus.
   The cause is NOT the parent theme. `a:focus { outline: none }` comes from the plugin Custom Store Locator
   (wp-content/plugins/custom-store-locator/assets/csl-custom-style.css, line 35), which is loaded on every page.
   The parent theme only removes the outline on a few Contact Form 7 fields (style.css line 6332), on `.button:hover`
   (line 6245) and on the FAQ accordion `.ac>.ac-q` (line 8179).

   THE RING is a sandwich: [light band 2 px][DARK ring 3 px][light band 2 px].
   A dark ring on its own is invisible on the dark mobile menu (#231f20 gives only 1.1:1), so the light bands are what
   guarantee 3:1 on every background: the ring against the bands next to it, and the outer band against dark surfaces.
   - outline: 3px dark, offset 2px, so it occupies 2..5 px outside the element.
   - box-shadow: 0 0 0 7px light. A shadow is painted BELOW the outline, so it shows in the 0..2 px gap inside the ring and in
     the 5..7 px band outside it. (A shadow of only 5 px would end under the ring and give a light band on the inside only.)
   The geometry and the contrast are READ from rendered pixels by `npm run focus`, not calculated.

   THE SELECTORS are listed on purpose. A bare `:focus-visible` has specificity (0,1,0) and loses to `a:focus` (0,1,1),
   `.button:hover` (0,2,0) and the Contact Form 7 rules (0,3,1). Each selector below is at least as specific as the rule it
   has to beat, and this file is loaded LAST, so equal specificity is enough: no `!important` except for Google Maps (below).

   LOAD ORDER IS WHAT MAKES THIS WORK, and it is not guaranteed: a plugin update that changes when its stylesheet is enqueued could
   bring the invisible focus back. `npm run focus` reads the computed style of every focused element and fails if that happens.
   ========================================================================== */
:root {
  --sg-focus: #1a1a1a;       /* the dark ring */
  --sg-focus-halo: #ffffff;  /* the light bands */
}

:focus-visible,
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
.button:focus-visible,
.wpcf7-form input[type="text"]:focus-visible,
.wpcf7-form input[type="tel"]:focus-visible,
.wpcf7-form input[type="email"]:focus-visible,
.wpcf7-form textarea:focus-visible {
  outline: 3px solid var(--sg-focus);
  outline-offset: 2px;
  box-shadow: 0 0 0 7px var(--sg-focus-halo);
}

/* The target of the skip link, <main id="innehall" tabindex="-1">, gets focus from script only. It is a content container and not
   an interactive control, so WCAG 2.4.7 does not apply to it, and a ring around the whole page content is noise. Feedback comes from
   the next Tab, which lands on the first focusable element in the content and shows ITS ring (tools/skip-link-check.js checks that).
   Scoped to main[tabindex="-1"] so that any other element that happens to get tabindex="-1" still shows its ring. */
main[tabindex="-1"]:focus-visible {
  outline: none;
  box-shadow: none;
}

/* MENUS: the ring goes INSIDE the link. Measured with `npm run focus` (pixels, with the clipping ancestor named): the menu links sit flush
   against ancestors that clip. header.site-header has overflow:hidden/auto and cuts the ring under the desktop drop-down; nav#menu.active
   has overflow:hidden and the links fill its full width, so the mobile menu cut the ring on both sides and showed only two horizontal lines.
   Inside the element nothing can clip it. Two variants, because a ring needs 3:1 against the surface it sits on:
   - desktop drop-down: light surface, so a dark ring with a light band at the edge. 2 px ring, because the links are only 26 px high.
   - mobile menu: dark surface (#231f20), so a LIGHT ring with a dark band at the edge. */
header .sub-menu a:focus-visible {
  outline-width: 2px;
  outline-offset: -4px;
  box-shadow: inset 0 0 0 2px var(--sg-focus-halo);
}

/* The sub-menu toggles (span.toggle-link, made keyboard operable by js/menu-a11y.js) sit flush against the right edge of nav#menu, which clips: measured with
   `npm run focus`, the ring on the toggle touched the element with no band between them. They get the same inside ring as the links. */
#menu.active a:focus-visible,
#menu.active button:focus-visible,
#menu.active .toggle-link:focus-visible {
  outline-color: var(--sg-focus-halo);
  outline-offset: -5px;
  box-shadow: inset 0 0 0 2px var(--sg-focus);
}

/* THE CLOSED MOBILE MENU IS OUT OF THE TAB ORDER. Below 1139 px the parent collapses the menu with `max-height: 0; overflow: hidden`, but its 24 links
   stay focusable: measured with `npm run focus`, a keyboard user tabs through 24-26 invisible links on EVERY mobile page (280 stops in all)
   before reaching the content, and no focus ring can show on a link that is not painted. `visibility: hidden` takes them out of the tab order
   and out of the accessibility tree. The parent's `.menu { transition: all 0.2s }` would also animate `visibility`, but then the menu is still
   hidden in the very first frame after the burger is pressed (measured), and a Tab in that frame skips every link. So opening switches
   `visibility` at once, and closing switches it only AFTER the 0.2 s closing animation, which is therefore kept. The burger lies outside the
   menu and is not affected. The breakpoint is the parent's.
   The collapsed SUB-menus inside the OPEN menu are handled in the next block. */
@media screen and (max-width: 1139px) {
  #menu.menu:not(.active) {
    visibility: hidden;
    transition: all 0.2s ease-in-out, visibility 0s linear 0.2s;
  }

  #menu.menu.active {
    transition: all 0.2s ease-in-out, visibility 0s;
  }
}

/* THE COLLAPSED SUB-MENUS INSIDE THE MOBILE MENU ARE OUT OF THE TAB ORDER TOO. Measured with `npm run focus` with the menu open: 18 links in the four
   `ul.sub-menu` received focus without being painted (`max-height: 0; overflow: hidden`), so a keyboard user tabs through invisible links and no focus
   ring can show. The parent keeps a sub-menu's state in a CLASS, `active` on the `ul` (js/index.js `toggleClass('active')`; style.css
   `.menu>ul ul { max-height: 0 }` and `.menu>ul ul.active { max-height: 500em }`), so the technique above can follow it. Measured: a sub-menu declares
   no `transition`, so it opens and closes at once and no delayed hide is needed. Only a `ul` WITHOUT `active` is set: an open one simply inherits
   `visible`, and a `ul` nested in a closed one stays hidden.
   KNOWN AND DELIBERATE CONSEQUENCE: only ONE of the four sub-menus has a toggle at all (Ventilation: `has-sub` is a CSS class set by hand on a single
   menu item in wp-admin). The other three (17 links) cannot be opened by anyone, so they lose nothing here, and 16 of those 17 pages can be reached
   without the menu (measured 2026-10-09; the exception is /om-oss/).
   GATE, CLOSED 2026-10-14: this rule was written on the condition that it be reconsidered if work order 02, task I were stopped. Task I was built, not
   stopped: the toggle is now a button that the keyboard can reach and operate (js/menu-a11y.js). The two do not work against each other, MEASURED by
   `npm run menu` (G1-G4): a collapsed sub-menu's links are out of the tab order, a sub-menu opened with the keyboard has ALL its links back in the tab
   order and visible, closed again they are gone, and a closed menu has none. Both this rule and the script read the parent's class `active`. */
@media screen and (max-width: 1139px) {
  .menu>ul ul:not(.active) {
    visibility: hidden;
  }
}

/* Links in the Google Maps info windows of the store locator. The plugin sets `.gm-style .gm-style-iw-c a { outline: none }`, which is
   more specific than the rule above, and Google injects its own <style> into the page AFTER this file at runtime. A link in a map popup
   that cannot show focus is a real 2.4.7 failure, so this is a deliberate, narrowly scoped `!important`. */
.gm-style a:focus-visible,
.gm-style button:focus-visible {
  outline: 3px solid var(--sg-focus) !important;
  outline-offset: 2px !important;
  box-shadow: 0 0 0 7px var(--sg-focus-halo) !important;
}

/* ==========================================================================
   Colours: orange as TEXT, and white text ON orange (WCAG 1.4.3 Contrast Minimum; work order 02, task C)

   THE DECISION (Chat and Tobias, 2026-10-14/15): the brand orange #f68a3c stays as a SURFACE and as a LINE (backgrounds, borders). A decorative border is neither
   text nor a control that is needed to understand the content, so 1.4.11 does not apply to it. As TEXT on white the orange gives 2.44:1 where 4.5:1 is required,
   so text uses --sg-brand-text, a darker orange-brown: 5.79:1 on white, 4.83:1 on #eeeae3, 4.90:1 on #ffe8d8. Text ON an orange surface is dark (--sg-on-brand,
   #212529, 6.0-6.4:1 on the oranges used on this site), never white (2.4-2.6:1). The orange does not disappear, it changes role.

   HOW EACH RULE WAS FOUND: by rendering every page and reading the COMPUTED style (axe `color-contrast`), not by reading the parent's CSS. The parent's
   `a { color: #f68a3c }` looks as if every link were orange, but Bootstrap's `a { color: #007bff }` loads after it and wins, so only 50 of 8 430 links were orange
   (docs/c0-farginventering.md). The same inventory showed that Bootstrap's own link blue is under the requirement too (3.98:1), so the default link colour below
   replaces BOTH. Links with a colour of their own (menus, footer, buttons) are more specific and are not touched.
   MEASURED 2026-10-15 on 69 addresses, with this CSS injected in the browser before it was written into the file: axe `color-contrast` 110 -> 6 elements at
   1440 px and 112 -> 8 at 390 px. The 6 left are the plugin's own page /sitemap.html (#808080, 3.94:1; not ours, listed as EXCLUDED in the colour inventory). The 2
   more at 390 px are white text on a PHOTO on the start page ("Vi ingår i Sovent Group" and its link): axe cannot judge text on images and flagged them before
   this change too. They are measured separately (colour inventory, section E).
   ========================================================================== */
:root {
  --sg-brand: #f68a3c;             /* the brand orange: surfaces and lines only */
  --sg-brand-text: #a64b00;        /* orange-brown for TEXT and icons on light surfaces */
  --sg-brand-text-hover: #7a3700;  /* the same, darker, for hover (8.8:1 on white) */
  --sg-on-brand: #212529;          /* text on an orange surface */
}

/* The default link colour. Replaces Bootstrap's blue (3.98:1) and the parent's orange (2.44:1). */
a {
  color: var(--sg-brand-text);
}

a:hover {
  color: var(--sg-brand-text-hover);
}

/* Orange text on a pale surface. Only the TEXT changes. (The contact boxes on /kontakt/ were here too; they have their own block, "The contact boxes on /kontakt/".) */
.article-item a.till-jobb,
.footer a:hover {
  color: var(--sg-brand-text);
}

.article-item a.till-jobb:hover {
  color: var(--sg-brand-text-hover);
}

/* White text on an orange surface becomes dark text. This covers the hover states too: the buttons turned white on #f68a3c (2.44:1) when hovered. */
.wpcf7-form input[type="submit"],
.text-container .title-has-background-color > span,
.modal-booking-card a:hover {
  color: var(--sg-on-brand);
}

/* The submit button is orange only AT REST. On hover the parent turns it BLACK (`.wpcf7-form input:hover[type="submit"] { background: #000 }`), and dark text on black is
   unreadable. The rule above first set dark text for EVERY state, which Tobias found by hovering "Skicka" on /kontakt/mariestad/ (2026-10-16); I had measured the hover
   states of the rules in the colour inventory, not of every element that task C touched. On hover the text goes back to the parent's white (21:1 on black).
   Specificity (0,3,1) beats the rest rule above (0,2,1). */
.wpcf7-form input[type="submit"]:hover {
  color: #fff;
}

/* The same mistake from the other side, found by the all-states sweep (2026-10-16, 2 306 states on 17 pages): the default block-editor button ("Kontakt" on /sotning/,
   the only one on the site) is dark grey with white text, and the default link colour on hover (above, from `a:hover`) turned its text brown on dark grey: 1.36:1 (it was Bootstrap's
   blue before, 1.71:1, also bad). It keeps its white text on hover. A button with a colour class (`has-*-color`, `!important`) or an inline colour is not touched by this rule.
   FOCUS TOO (added after the 69-page sweep, 2026-10-16): the parent's `a:hover, a:focus { color: #000 }` (0,1,1) beats WordPress' `.wp-block-button__link { color: #fff }`
   (0,1,0), so keyboard focus made the text BLACK on the dark grey: 1.75:1. That was there before task C too (it is the parent's rule); the first version of this rule
   fixed hover only. `:focus` and not `:focus-visible`, because the parent's rule is `:focus` and a mouse click leaves the button focused as well. */
.wp-block-button__link:hover,
.wp-block-button__link:focus {
  color: #fff;
}

/* The contact boxes on /kontakt/ (variant V4, decision 64). The first version of task C made the box headings and the "Mer information" buttons orange-brown
   (--sg-brand-text); Tobias found that it did not feel like Sotargruppen. Orange TEXT cannot be saved by a paler box (#f68a3c is 2.44:1 even on pure white), so
   the orange changes role instead: a LINE along the top of the box, and the SURFACE of the button. Tobias and a colleague chose this out of four options shown as
   pictures (2026-10-16; tools/out/C/varianter/). The line is decoration and 1.4.11 does not apply to it. The heading takes the body text colour: 13.07:1 on the
   box's #ffe8d8, which passes 4.5:1 whatever its size (tests/run.php locks that, so a later font size change cannot drop it under the requirement unnoticed).
   No `!important`: the parent's `.border-0 { border: 0 !important }` is on the outer `.card`, not on `.card-body.orange-contact-box`, and nothing else sets a
   border on the box. These classes are used on /kontakt/ only (14 boxes, 13 buttons; counted on all 69 sitemap addresses, 2026-10-16). */
.orange-contact-box {
  border-top: 6px solid var(--sg-brand);
}

.orange-contact-box h3 {
  color: #212529;  /* the body text colour */
}

.custom-orange-button.custom-orange-button {
  background-color: var(--sg-brand);
  border-color: var(--sg-brand);
  color: var(--sg-on-brand);  /* 6.33:1 on #f68a3c */
}

/* One hover for every button with a border (decision 63): the button FILLS, and its text gets readable contrast against the fill. Before this the site had three
   patterns: `.outline-link` ("Boka om") filled black with white text, the footer buttons only changed their text colour, and the contact box buttons filled orange.
   The parent's `.outline-link` is the model and is not touched here: `background-color: #000`, white text, 21:1. Grey (#6c7d8a, the footer button's border) is
   not used as a fill: white on it is 4.25:1. Links in running text are not buttons and keep their own hover (darker, thicker underline).
   KEYBOARD FOCUS LOOKS THE SAME AS HOVER. Measured before this rule (2026-10-16, real Tab presses): the contact box buttons and the footer buttons got only the
   focus ring and no fill when focused, while `.outline-link` already filled (the parent has `.outline-link:focus`). The ring from "Visible keyboard focus"
   is still drawn around the filled button. Specificity: `.footer a.rm-button:hover` (0,3,1) beats this file's `.footer a:hover` (0,2,1), and the contact box
   rule (0,3,0) equals the parent's `.custom-orange-button.custom-orange-button:hover`, which loses because this stylesheet loads last. */
.custom-orange-button.custom-orange-button:hover,
.custom-orange-button.custom-orange-button:focus-visible,
.footer a.rm-button:hover,
.footer a.rm-button:focus-visible {
  background-color: #000;
  border-color: #000;
  color: #fff;
}

/* The model button itself was broken on one template, found by the 69-page sweep (2026-10-16) and in production before task C: on the location pages
   (page-2.php: /sotare-i-lund/, /sotning-helsingborg/, /sotning-angelholm/, /sotning-vanersborg/, /ventilation-helsingborg/, /ventilation-angelholm/) the parent's
   `.page-template-page-2 .row-section a { color: black }` (0,2,1) beats the parent's own `.outline-link:hover, .outline-link:focus { color: white }` (0,2,0), so
   "Gå till bokasidan" / "Boka här" became BLACK text on the black fill: 1.00:1, an empty black box under the mouse and under keyboard focus. Only the text colour
   is set; the fill and the border are the parent's. `:focus` like the parent's rule. Specificity (0,4,1). */
.page-template-page-2 .row-section a.outline-link:hover,
.page-template-page-2 .row-section a.outline-link:focus {
  color: #fff;
}

/* The booking modal (#bookingmodal in header.php, on every page; opened by the booking links). It is closed when a page loads, so neither axe nor the
   all-states sweep had ever measured it; it was found when one run measured a page without Bootstrap (2026-10-16) and then measured on purpose, OPEN.
   (1) The link in the modal text ("höra av dig till oss") sits on the dark #2c2e35, and the default link colour of task C is made for LIGHT surfaces: it made the
       link worse, 3.40:1 (Bootstrap's blue) -> 2.34:1, hover 1.53:1, focus 1.55:1 (the parent's black `a:focus`). OUR regression. The link takes the colour of the
       text around it (white, 13.55:1) and an underline, which is then what tells it apart (1.4.1); hover and focus thicken the underline.
   (2) The four card headings were orange on white, 2.44:1 (22-25 px, so 3:1 or 4.5:1 is required): in the parent from the start. They follow V4 from /kontakt/:
       body text colour (15.43:1) and the orange as a line along the top of the card.
   Chosen on pictures by Chat and Tobias (2026-10-19; tools/out/V4/modal-bilder/). Specificity: `#bookingmodal .modal-text a` (1,1,1) beats `a`, `a:hover` and the
   parent's `a:focus`; `.modal-booking-card h3` (0,1,1) equals the parent's rule (also inside its media query) and wins because this file loads last. */
#bookingmodal .modal-text a {
  color: #fff;
  text-decoration: underline;
}

#bookingmodal .modal-text a:hover,
#bookingmodal .modal-text a:focus {
  color: #fff;
  text-decoration-thickness: 2px;
}

.modal-booking-card {
  border-top: 6px solid var(--sg-brand);
}

.modal-booking-card h3 {
  color: #212529;  /* the body text colour */
}

/* A STOPGAP, NOT A FIX: the block-editor buttons on /har-finns-vi/ (12) and /rensning/ (1). WordPress paints their orange background INLINE
   (style="background-color:#f18630") and their white text with `.has-white-color { color: ... !important }`, so nothing but an `!important` rule can change it.
   The rule is bounded as tightly as it can be: it needs the class AND one of the five orange shades the site uses in an inline background, so a white button on any
   other background is untouched. Measured: white on #f18630 is 2.56:1, #212529 on it is 6.0:1. THE REAL FIX is in the content (the editor should set dark text on
   these buttons), after which this rule can be deleted. If an editor picks a new orange, `npm run a11y` finds the button (color-contrast). */
.wp-block-button__link.has-white-color.has-background[style*="background-color:#f18630"],
.wp-block-button__link.has-white-color.has-background[style*="background-color:#f0862f"],
.wp-block-button__link.has-white-color.has-background[style*="background-color:#f08630"],
.wp-block-button__link.has-white-color.has-background[style*="background-color:#f68a3c"],
.wp-block-button__link.has-white-color.has-background[style*="background-color:#ff863d"] {
  color: var(--sg-on-brand) !important;
}

/* Grey texts that were just under the requirement. Value changes only, no design decision. The selectors are as specific as the parent's rules (`.article-item span`
   and `.row-article-items .article-item span` are (0,2,1)); this file loads last, so equal specificity is enough. */
.article-item span.article-item-date {
  color: #595959;  /* was #888888, 3.54:1; now 7:1 */
}

.article-heading span.publish-date {
  color: #595959;  /* was #777777, 4.48:1 */
}

.ac > .ac-q {
  color: #566673;  /* was #6c7d8a, 4.25:1; now 5.93:1 */
}

/* ==========================================================================
   Links in running text are underlined (WCAG 1.4.1 Use of Color)

   A link inside a block of text must be distinguishable from the text WITHOUT relying on colour. With the new link colour (2.66:1 against the body text #212529) colour
   alone does not do it (3:1 is the requirement when colour is the only difference), and 31 links were already the same colour as their text, or nearly (the 21 grey
   #484a53 links on /kontakt/ are 1.75:1): axe's own rule `link-in-text-block` found 13 elements on the 69 addresses, at each of the two widths. An underline works for everyone.

   WHICH LINKS: CSS cannot say "a link with text around it" (text nodes are not counted by :only-child), so the rule lists the containers that hold running text: p, li, td,
   dd and blockquote inside <main>, and two template containers that print text without a <p> (the orange contact boxes on /kontakt/, the columns of the location pages).
   Measured 2026-10-15 on 69 addresses: of the 152 links in running text, all but 2 are underlined (5 already were). It also reaches about 16 links that stand alone in their block. That was accepted (Chat and Tobias):
   an underlined stand-alone link is never an accessibility problem, and narrowing the selector for them would be more risk than gain. Buttons are left out (:not list).
   THE TWO THE RULE DOES NOT REACH are named in tools/links-check.js. That tool is what makes this safe: `npm run links` reads the RENDERED pages, classifies every link, and
   fails if a link in running text is not underlined, so new content that lands outside these selectors is found.
   ========================================================================== */
main p a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp),
main li a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp),
main td a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp),
main dd a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp),
main blockquote a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp),
main .orange-contact-box a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp),
.page-template-kontakt-ort main .col-lg-4 a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp) {
  color: var(--sg-brand-text);
  text-decoration: underline;
}

/* Hover feedback for those links: a thicker underline. The colour does not change on hover (it already has the contrast it needs, and a colour change would have to
   win against the rule above and the photo rule below). `:is()` only inflates the specificity of THIS rule, and this rule sets nothing but the thickness. */
:is(main p, main li, main td, main dd, main blockquote, main .orange-contact-box, .page-template-kontakt-ort main .col-lg-4) a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp):hover {
  text-decoration-thickness: 2px;
}

/* ON A PHOTO the text is white because the picture is dark, and brown would be harder to read there (measured: 3 links, on / and two ventilation pages; seen with the eyes,
   because axe cannot judge text on images). These links keep the colour of their text, and the underline from the rule above carries the difference. */
main .img-section p a:not(.btn, .button, .custom-orange-button, .outline-link, .normal-lapp) {
  color: inherit;
}
