/* =============================================================================
   TG Access — collapsible sections, on their own because more than one shell
   needs them

   WHY ITS OWN FILE, written before the second shell needed it rather than after.
   These rules lived in `dashboard.css`. The accordion is now going on Settings
   (same shell, fine) AND on /guide, whose shell links only `guide.css` — so
   wrapping the guide's groups in the macro while the rules stayed here would
   have given it five unstyled headers and no behaviour.

   That is exactly what happened to the language picker earlier the same night:
   a component added to five more templates while its stylesheet stayed in the
   one shell that already had it, costing 38 gate failures and a 51x21px tap
   target on nineteen pages. Doing it in this order is the whole lesson.

   THEMED THROUGH FOUR VARIABLES, defaulted on `:root` and NOT on `.acc`. The
   defaults have to sit on an ancestor: both this file and the shell's own
   stylesheet match `.acc` with identical specificity, so whichever loads later
   would win — and a custom property declared ON the element always beats one
   inherited from an ancestor, whatever the link order. The picker shipped with
   the defaults on the component for one commit and painted 2.96:1 text on a
   dark panel across nineteen pages.
   ========================================================================== */

/* THE SIZES BELOW ARE TOKENS, not hand-picked rems. This block shipped with five
   off-scale values — 1.02rem, .95rem, .92rem, .86rem and .8rem — which is the exact
   pattern `tokens.css` names as the problem it exists to solve, reintroduced by the commit
   that added the accordion. Each is now the nearest step on the scale.

   Nothing caught it: the design-system suite checks that the tokens EXIST, never that a
   stylesheet USES them. That gate is queued, and it is the actual fix — five values
   corrected by hand will drift again. */

:root {
  --acc-ink:        var(--ink);
  --acc-ink-muted:  var(--ink-muted);
  --acc-line:       var(--line);
  --acc-hover:      rgba(0, 0, 0, .03);
}

/* ---------------------------------------------------------------------------
   COLLAPSIBLE SECTIONS

   The catalogue page is five long sections and finding anything meant scrolling
   past the other four. These turn each one into a header row that opens.

   Logical properties throughout. The chevron points at the content, which is to
   the right in English and to the left in Arabic, so it is rotated off a
   logical axis rather than a physical one — `rotate(-90deg)` would have aimed
   it off the page in Arabic.

   The animation is on `grid-template-rows`, not `height`, so a section opens to
   whatever its content needs without anybody measuring it in JavaScript. `0fr`
   to `1fr` is the modern way to do this and it degrades to an instant open
   where it is not supported, which is the right failure.
   --------------------------------------------------------------------------- */
.acc { padding: 0; overflow: hidden; }

/* The stack's spacing, in one place. `.acc-list` was added to three templates with no
   rules behind it, so the gap between drawers was whatever `.card`'s margin happened to
   be on that page — which is how three pages ended up looking like three components. */
.acc-list { display: grid; gap: 12px; }
.acc-list > .acc { margin: 0; }

.acc-h { margin: 0; font-size: inherit; font-weight: inherit; }

.acc-head {
  display: grid;
  grid-template-columns: auto 1fr auto auto auto;
  grid-template-areas: "chev title chip count state" "chev sub sub sub sub";
  align-items: center;
  gap: 2px 12px;
  inline-size: 100%;
  /* 44px of target without a magic number: padding plus the title's line box. */
  padding: 14px 18px;
  border: 0;
  background: none;
  text-align: start;
  font: inherit;
  color: var(--acc-ink);
  cursor: pointer;
}

.acc-head:hover { background: var(--acc-hover); }

.acc-head:focus-visible {
  outline: 2px solid var(--dash-focus, #2563eb);
  outline-offset: -2px;
}

.acc-chevron {
  grid-area: chev;
  inline-size: 10px;
  block-size: 10px;
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  /* Points at the content when closed, down when open. The start-side rotation
     is mirrored for free because the borders are logical. */
  transform: rotate(-45deg);
  transition: transform .18s ease;
  opacity: .55;
}

[dir="rtl"] .acc-chevron { transform: rotate(135deg); }

.acc-head[aria-expanded="true"] .acc-chevron,
[dir="rtl"] .acc-head[aria-expanded="true"] .acc-chevron { transform: rotate(45deg); }

.acc-title { grid-area: title; font-size: var(--text-md); font-weight: 700; }

.acc-count {
  grid-area: count;
  min-inline-size: 1.6rem;
  padding: 1px 8px;
  border-radius: var(--radius-pill, 999px);
  background: var(--dash-chip, rgba(0, 0, 0, .06));
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--acc-ink-muted);
}

