/* ACCESSIBILITY REPAIRS -- 2026-09-29 (lane portal-a11y-repairs).
 *
 * Every rule here answers ONE measured failure from the viewport matrix
 * (platform/test/tools/viewport-matrix.mjs: elementFromPoint hit-testing, real
 * Tab-key traversal, computed geometry). Nothing here restyles anything: no
 * colours, no type, no layout composition. The only levers used are
 * padding / min-size / scroll-padding / outline-offset / transparent-border hit
 * areas. Linked LAST in index.html so it wins by order at equal specificity;
 * sheets that attach later (settings-fidelity.css, ...) are outranked with an
 * ID or a `:root` prefix.
 *
 * Tests: platform/test/portal-a11y-repairs-ui.test.js (real browser geometry).
 */

/* ---- FOCUS COVERED BY THE STICKY SUBNAV / 2-STEP BANNER ------------------
   `.subnav` and `.policy-tabs` are `position: sticky; top: 8px` (~50px tall)
   and the fixed enrol banner / dock sit over the ends of the viewport. A
   control the browser scrolls into view on Tab used to come to rest UNDER
   them. scroll-padding changes where a scroll comes to rest, not the layout.
   The bottom value is app.css's (`--phonedock`); only the top is added, and
   the short-viewport (zoom 200%) case reserves the banner as well. */
html { scroll-padding-top: 76px; }
/* <=700px the sticky sub-nav is two rows (~108px with its 8px offset), not one. */
@media (max-width: 700px) { html { scroll-padding-top: 124px; } }
@media (max-height: 480px) {
  html { scroll-padding-top: 124px; scroll-padding-bottom: 96px; }
  html.enrolpinned { scroll-padding-bottom: 178px; }
}

/* ---- FOCUS RING CLIPPED BY AN overflow:hidden PARENT ----------------------
   The global ring is `outline: 2px; outline-offset: 1px` (3px outside the box).
   These controls sit flush inside an ancestor that clips overflow, so the ring
   was cut on 1-4 sides. An INSET ring (negative offset) is drawn wholly inside
   the control's own box and cannot be clipped. */
