/* =============================================================================
   accessibility.css - shared accessibility primitives.

   Loaded on every public page. Keep it small and keep it first in the cascade:
   everything here is meant to be overridable by page styles except where marked
   !important, which is reserved for the visually-hidden helpers.

   Rules that live here and MUST NOT be redefined elsewhere:
     .sr-only            visually hidden, still read by assistive technology
     .sr-only-focusable  the same, but revealed on focus (skip links)

   History: three stylesheets used to define `.sr-only { display: none }`, which
   removes the element from the accessibility tree as well as from the screen.
   Every screen-reader-only label in the project was therefore silent. Do not
   reintroduce display:none or visibility:hidden for this class.
   ========================================================================== */

/* -- Visually hidden, still announced ------------------------------------- */

.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Skip links: hidden until a keyboard user tabs to them, then fully visible. */
.sr-only-focusable:focus,
.sr-only-focusable:focus-within {
  position: static !important;
  width: auto !important;
  height: auto !important;
  padding: 0.5rem 1rem !important;
  margin: 0 !important;
  overflow: visible !important;
  clip: auto !important;
  clip-path: none !important;
  white-space: normal !important;
}

/* -- Skip link presentation ----------------------------------------------- */

.skip-link {
  display: inline-block;
  background: #467d1e;
  color: #fff;
  font-weight: 700;
  text-decoration: none;
  border-radius: 0 0 6px 0;
}

/* White ring on the skip link's dark green ground: the site's own dashed
   #89b95c would sit at too low a contrast against it. Scoped to this one
   component that did not exist before, so it overrides nothing. */
.skip-link:focus {
  position: absolute !important;
  z-index: 2147483647;
  top: 0;
  left: 0;
  color: #fff;
  outline: 3px solid #fff;
  outline-offset: -6px;
}

/* -- Focus indicator: OWNED BY theme.css, do not restate here -------------- */

/* theme.css owns the site-wide focus ring (`*:focus-visible { outline: 2px
 * dashed #89b95c }`). Do not add a global focus rule here - anything more
 * specific silently replaces that ring everywhere. Change theme.css instead. */

/* Exception: a region that only takes focus programmatically. The main region
   receives focus from the skip link, and a dialog receives focus when it opens;
   theme.css's universal rules would then tint them green, scale them down and
   draw a ring around the whole area.
   `background: none` is deliberately NOT applied: written as a blanket
   [tabindex='-1'] rule it wiped the dark scrim off the login dialog's overlay
   the moment that overlay took focus. Only the tint from theme.css needs
   cancelling, and `background-color: transparent` there does that without
   touching a background the design sets. */
main:focus,
[role='main']:focus,
[role='dialog']:focus,
[role='alertdialog']:focus,
main:focus-visible,
[role='main']:focus-visible,
[role='dialog']:focus-visible,
[role='alertdialog']:focus-visible {
  outline: none;
  transform: none;
}

/* theme.css paints every :focus with a pale green. On a region carrying
   tabindex="-1" that means clicking anywhere inside it washes the whole block
   green, because the click focuses the region itself. Dialogs are deliberately
   left out: their overlay needs its own background to stay a scrim. */
main:focus,
[role='main']:focus,
main:focus-visible,
[role='main']:focus-visible {
  background: none;
}

/* -- Heading compatibility classes ---------------------------------------- */

/* Used when a heading tag has to become a non-heading element because it was
   marking up body content rather than a section title. The class carries the
   default heading metrics so the element keeps its previous look; any page-
   specific rule must be extended alongside it, e.g.

     .download_btn_text h5,
     .download_btn_text .as-h5 { ... }

   See docs/design/accessibility/guideline.md section 3. */

/* -- Buttons rebuilt from clickable divs ----------------------------------- */

/* Applied when a <div onclick> becomes a real <button>, so the browser's default
   button chrome does not change the design. Page styles still apply on top. */
.as-plain-button {
  display: inline-block;
  padding: 0;
  margin: 0;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  text-align: inherit;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

/* -- Reduced motion -------------------------------------------------------- */

@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;
  }
}

/* -- Footer text that used to be a heading --------------------------------- */

/* The footer marked its address, phone, opening hours and copyright line as
   <h6>, and its menu column titles as <h5>. None of the first group is a
   heading, and the levels made page after page report "H1 jumps straight to H6".

   No styling is declared here on purpose. An earlier version guessed at generic
   heading metrics and got font-size, weight and line-height all wrong, shrinking
   every page by 28px. The real rules live in footer_bar_*.css and now name the
   new classes alongside the old tags, so the footer renders byte-identically. */

/* -- Retagged headings ----------------------------------------------------- */

/* When a heading changes level to fix the document outline, it keeps an
   `as-hN` class naming the tag it used to be, and every stylesheet rule that
   targeted that tag carries a twin selector for the class. What the twins cannot
   carry is the bare `h1..h6` reset the CSS bundle applies by tag: the new tag
   picks up that reset, the old one had different values, and pages grew by up to
   57px.
   Values below are measured from the original tags, not assumed. */

