/*
 * focus-visible.css -- the application's single keyboard focus indicator.
 *
 * Task 65. The vendor sheet css/dashboard/css/app.css opens with
 * `*:focus { outline: 0 !important; }`, which defeated every scoped focus style
 * in the application and left keyboard focus invisible on every screen
 * (WCAG 2.4.7 Focus Visible, Level AA: "Any keyboard operable user interface
 * has a mode of operation where the keyboard focus indicator is visible.").
 *
 * The vendor file is deliberately left alone -- this repository is a fork that
 * still syncs upstream, so the reset is out-ranked rather than deleted. That
 * costs one `!important`: `*:focus` and `:focus-visible` carry equal
 * specificity, so this sheet must both be marked important and be emitted last
 * (php/UIHandler.php) to win. Scoped focus styles elsewhere therefore need
 * `!important` too -- see docs/design/focus-indicator-register.md.
 *
 * :focus-visible, not :focus, on purpose: the browser draws the ring for
 * keyboard and assistive-technology focus and withholds it for a mouse click,
 * which is almost certainly what the original reset was reaching for.
 */

:focus-visible {
	/* #2f6fed is the existing --wa-admin-accent. Measured against every surface
	   this app paints: 3.16:1 on the #2a2a2a chrome, 4.55:1 on white panels,
	   4.24:1 on the #f5f7fa page -- all clear of the 3:1 floor. */
	outline: 2px solid #2f6fed !important;
	/* Bootstrap 3.3.2 ships `a:focus { outline-offset: -2px }`, which outranks a
	   bare `:focus-visible` on specificity (0,1,1) beats (0,1,0) -- so without
	   this the ring drew *inside* every anchor in the app. Measured live on pj. */
	outline-offset: 2px !important;
}

/* Controls that sit flush against a container edge would have the offset ring
   clipped by the container's overflow, so they draw it inside their own box.
   The sidebars earn their place here by sight, not by measurement: their items
   are 229px wide inside a 230px panel, so an outset ring is clipped down to two
   disconnected horizontal lines. Seen headed at 360 on pj. */
.table-responsive :focus-visible,
.dataTables_wrapper :focus-visible,
.main-sidebar :focus-visible,
.control-sidebar :focus-visible {
	outline-offset: -2px !important;
}

/*
 * Closed off-canvas panels must leave the tab order.
 *
 * Task 65.3. Both of the shell's slide-away panels stay `visibility: visible`
 * while closed, so every control inside them keeps its place in the tab order
 * and the new focus ring is painted off the side of the screen -- WCAG 2.4.7
 * (Focus Visible) and 2.4.11 (Focus Not Obscured, Minimum). Measured headed on
 * pj: at 360 the eleven main-navigation items focus at x = -230 with the
 * viewport 360 wide; the right control sidebar does the same at every width,
 * six stops at x = 1287 in a 1280 viewport.
 *
 * `visibility: hidden` is what removes a subtree from the tab order; `opacity`
 * and `transform` do not. It has to name the descendants as well as the panel:
 * MDN is explicit that "descendants of the element will be visible if they have
 * visibility set to visible", and inside the control sidebar something below
 * `.tab-content` re-asserts `visible`, which kept all six of its controls in the
 * tab order when only the panel itself was hidden.
 *
 * The hide is delayed by the length of the slide so the panel does not empty out
 * while it is still animating away. The open state sets visibility alone and no
 * transition, so controls become focusable the moment the panel starts moving in
 * and keep whatever transitions AdminLTE gave them.
 *
 * State hooks verified live, not assumed: the main sidebar is open when <body>
 * carries `sidebar-open`; the control sidebar when it carries
 * `control-sidebar-open`.
 *
 * The cubic-bezier below is AdminLTE's own sidebar easing, copied verbatim.
 * `transition` is a shorthand, so declaring visibility here would otherwise
 * reset the vendor's transform transition and change how the panel slides.
 * It is reproduced to preserve existing motion, not chosen as new easing.
 */

@media (max-width: 767px) {
	body:not(.sidebar-open) .main-sidebar {
		visibility: hidden;
		transition: transform .3s cubic-bezier(.32, 1.25, .375, 1.15),
		            visibility 0s linear .3s;
	}

	body:not(.sidebar-open) .main-sidebar * {
		visibility: hidden;
		transition: visibility 0s linear .3s;
	}

	body.sidebar-open .main-sidebar,
	body.sidebar-open .main-sidebar * {
		visibility: visible;
	}
}

.control-sidebar:not(.control-sidebar-open) {
	visibility: hidden;
	transition: right .3s ease-in-out, visibility 0s linear .3s;
}

.control-sidebar:not(.control-sidebar-open) * {
	visibility: hidden;
	transition: visibility 0s linear .3s;
}

.control-sidebar.control-sidebar-open,
.control-sidebar.control-sidebar-open * {
	visibility: visible;
}

/*
 * Tiles whose anchor collapses to zero height draw their ring on the tile.
 *
 * Task 65.4. The dashboard's stat tiles are written as an inline <a> whose only
 * child is a floated Bootstrap grid column (`div.panel.widget.col-md-2 ...`).
 * A float is out of flow and an inline box has no line box to hold it, so the
 * anchor measures 0x0 and the focus ring painted at that point is invisible --
 * WCAG 2.4.7 (Focus Visible). Measured headed on pj: two such stops at 1280
 * (981,623) and the same two at 360 (315,559 and 315,469), both 0x0.
 *
 * The obvious repair -- giving the anchor a box -- was measured and rejected.
 * `display: block` still yields 716x0, because a block box does not contain a
 * float either; only a block formatting context does. `display: flow-root`
 * (716x173) and `display: inline-block` (151x173) both work, and both rearrange
 * the dashboard: 11 and 12 of the 12 tiles move respectively.
 *
 * So the ring is drawn on the child instead. The tile is what the user sees and
 * what they are aiming at, it measures 119x153, and nothing about the layout
 * changes -- verified live, 0 of 12 tiles moved.
 *
 * The offset is inset: the tile sits flush inside its row, so an outset ring
 * would be clipped, the same reason the sidebars appear in the list above.
 */

a:focus-visible > .panel.widget {
	outline: 2px solid #2f6fed !important;
	outline-offset: -2px !important;
}
