/* Keyboard affordances: the skip link, the shortcuts dialog, and the
   visually-hidden class the live region uses.

   Loaded on every page, templated and legacy alike, so the two page systems
   answer the keyboard the same way. Colours come from the site's theme
   tokens, so everything here follows the light/dark toggle without a second
   block restating it. */

/* ---- visually hidden ----
   Off screen for the eye, present for a screen reader. The clip-path pair is
   the usual belt and braces: `clip` for what still only understands that. */
.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- skip link ----
   The first focusable thing in the document. Off screen until it is focused,
   then it comes down over the banner — it has to be visible where it lands,
   and the banner is fixed, so it sits above that.

   Its two colours are its own rather than borrowed. It used to take
   --surface-raised for its paper and --link-color for its ink, which travel
   together on the templated pages and do not on the legacy ones: those
   declare --link-color and not --surface-raised, so in dark mode a #a3a3ff
   link landed on the #fff fallback at 2.3:1 — on the one control a
   keyboard-only reader cannot do without. Declared here, in both themes,
   8.4:1 and 9.5:1. */
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10000;
  transform: translateY(-120%);
  padding: 0.7rem 1.1rem;
  background: #fffefb;
  color: #3a3ab1;
  border: 1px solid #55555f;
  border-radius: 0 0 8px 0;
  box-shadow: 0 2px 8px rgba(60, 50, 40, 0.24);
  font: 500 0.95rem/1.2 Roboto, -apple-system, sans-serif;
  text-decoration: none;
}
html.dark-mode .skip-link {
  background: #15151e;
  color: #b3b3ff;
  border-color: #a8a8b4;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
}
.skip-link:focus {
  transform: none;
  outline: 2px solid currentColor;
  outline-offset: 2px;
}
@media (prefers-reduced-motion: no-preference) {
  .skip-link { transition: transform 0.15s ease; }
}

/* Focus should be visible on the landmark the skip link lands on, but an
   outline around the landmark is an outline around the whole page — 4,000px
   of it on /chats and 18,000 on /news, which reads as a border somebody left
   on the page rather than as a focus ring. A bar across the top of the region
   says the same thing where the reader is actually looking.

   The accent is written out rather than taken from --link-color: the legacy
   pages set that to near-black, which would draw a rule rather than read as
   an indicator. */
#main-content:focus { outline: none; }
#main-content:focus-visible {
  outline: none;
  box-shadow: inset 0 3px 0 #5a5ad1;
}
html.dark-mode #main-content:focus-visible { box-shadow: inset 0 3px 0 #8a8aff; }

/* The footer's way in, for a reader who would never guess that "?" does
   anything. Quiet — it is a footnote about the page, not a call to action. */
.footer-keys { margin: 0.4rem 0 0; }
/* The link needs the same rules as the button and needs them to win: the
   footer sets its own anchors to inherit, undecorated (css/site.css), which
   is right for the org credits above and wrong for this one. */