@media (max-width: 899px) {
  body.signed-in #navRow .navbtn:focus-visible { outline-offset: -3px; }
}
:root .jump-row:focus-visible,
:root #settingsTabs .account-section-select:focus,
:root #settingsTabs.account-tabs > .chip:focus-visible,
:root #accountPasswordDisclosureSummary:focus-visible,
:root #accountHistoryDisclosureSummary:focus-visible,
:root #playProfilePanel .play-actions > button:focus-visible,
:root .fc-chips button:focus-visible,
:root .apps-context-summary:focus-visible,
:root .co4-period-header:focus-visible,
:root #deviceSetupDialog .ds-body a:focus-visible,
:root #deviceSetupDialog .ds-body button:focus-visible,
:root #schedForm input:focus-visible,
:root #schedForm input:focus { outline-offset: -3px; }
#authHomeLink:focus-visible,
:root body:has(#loginShell:not(.hide)) #authHomeLink:focus-visible,
:root body:has(#loginShell:not(.hide)) #authHomeLink { outline-offset: -3px; }
#childOnboarding.co-v3 .co4-period-header:focus-visible { outline-offset: -3px; }
/* the primary button's focus glow (a 24px box-shadow) is what the panel's
   overflow:hidden cut; the inset ring above remains the indicator. */
:root #playProfilePanel .play-actions > button:focus-visible,
:root #billingSettingsPanel .primary:focus-visible { box-shadow: none; }

/* ---- TOUCH TARGETS UNDER 44x44 -------------------------------------------
   Text controls grow with min-height. Switch-like controls keep their painted
   size: the extra hit area is a transparent border (background-clip:
   padding-box) pulled back with a negative margin so layout does not move. */
:root .support-faq-q,
:root .invMoreGroup > summary,
:root #categories .cat-explainer > summary,
:root .web-rules-help > summary,
:root #appsCard details.screen-help > summary,
:root .policy-tab,
:root .subnav .chip.navbtn,
:root #categories .cat-refresh,
:root #categories .cat-device-action,
:root .apps-delivery-head > .apps-refresh,
:root .apps-device-list .appsdelrow > .apps-device-action,
:root #schedAddBtn,
:root #copNameEdit,
:root #securityRows > .arow > .iconbtn,
:root .fc-head .child-headtop > .btnlink { min-height: 44px; box-sizing: border-box; }
:root .support-faq-q,
:root .invMoreGroup > summary,
:root #categories .cat-explainer > summary,
:root .web-rules-help > summary,
:root #appsCard details.screen-help > summary { display: flex; align-items: center; }
:root .subnav .chip.navbtn { min-width: 44px; }
:root .pw-app-open { display: flex; align-items: center; min-height: 44px; }
:root .consentRow,
:root #rememberMeRow,
:root #notifPrefCard .consentRow,
:root #privacyCard .consentRow,
:root #reportCard .consentRow { min-height: 44px; align-items: center; box-sizing: border-box; }
:root #deviceMenuOverlay #deviceMenuClose { min-height: 44px; min-width: 44px; box-sizing: border-box; }
/* sign-in / sign-up rows: the auth sheet outranks a bare selector, so match its
   own `body:has(#loginShell...)` prefix. */
:root body:has(#loginShell:not(.hide)) #signin #rememberMeRow { min-height: 44px; align-items: center; }
/* An inline link that WRAPS has a bounding box whose centre is the gap between
   its two lines (measured at 320px: "Read the / Terms" hit-tested to the label's
   text span). a single inline-block (text may still wrap INSIDE it, max-width:100% so it never leaves a 160px viewport) keeps it one box; padding + equal negative margin gives a
   44px hit area without changing the line box. */
#signupTermsLink,
:root body:has(#loginShell:not(.hide)) #signupTermsLink { display: inline-block; max-width: 100%; white-space: normal; padding-block: 13px; margin-block: -13px; }
:root .consentRow input { margin-top: 0; }
:root #timeDial { height: 44px; }
:root .fc-head .child-headtop > .btnlink { display: inline-flex; align-items: center; }

:root .cat-cat-row > .sw {
  box-sizing: border-box; height: 44px; margin-block: -9px;
  border-block: 9px solid transparent; background-clip: padding-box; border-radius: 13px / 22px;
}
:root #powerToggle {
  box-sizing: border-box; height: 44px; margin-block: -6px;
  border-block: 6px solid transparent; background-clip: padding-box; border-radius: 16px / 22px;
}
:root .navchildlock {
  box-sizing: border-box; width: 44px; height: 44px; margin: -5px;
  border-width: 6px; background-clip: padding-box; border-radius: 14px;
}

/* ---- HORIZONTAL CHIP STRIPS: FOCUS MUST SCROLL THE CHIP INTO VIEW ----------
   `scroll-snap-type: x proximity` on the sub-nav / settings strips let the
   browser settle a keyboard-focused chip OUTSIDE the strip's clip box (Help at
   the right end, Overview at the left) so it painted under nothing and
   hit-tested to <body>. Snapping is a swipe nicety; scrolling the focused chip
   into view is not optional, so the strips keep their overflow and lose the snap. */
:root .subnav,
:root #settingsTabs.account-tabs,
:root .policy-tabs { scroll-snap-type: none; }

/* The child sub-nav strip already WRAPS to two rows at <=560px (DEF-004 above:
   "wrap instead of scrolling so every destination stays discoverable"). At
   561-700px (a phone in landscape, a 640px-wide window, 200% browser zoom of a
   1280px window) it still scrolled sideways, and a sticky strip that has to
   scroll sideways swallowed keyboard focus: Chromium scrolled the PAGE to the
   chip and never scrolled the strip, leaving "Overview" painted outside the
   strip's clip where it hit-tested to <body>. Same wrap, wider range. */
@media (min-width: 561px) and (max-width: 700px) {
  .screen > .subnav { flex-wrap: wrap; overflow-x: visible; row-gap: 4px; }
  .screen > .subnav .subnavbtn { flex: 0 1 auto; }
}

/* A modal taller than a 360px-high (200% zoom) viewport: the panel is capped at
   84vh with no overflow, so the confirm button sat below the visible area and
   could not be scrolled to. Let the panel scroll itself. */
#cdmOverlay .pickpanel { overflow-y: auto; overscroll-behavior: contain; }

/* ---- R3 (2026-09-29): defects measured on the first replay of this sheet ------
   1. FORCED COLORS. The system repaints a `transparent` border in a system colour, so the
      transparent-border hit areas above became heavy black frames (a 46x26 switch painted
      46x44 with 9px borders, hiding its on/off state). Under forced colors the painted box
      goes back to its unrepaired size; the 44px hit area is a pointer nicety, a visible
      state is not. Focus rings are `outline`, which forced colors keeps.
   2. LONG E-MAIL. An 80-character local part has no break opportunity, so the "current
      address" line widened the whole page to 692px at 320px. */
@media (forced-colors: active) {
  :root .cat-cat-row > .sw { height: 26px; margin-block: 0; border-block-width: 0; }
  :root #powerToggle { height: 32px; margin-block: 0; border-block-width: 0; }
  :root .navchildlock { width: 34px; height: 34px; margin: 0; border-width: 1px; }
}
:root #echangeCurrent { overflow-wrap: anywhere; }