.acc-state { grid-area: state; font-size: var(--text-md); line-height: 1; }

.acc-chip { grid-area: chip; justify-self: end; }

.acc-sub {
  grid-area: sub;
  font-size: var(--text-base);
  line-height: 1.45;
  color: var(--acc-ink-muted);
  /* min-width against a 1fr track's min-content minimum: a long summary would
     otherwise widen the header past the card and give the page a sideways
     scrollbar on a phone. */
  min-inline-size: 0;
}

.acc-body { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .22s ease; }

/* The clip lives on `.acc-inner`, the macro's own wrapper, and not on `.acc-body > *`.
   Two reasons, both measured:

   `grid-template-rows` sizes the DECLARED rows only, so a section with two children had
   the second in an implicit `auto` row that `0fr` never touched — /dashboard/settings'
   USDT section measured 601px CLOSED, rows `40px 411px 72.6px`. One wrapper means one
   row, whatever the caller writes.

   And `min-block-size: 0` with `overflow: hidden` collapses an element's CONTENT and not
   its padding, so `.pad`'s `--space-5` top and bottom kept every closed dashboard section
   at exactly 40px of body — while /guide, whose children have no padding, collapsed to
   zero. The wrapper owns no spacing, so there is nothing left to keep. */
.acc-inner { min-block-size: 0; overflow: hidden; }
.acc[data-acc-closed] .acc-body { grid-template-rows: 0fr; }

/* `visibility: hidden`, NOT JUST `overflow: hidden`, AND THAT IS A KEYBOARD FIX.
   Collapsing to `0fr` takes the content off screen but leaves it FOCUSABLE: tabbing
   through a page with four closed sections walked into inputs nobody could see, and
   `test_every_focusable_control_paints_a_visible_focus_ring` found seven of them on the
   catalogue — a control with no visible focus indicator because it has no visible
   anything (WCAG 2.4.7, and 2.1.1 for the trap it makes).

   `visibility: hidden` removes an element from the tab order, which `overflow` and a zero
   grid row do not, and unlike `display: none` it leaves the row height animatable — so the
   slide survives. It inherits, so the one declaration covers everything inside. */
.acc[data-acc-closed] .acc-inner { visibility: hidden; }

/* A reader who asked for less motion gets the same behaviour without the slide. */
@media (prefers-reduced-motion: reduce) {
  .acc-body, .acc-chevron { transition: none; }
}

.acc-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-block: 14px 18px;
}

.acc-search { flex: 1 1 14rem; min-inline-size: 0; }

.acc-search input {
  inline-size: 100%;
  min-block-size: 44px;
  padding: 8px 14px;
  font: inherit;
  border: 1px solid var(--acc-line);
  border-radius: var(--radius-sm, 10px);
  background: var(--dash-field, #fff);
  color: var(--acc-ink);
}

.acc-search input:focus-visible {
  outline: 2px solid var(--dash-focus, #2563eb);
  outline-offset: 2px;
}

.acc-nomatch { margin: 0 0 18px; color: var(--acc-ink-muted); font-size: var(--text-base); }

/* A section the search has ruled out. `display: none` rather than a class that
   only dims it: a reader scanning results should not have to tell "no match"
   apart from "closed". */
.acc[data-acc-hidden] { display: none; }

@media (max-width: 560px) {
  /* A CLOSED HEADER IS A ROW, NOT A PARAGRAPH. This used to give the count and the
     state marker a line of their own — "three things on one line at 360px leaves the
     title two words wide" — which made the header three stacked rows and a closed
     section 125px tall on the catalogue and 105px on Settings, against the ~64-80px a
     header row should be. Measured, both over the 96px the gate now enforces.

     So the count stays beside the title (a two-digit chip and a single glyph are not
     what crowds a title) and the SUMMARY is clamped to one line with an ellipsis. The
     summary is the part that was costing two rows, and it is also the part a reader
     gets in full the moment they open the section — unlike the count, which only
     means anything closed. */
  .acc-head {
    justify-items: start;
    grid-template-columns: auto 1fr auto auto auto;
    grid-template-areas: "chev title chip count state" "chev sub sub sub sub";
  }
  .acc-sub {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-inline-size: 100%;
  }
}