[class*="as-h"] {
  margin-top: 0;
  margin-bottom: 0;
}

/* -- Fieldset used purely for grouping ------------------------------------- */

/* Choice questions are wrapped in <fieldset> so a screen reader announces the
   question when focus enters the options. The browser gives
   a fieldset a groove border, horizontal margin and min-inline-size:min-content,
   none of which the surrounding design expects.
   Declared on the element, not a class, so any styling the page already applies
   through its own classes still wins. */

fieldset {
  border: 0;
  padding: 0;
  margin-inline: 0;
  min-inline-size: 0;
}

legend {
  /* A legend shrink-wraps its text even with display:block, where the <label>
     it replaced filled the row. width:100% restores that. */
  display: block;
  width: 100%;
  max-width: 100%;
  padding: 0;
  margin-bottom: 0;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}

/* -- Form errors ---------------------------------------------------------- */

/* Shown next to the field that failed, by reportFormError() in contactUs.js.
   #b3261e measures 6.54:1 on white - WCAG AA asks 4.5:1 for body text. Colour
   is not the only signal: the field carries aria-invalid and the message is
   plain text, so it survives greyscale and colour blindness. */
.form-error {
  margin: 0.35rem 0 0;
  color: #b3261e;
  font-size: 0.95rem;
  line-height: 1.4;
}

/* The invalid field gets a border to match, so the error is visible without
   reading - but only while it is actually invalid. */
#addnew_form_data [aria-invalid='true'] {
  border-color: #b3261e;
}

/* -- Ranking tables ------------------------------------------------------- */

/* The ranking is a real <table> now. Two things need restoring -
   the UA's display:table would override the flex layout member-ranking.css sets
   by class, and the .left-group wrapper is gone because a <div> inside a <tr>
   gets lifted out of the table. Gap values below are the ones it used. */

table.ranking-table,
table.ranking-table > thead,
table.ranking-table > tbody {
  display: block;
  border-collapse: collapse;
}

/* Only above the mobile breakpoint: member-ranking.css lays these out with
   flex:1 and its own gaps under 768px, and an unscoped rule here would win over
   its media query and squash the columns. */
@media screen and (min-width: 769px) {
  .ranking-table .table-header,
  .ranking-table .ranking-record {
    justify-content: flex-start;
    gap: 4.25rem;
  }

  .ranking-table .table-body .ranking-record {
    gap: 4rem;
  }

  .ranking-table .header-point-total,
  .ranking-table .ranking-record > .point-total {
    margin-left: auto;
  }
}

/* Below the breakpoint member-ranking.css sized the three left-hand cells as one
   group and let the points column take the rest. With the wrapper gone, a plain
   space-between spreads all four evenly instead. Margins between the leading
   cells reproduce the old gaps without adding one before the points. */
@media screen and (max-width: 768px) {
  .ranking-table .table-header,
  .ranking-table .table-body .ranking-record {
    justify-content: flex-start;
  }

  .ranking-table .table-header .header-title {
    flex: 0 1 auto;
  }

  .ranking-table .table-header .header-point-total {
    flex: 1;
  }

  .ranking-table .table-body .ranking-record > .point-total {
    margin-left: auto;
  }
}

/* Only in this band: under 541px the avatar and the name carry their own
   margins in member-ranking.css, and adding one here would double them. */
@media screen and (min-width: 541px) and (max-width: 768px) {
  /* 5rem, not the wrapper's 2.5rem gap: the headings were flex:1 inside
     .left-group, so each box also absorbed a share of its free space. Measured
     against the pre-conversion layout, which puts them at the same offsets
     anywhere in this band. */
  .ranking-table .table-header .header-title + .header-title {
    margin-left: 5rem;
  }

  .ranking-table .table-body .ranking-record > td + td:not(.point-total) {
    margin-left: 1.75rem;
  }
}

/* The empty-state row carries no class, so it stays a table-row inside a block
   tbody - an anonymous table that shrinks to its content and strands the text
   on the left. */
.ranking-table .table-body-empty,
.ranking-table .table-body-empty > tr,
.ranking-table .no-ranking-data {
  display: block;
  width: 100%;
}

/* <th> defaults to bold and centred; the divs it replaced were neither. */
.ranking-table th {
  font-weight: inherit;
  text-align: inherit;
}

.ranking-table td:not(.no-ranking-data) {
  padding: 0;
}

/* The avatar is sized with width/height:100% against its cell. A <td> resolves
   that percentage differently from the <div> it replaced - 52px instead of 40 -
   so the picture swallowed its wreath and crowded the name. Pin the two sizes
   member-ranking.css used to produce. */
.ranking-table .ranking-record .avatar img {
  width: 50px;
  height: 50px;
}

@media screen and (max-width: 540px) {
  .ranking-table .ranking-record .avatar img {
    width: 40px;
    height: 40px;
  }
}
