/**
 * Focus visibility — the focus ring (Layer B), plus the skip link's own styling (Layer A).
 *
 * WHY THIS FILE EXISTS
 * --------------------
 * A keyboard user can only use the Tab key if they can SEE where focus is.
 * Before this file there was no focus indicator on buttons or links:
 *
 *   - bs5/style.css lumps `.btn:focus-visible` in with `.btn.active` and
 *     `.btn:active`, so a focused button looked exactly like a pressed one
 *     (it changes background/border only — no outline, no ring).
 *   - bs5/skin-carbonshelf.css removes the browser outline on
 *     `button.close` and `.app-search-form .search-btn` without putting
 *     anything back.
 *   - The Bootstrap 5 stylesheet is never loaded (bs5-layout.ctp loads
 *     Bootstrap's JS from CDN only), so Bootstrap's own focus ring — which
 *     lives in its CSS — is not available to inherit.
 *   - bs3/style.css gives select2 `outline: 0` and `border: 0` and never
 *     adds a focus ring back, so on bs3-layout and public-layout a focused
 *     dropdown was pixel-identical to an unfocused one. See the select2
 *     block at the bottom of this file.
 *
 * Text inputs are NOT handled here — they keep the browser default outline,
 * which nothing in this codebase removes. Checkboxes already have their own
 * ring at bs5/style.css `input[type="checkbox"]:focus`. This file
 * deliberately only fills the gaps, so nothing already working is disturbed.
 *
 * WHY `:focus-visible` AND NOT `:focus`
 * -------------------------------------
 * `:focus-visible` only matches when the browser judges that the user needs
 * the indicator — keyboard and assistive tech, not a mouse click. This is
 * why the outlines were suppressed in the first place: on `:focus` a ring
 * appeared on every mouse click and looked wrong. With `:focus-visible`,
 * mouse users see no change at all.
 *
 * WHY `outline` AND NOT `box-shadow`
 * ----------------------------------
 * `outline` takes no space in the layout, so nothing shifts when focus
 * moves, and modern browsers make it follow `border-radius` on its own.
 * `outline-offset` leaves a gap of page background between the control's own
 * fill and the ring, which keeps the ring readable on a filled button
 * (a `.btn-primary`) as well as on a bare icon link. It also avoids
 * colliding with the `box-shadow` rings the form fields already use.
 *
 * Loaded by bs3-layout, bs5-layout and public-layout — the three layouts
 * that load the focus script stack. That is also why the `.skip-link` rules at the
 * bottom live here rather than in one layout's own stylesheet: the anchor is rendered
 * by bs3-layout and bs5-layout, and a stylesheet only one of them loads would leave
 * the other rendering "Skip to main content" as permanently visible text.
 * See docs/client-side/focus-and-tab-order-engineering.md (Layers A and B).
 */

/*
 * The ring's two values, in one place so every rule below agrees.
 *
 * NOTE THERE IS NO COLOUR TOKEN. That is deliberate. The `outline` shorthand
 * below names a width and a style but no colour, which resets `outline-color`
 * to its initial value — `currentColor`, the element's own text colour. So
 * the ring is whatever colour the browser would already have drawn it, and
 * this file introduces no colour of its own.
 *
 * Why that is the right call rather than picking a hex:
 *   - It adapts per control. On dark text the ring is dark; on a filled
 *     `.btn-primary` with white text the ring is white and clearly visible.
 *     A single fixed hex cannot do both.
 *   - `var(--primary-color)` would have been the obvious candidate and is
 *     wrong: it is redefined per skin (#e94235 app, #056ABC directory,
 *     #002170 gst-essentials, #EF7F1A signature), and a ring drawn in the
 *     primary colour disappears on a primary-filled button.
 *   - Nothing new has to be kept in sync with the skins.
 *
 * These sit on bare `:root` — not inside a media query, not inside a skin
 * selector — because every rule in this file depends on them. A `var()` with
 * no definition anywhere makes the WHOLE declaration invalid and the browser
 * throws it away, which means no ring at all rather than a fallback ring.
 */
:root {
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;
}

/*
 * The shared ring.
 *
 * `.btn` and `.nav-link` are listed alongside the bare element selectors
 * because titlebar action buttons are anchors whose class comes from
 * NavItemElement (`nav-item-js printIcon btn btn-primary btn-sm`, and so
 * on) — they are not always plain `<a>` and not always `.nav-link`.
 */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