.footer-keys button,
.site-footer .footer-keys a,
.footer-keys a {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 0.85em;
  /* No opacity here: the footer's own colour clears AA on the footer's
     background, and fading it to 85% took it to 3.6:1, which does not. */
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.footer-keys button:hover,
.site-footer .footer-keys a:hover,
.footer-keys a:hover { color: var(--link-color, #5a5ad1); }
/* Two items on one line, kept apart without a divider between them. */
.footer-keys > * + * { margin-left: 1.1em; }
.footer-keys kbd {
  padding: 0 0.3em;
  border: 1px solid currentColor;
  border-radius: 3px;
  font-family: "Roboto Mono", ui-monospace, Menlo, monospace;
  font-size: 0.9em;
  text-decoration: none;
}

/* j and k land on a disclosure as well as on a heading, so a disclosure needs
   the same clearance under the fixed banner that css/site.css gives headings
   — without it the question the reader jumped to sits behind the banner. */
#main-content details { scroll-margin-top: calc(var(--banner-h, 64px) + 20px); }

/* ---- the shortcuts dialog ----
   Given the wireframe's own treatment — paper, a ruled edge, a hard offset
   cast — because it is part of this site rather than a browser affordance
   dropped on top of it. The destinations are grouped the way the site is
   grouped and set in columns: eighteen of them in one list is a list nobody
   reads. */
.kb-dialog {
  width: min(58rem, calc(100vw - 2.5rem));
  max-height: min(86vh, 46rem);
  overflow: auto;
  padding: 1.5rem 1.6rem 1.4rem;
  border: 1.5px solid var(--border-strong, #c6c3bd);
  border-radius: 6px;
  background: var(--surface-raised, #fff);
  color: var(--text, #212529);
  box-shadow: 5px 5px 0 var(--rule, rgba(60, 50, 40, 0.16)),
    var(--shadow-lg, 0 12px 40px rgba(0, 0, 0, 0.3));
  font-family: Roboto, -apple-system, sans-serif;
}
.kb-dialog::backdrop { background: rgba(20, 18, 30, 0.55); }
.kb-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 0 1.15rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--border-subtle, #dedcd7);
}
.kb-dialog h2 {
  margin: 0;
  font-family: "Roboto Mono", ui-monospace, Menlo, monospace;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-strong, #111118);
}
.kb-dialog h2:focus { outline: none; }
/* The two column heads, and the group heads inside the left one. */
.kb-dialog h3 {
  margin: 0 0 0.7rem;
  font-family: "Roboto Mono", ui-monospace, Menlo, monospace;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--link-color, #5a5ad1);
}
.kb-dialog h3 span {
  margin-left: 0.6em;
  font-size: 0.94em;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--text-soft, #3f3f46);
}
.kb-dialog h4 {
  margin: 0 0 0.25rem;
  font-family: Roboto, sans-serif;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-soft, #3f3f46);
}
.kb-close {
  flex: none;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--border-subtle, #dedcd7);
  border-radius: 5px;
  background: none;
  color: var(--text-soft, #3f3f46);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
}
.kb-close:hover { border-color: var(--link-color, #5a5ad1); color: var(--link-color, #5a5ad1); }

.kb-cols {
  display: grid;
  grid-template-columns: minmax(0, 2.15fr) minmax(0, 1fr);
  gap: 1.8rem;
  align-items: start;
}
/* The groups flow down one column and on into the next, so a group is never
   split across the fold. */
.kb-groups { columns: 2; column-gap: 1.6rem; }
.kb-group {
  break-inside: avoid;
  margin: 0 0 0.95rem;
}
.kb-here {
  padding-left: 1.6rem;
  border-left: 1px solid var(--border-subtle, #dedcd7);
}

.kb-dialog table { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
.kb-dialog th,
.kb-dialog td {
  padding: 0.17rem 0;
  text-align: left;
  font-weight: 400;
  vertical-align: baseline;
}
.kb-dialog th { width: 3.4rem; white-space: nowrap; }
.kb-here th { width: 4.2rem; }
.kb-dialog td { color: var(--text-soft, #3f3f46); }
.kb-dialog kbd {
  display: inline-block;
  min-width: 1.3em;
  padding: 0.08em 0.32em;
  border: 1px solid var(--border-strong, #c6c3bd);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--surface-sunken, #f0eeea);
  color: var(--text-strong, #111118);
  font-family: "Roboto Mono", ui-monospace, Menlo, monospace;
  font-size: 0.8em;
  text-align: center;
}
.kb-off {
  margin: 1.3rem 0 0;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border-subtle, #dedcd7);
  font-size: 0.83rem;
  color: var(--text-soft, #3f3f46);
}
.kb-off label { display: flex; align-items: center; gap: 0.45rem; cursor: pointer; }
.kb-off span { display: block; margin-top: 0.3rem; opacity: 0.85; }

@media (max-width: 860px) {
  .kb-cols { grid-template-columns: 1fr; gap: 1.3rem; }
  .kb-groups { columns: 1; }
  .kb-here { padding-left: 0; border-left: 0; padding-top: 1rem; border-top: 1px solid var(--border-subtle, #dedcd7); }
}

/* While "g" is waiting for its second key: a press that appears to have done
   nothing is visibly a press waiting for the rest of itself. A pseudo-element
   rather than markup, so it is decorative by construction and no screen
   reader has to hear about a key that is only half pressed. */
html.kb-armed body::after {
  content: "g …";
  position: fixed;
  left: 1rem;
  bottom: 1rem;
  z-index: 9999;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--border-strong, #c6c3bd);
  border-radius: 6px;
  background: var(--surface-overlay, #fff);
  color: var(--text-strong, #111118);
  font: 500 0.8rem/1 "Roboto Mono", ui-monospace, Menlo, monospace;
  box-shadow: var(--shadow-md, 0 2px 8px rgba(0, 0, 0, 0.18));
  pointer-events: none;
}

@media (max-width: 620px) {
  .kb-cols { grid-template-columns: 1fr; gap: 1.1rem; }
}

/* ---- the closed mobile drawer ----
   Below the sidebar breakpoint the nav is moved off screen with a transform
   (css/site.css), which hides it from the eye but not from the keyboard: its
   twenty-odd links stay in the tab order at x = -250px, where a focus ring
   cannot be seen. Visibility is what takes a subtree out of the tab order,
   and it is delayed on the way out so the slide still animates. */
@media (max-width: 1279px) {
  .gs-sidebar {
    visibility: hidden;
    transition: transform 0.25s ease, visibility 0s linear 0.25s;
  }
  body.nav-open .gs-sidebar {
    visibility: visible;
    transition: transform 0.25s ease, visibility 0s;
  }
}