.nav-link:focus-visible {
  outline: var(--focus-ring-width) solid;
  outline-offset: var(--focus-ring-offset);
}

/*
 * Re-assert the ring where an existing rule removed it.
 *
 * `!important` is required here and only here: the rules being corrected
 * use `outline: none !important` themselves
 * (bs5/skin-carbonshelf.css, `.app-search-form .search-btn:focus`), and an
 * `!important` declaration can only be beaten by another one. `button.close`
 * is included for the same reason even though its rule is not `!important`,
 * so both corrections read as one intentional block.
 */
button.close:focus-visible,
.app-search-form .search-btn:focus-visible {
  outline: var(--focus-ring-width) solid !important;
  outline-offset: var(--focus-ring-offset);
}

/*
 * select2 dropdowns.
 *
 * THE PROBLEM. A select2 dropdown IS in the tab order. select2 moves the tab
 * stop off the hidden `<select>` (which it leaves at `tabindex="-1"` and
 * `aria-hidden="true"`) and onto the `.select2-selection` box it renders with
 * `tabindex="0"`. So Tab does reach it. What was missing on the legacy
 * layouts was any sign that it had:
 *
 *   - bs3/style.css sets `border: 0` and `outline: 0` on
 *     `.select2-container--default .select2-selection--single`, which also
 *     kills the browser's own focus outline.
 *   - The only `.select2-container--focus` selector bs3/style.css has is in
 *     that same group, so the focused state gets exactly the same
 *     declarations as the unfocused one — no ring is ever added back.
 *   - bs3/skin-carbonshelf.css only restores a flat `border-bottom`, again
 *     for focused and unfocused alike.
 *
 * bs5/style.css does add a ring, so this was a bs3-layout / public-layout
 * defect only. On a form whose dropdowns sit next to each other (three in a
 * row on Artifactconfigurations edit) three invisible stops in succession
 * read as Tab jumping straight over the whole group.
 *
 * WHY `.select2-container--focus` AND NOT `:focus-visible`. select2 signals
 * focus by putting that class on the container, and it is the hook
 * bs5/style.css already uses. Matching it means bs3 now looks exactly like
 * bs5 instead of gaining a second, different-looking ring. It does mean the
 * ring also shows on a mouse click — which is precisely how bs5 behaves
 * today, so the two layouts stay identical.
 *
 * WHY `box-shadow` HERE and not `outline` like the rules above. Same reason:
 * these are the values bs5 already uses. An `outline` would additionally
 * have to fight the `outline: 0` quoted above.
 *
 * SPECIFICITY. This selector is (0,3,0). It beats bs3/style.css's
 * `.select2-container--default .select2-selection--single` at (0,2,0), and
 * ties its `.select2.select2-container--default .select2-selection--single`
 * at (0,3,0) — won on load order, because bs3-layout.ctp loads this file
 * after bs3/style.css. bs3/skin-carbonshelf.css's (0,4,0) rule sets only
 * `border-bottom`, a different property, so there is no conflict. On bs5
 * these declarations are identical to the ones already present, so nothing
 * changes there.
 */
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple {
  border-color: #80bdff;
  box-shadow: 0 0 0 .25rem rgba(13, 110, 253, .25);
}

/**
 * Skip link — the first focusable element on the page.
 *
 * Hidden until focused, then pinned to the top-left above the fixed header
 * (which sits at z-index 1034-1036), so a keyboard user's first Tab reveals it.
 *
 * Clipped rather than `display: none` / `visibility: hidden`, because those remove
 * the element from the tab order entirely, which would defeat the point of it.
 *
 * Written out longhand: this stylesheet has no sr-only / visually-hidden helper
 * to compose from.
 *
 * position: fixed (not absolute) so it stays on screen even if the page is
 * scrolled when focus reaches it.
 *
 * See docs/client-side/focus-and-tab-order-engineering.md (Layer A — page regions).
 */
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  z-index: 1040;
}

.skip-link:focus {
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  clip-path: none;
  padding: 8px 16px;
  background-color: #fff;
  color: rgb(27, 101, 206);
  border: 2px solid rgb(27, 101, 206);
  border-bottom-right-radius: 0.5em;
  text-decoration: underline;
}
