/*SECTION - Submit request confirmation modal */

#page-container
  > div
  > div.support-request
  > div
  > div
  > div
  > div
  > div
  > div {
  border-radius: 0.5rem;
  color: var(--clr-neutral-160);
  max-width: 50vw !important;
  align-items: center;
  padding: 4rem 0;
}

#page-container
  > div
  > div.support-request
  > div
  > div
  > div:nth-child(3)
  > div
  > div
  > div
  > header {
  border-bottom: 0;
}
#page-container
  > div
  > div.support-request
  > div
  > div
  > div:nth-child(3)
  > div
  > div
  > div
  > header
  > div.unFdE6BdKF9sLCu4WcD8A2g3BKFiuGUE {
  right: 25px;
  top: -40px;
}

#page-container
  > div
  > div.support-request
  > div
  > div
  > div:nth-child(3)
  > div
  > div
  > div
  > header
  > div.QxkpxJisIaZ3NcAsfzZQ1wYSd3dMNLyB.RblI0Jw3Z2smxXJnBz65QNsyW07rP8Ff {
  font-size: var(--step-1);
}

.vfxBZjJkrtIyH2I2nKukgXUHFHmA8uVD {
  margin-block-end: 0;
  padding: 0 !important;
}

/* Header Icon */
#page-container
  > div
  > div.support-request
  > div
  > div
  > div
  > div
  > div
  > div
  > header
  > div.QxkpxJisIaZ3NcAsfzZQ1wYSd3dMNLyB.RblI0Jw3Z2smxXJnBz65QNsyW07rP8Ff
  > svg {
  color: var(--clr-success-120);
  width: 1.5rem;
  height: 1.5rem;
}

/* Subheader */
.gEy7Kpx7LuVZ6Kqv_rULuwiha5kt9YW4 {
  font-size: var(--step-1) !important;
  font-weight: var(--font-bold) !important;
}

/* Article containers */
#page-container
  > div
  > div.support-request
  > div
  > div
  > div
  > div
  > div
  > div
  > div.mzG5ROjHucNzlVRSJxv23wolOtloBrPl {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  color: var(--clr-neutral-160);
  padding: var(--space-m) var(--space-2xl);
}

#page-container
  > div
  > div.support-request
  > div
  > div
  > div
  > div
  > div
  > div
  > div.mzG5ROjHucNzlVRSJxv23wolOtloBrPl
  > div {
  border: 1px solid var(--clr-neutral-40);
  border-radius: 0.5rem;
  padding: 1.5rem;
  position: relative;
  cursor: pointer;
  &:hover {
    border-color: var(--clr-neutral-40);
    box-shadow: var(--shadow-dropdown);
    transition-duration: var(--transition-duration);
  }
}

/* Article Link */
a.U1APFZw2SFqWlOEsnR7yqgBjwYkWt0y8 {
  font-size: var(--step-1) !important;
  font-weight: var(--font-bold) !important;
  text-decoration: underline !important;
  color: var(--clr-secondary-140) !important;
  display: inline-flex !important;
  gap: 0.25rem !important;
  align-items: center !important;
  &:hover,
  &:hover * {
    background-color: var(--clr-secondary-5);
    text-decoration: none;
    transition-duration: var(--transition-duration);
  }

  &::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
  }
}

.U1APFZw2SFqWlOEsnR7yqgBjwYkWt0y8 .Mg7j_WysI0nbxTJxBMPyIAeKipcqegBC {
  display: none !important;
  content: '';
  &:focus-visible {
    display: none;
  }
}

a.U1APFZw2SFqWlOEsnR7yqgBjwYkWt0y8::after {
  display: none;
  font: var(--fa-font-regular);
  content: '\f08e';
}

div._psoINas5BE_FuhmDF_PzwUIvwUGB9DB > svg {
  display: none;
}

/* Bottom Buttons */
.sAsWeSofCRZeQfIv9OtCQ8rkLJXO0WA8 {
  padding: 0 !important;
}

#page-container
  > div
  > div.support-request
  > div
  > div
  > div
  > div
  > div
  > div
  > div.sAsWeSofCRZeQfIv9OtCQ8rkLJXO0WA8.x0t42gsaZWqdOoOLoXrAJwmoscNVqloY
  > form
  > div.i02ZzfBKhWYrfJPFRdbMwgDcX3mpNvpl {
  color: var(--clr-neutral-160) !important;
  font-size: var(--step-1);
  font-weight: var(--font-bold);
  margin-block-end: 0.5rem;
}

.jG_FrCWI0bQAiZgDkZBFfQVGdEdRfjQ9 {
  font-size: var(--step-1) !important;
  color: var(--clr-neutral-160);
  margin-block-end: 0 !important;
}

#zd-abm-feedback-yes,
#zd-abm-feedback-no {
  display: inline-flex;
  width: fit-content;
  margin: 0.75rem !important;
  padding: 0.25rem 0.5rem;
  align-items: center;
  border: 1px solid var(--clr-neutral-160);
  border-radius: 0.25rem;
  font-size: var(--step-0);

  svg {
    margin: 0.25rem !important;
  }
}

#zd-abm-feedback-yes:hover {
  background-color: var(--clr-success-10);
  border: 1px solid var(--clr-success-140);
  color: var(--clr-success-140);
  transition-duration: var(--transition-duration);
}

#zd-abm-feedback-yes:hover {
  color: var(--clr-success-140);
  transition-duration: var(--transition-duration);
}

#zd-abm-feedback-yes:focus-within {
  background-color: var(--clr-success-140);
  border: 1px solid var(--clr-success-60);
  color: var(--clr-success-5);
}

#zd-abm-feedback-yes:focus-within * {
  color: var(--clr-success-5);
}

#zd-abm-feedback-no:hover {
  background-color: var(--clr-alert-10);
  border: 1px solid var(--clr-alert-140);
  color: var(--clr-alert-140);
  transition-duration: var(--transition-duration);
}

#zd-abm-feedback-no:hover * {
  color: var(--clr-alert-140);
  transition-duration: var(--transition-duration);
}

#zd-abm-feedback-no:focus-within {
  background-color: var(--clr-alert-140);
  border: 1px solid var(--clr-alert-60);
  color: var(--clr-alert-5);
}

#zd-abm-feedback-no:focus-within * {
  background-color: var(--clr-alert-140);
  color: var(--clr-alert-5);
}
/*!SECTION - Submit request confirmation modal */

/* Header */
.requests-header {
  margin-block-end: var(--space-s);
}

/* Filter tabs */
.requests {
  border-bottom: 1px solid var(--neutral-border-soft);
  padding: 1rem 1rem 0 0;
  display: flex;
  gap: 1.5rem;
}

.requests-page {
  .request-link {
    text-decoration: none;
    font-size: var(--step-1);
    color: var(--neutral-text-soft);
    font-weight: var(--font-bold);
    padding: 1rem 2rem;
    /* Held on every tab, not just the active one, so hovering can't
       nudge the row 4px taller. */
    border-bottom: 4px solid transparent;
    transition:
      color var(--motion-duration-control) var(--ease-out),
      border-color var(--motion-duration-control) var(--ease-out);

    &:hover {
      border-bottom-color: var(--neutral-border);
      color: var(--neutral-text);
    }

    /* The theme's focus convention: css-reset.css:19 owns the ring's colour,
       width and style sitewide, and a component only pins `--outline-offset`.
       Declaring `outline` here would have overridden all three.

       A `border-width: 0 0 4px` used to sit here as well, and it is gone as of
       2026-10-25. Its job was to cancel three sides of the
       `border: 2px solid var(--form-focus-ring)` that the reset rule used to add
       on focus -- the base rule above sets only the BOTTOM border, so that
       addition drew a 2px box on the other three sides and shifted the tab. The
       reset declaration is deleted, so there is nothing left to zero: an `<a>`
       has `border-style: none` on those three sides and they have no width to
       begin with.

       `border-radius` stays, and is not cosmetic on a tab with no visible box:
       the outline follows the border radius, so it is what rounds the ring. */
    &:focus-visible {
      --outline-offset: 2px;
      border-radius: var(--radius-sm);
    }
  }
  .is-active {
    color: var(--neutral-text);
    border-bottom-color: var(--neutral-text);
  }
}

.requests-filter {
  display: flex;
  gap: 2rem;
  align-items: flex-end;
  margin-block-end: var(--space-m);

  /* `.form-field` is `flex-direction: column` with NO gap
     (css-page-new-request.css:106), which is why the label sat straight on top
     of the field. The gap is added here rather than there on purpose: that rule
     is shared with the contact form, which is still on legacy tokens and has
     not been re-previewed this round.

     10px is Codex's `space/2-5`. Measured off the Input Documentation frame at
     1:1 on two separate labelled fields, both of which put 14px between the
     last row of label glyphs and the field's top border; backing out Sora
     SemiBold 14/1.0's metrics from that leaves ~11px box-to-box. Font metrics
     make that +/-2, so the honest read is "10 or 12" and this takes the nearer
     of the two Codex tokens. A flat value, not --space-2xs, which is fluid
     (8px -> 12px) and would drift the gap with the viewport.

     `justify-content: flex-end` keeps the two fields' baselines aligned when
     one has a visible label and the other does not -- which is now the case
     again, the search label having gone back to sr-only. */
  .form-field {
    justify-content: flex-end;
    gap: 0.625rem;
  }

  /* The "Status:" label, which was unreadable in dark: dark grey on a dark
     page. `.form-field label` sets `color: var(--clr-neutral-160)`
     (css-page-new-request.css:114), and that primitive is #333333 defined in
     css-root.css -- a file with ZERO `data-theme` blocks in it, so the value is
     the same in both tiers and the label never flipped.

     --neutral-text is the role token for the same job and has both tiers
     (#10171e / #ffffff), so it flips on its own with no dark-tier rule here.

     Scoped to this page, same reasoning as the gap above: the selector it is
     beating is shared with the contact form, which is still on legacy tokens.
     (0,3,1) against that rule's (0,1,1). Colour only -- the label's size and
     weight are left alone, since Codex's label is Sora SemiBold 14 and this is
     Inter Regular 16, which is a real divergence but one for the form-field
     round rather than a dark-mode fix. */
  .form-field label {
    color: var(--neutral-text);
  }
}

@media screen and (max-width: 44.9em) {
  .requests-filter {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-xs);
  }
}

/* Codex Input/Select: 40px tall, 1px --form-border, 12px inline padding.
   #quick-search had no rule of its own anywhere before this. */
#quick-search,
#request-status-select {
  box-sizing: border-box;
  block-size: 2.5rem;
  padding-inline: 0.75rem;
  border: 1px solid var(--form-border);
  border-radius: var(--radius-sm);
  background-color: var(--form-bg);
  color: var(--neutral-text);
  font-family: inherit;
  font-size: var(--step-0);
  transition:
    border-color var(--motion-duration-control) var(--ease-out),
    background-color var(--motion-duration-control) var(--ease-out);

  /* Fill on hover, border on focus -- not both on both. That split is already
     the theme's, written down at css-page-header.css:493: "The border darkening
     belongs to :focus alone, so hover and focus are now distinguishable rather
     than hover pre-empting the focus treatment." This matched the refreshed
     search field at css-page-search-results.css:270 rather than the
     --neutral-text-soft border it used to invent. */
  &:hover {
    background-color: var(--form-bg-hover);
  }

  /* `--outline-offset` only: css-reset.css:19 owns the ring sitewide and a
     component pins nothing else. The 1px offset declared here before was not
     just redundant, it was narrower than the convention.

     This block is the one Joy pointed at on 2026-10-25 as "what we want" when
     she found the two warring focus styles, and it is worth saying why it looked
     right while the rest of the theme looked wrong. It used to restate the
     border as a 1px SHORTHAND, which overwrote the
     `border: 2px solid var(--form-focus-ring)` the reset rule added on focus --
     so this field never showed the extra rim, and every control WITHOUT a border
     of its own did. That reset declaration is now deleted, which makes the
     shorthand's width and style redundant; what remains is the colour change, so
     this is a `border-color` longhand and nothing more.

     --form-border-active / --form-bg-active are Codex's own focused field,
     sampled off the frame as #4f5f63 on #effbfb -- exact matches for the two
     tokens. Worth noting what that means: Codex does NOT tint the border with
     the ring colour, the ring is the outline alone. */
  &:focus-visible {
    --outline-offset: 2px;
    border-color: var(--form-border-active);
    background-color: var(--form-bg-active);
  }
}

/* Leading magnifier, Codex Search. Sits on the wrapper because an `input` can't
   carry a pseudo-element of its own.

   Centred rather than pinned to the bottom edge, which is what it needed while
   the label was visible. The label is `sr-only` again as of this round, so the
   wrapper is exactly the field's 40px and there is nothing above to shift it.

   The inline inset adds the border width instead of being a flat 0.75rem, for
   the reason already worked out at css-page-search-results.css:294: Codex draws
   the glyph at x=13, which is space/3 (12) plus border-width/regular (1),
   because the design's 12px is measured from INSIDE the stroke. This box is not
   the one carrying the border -- the input is -- so a flat 0.75rem would sit
   12px from the outer edge and 11px from the inside of it. */
.requests-filter .search .form-field {
  position: relative;
  /* `.search` carries `.flex-fill`, which was stretching the input to the full
     content width. Codex's Input measures 360px absolute and runs at roughly
     40% of its table; 28rem is that proportion at this theme's table width. */
  max-inline-size: 28rem;

  &::before {
    content: '';
    position: absolute;
    inset-inline-start: calc(0.75rem + var(--border-width-regular));
    inset-block-start: 50%;
    transform: translateY(-50%);
    inline-size: 1rem;
    block-size: 1rem;
    pointer-events: none;
    background-color: var(--neutral-icon);
    transition: background-color var(--motion-duration-control) var(--ease-out);
    --search-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Ccircle cx='7' cy='7' r='4.5' stroke='%23000' stroke-width='1.5'/%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-width='1.5' d='m10.5 10.5 3.5 3.5'/%3E%3C/svg%3E");
    -webkit-mask: var(--search-icon) no-repeat center / 1rem 1rem;
    mask: var(--search-icon) no-repeat center / 1rem 1rem;
  }

  /* Orange while the field is active, which Codex does too -- its focused
     Search variant draws the glyph #ef4523, an exact --brand-icon match.

     `:focus`, not `:focus-visible`: this is a decoration that should follow the
     caret however the field was reached, including a mouse click. Same idiom
     and the same token as css-page-search-results.css:315, which does this for
     the hero search. That one needs a `~` sibling rule as well as the `:has()`
     because its icon is a real element; ours is a pseudo-element on the
     ancestor, so `:has()` is the only form available.

     --brand-icon is single-tier, so the orange is identical in dark. That is
     deliberate on Codex's part, not a gap in our token table. */
  &:has(input:focus)::before {
    background-color: var(--brand-icon);
  }
}

#quick-search {
  inline-size: 100%;
  /* 12px inset + 16px icon + 8px gap */
  padding-inline-start: 2.25rem;

  &::placeholder {
    color: var(--neutral-text-soft);
    opacity: 1;
  }
}

#request-status-select {
  /* Intrinsic width, so the chevron reads as adjacent to the label the way
     Codex's does, instead of being pinned to a far-off right edge. */
  inline-size: auto;
  padding-inline-end: 2rem;
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-repeat: no-repeat;
  background-position: right 0.625rem center;
  background-size: 1rem 1rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23384649' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m4 6.5 4 4 4-4'/%3E%3C/svg%3E");
}

/* appearance:none kills the native arrow, so the chevron is ours. A data URI
   can't read var(--neutral-icon), so the dark tier restates it. */
:root[data-theme='dark'] #request-status-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23b2c3d2' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m4 6.5 4 4 4-4'/%3E%3C/svg%3E");
}

/* The sort indicator's box. Two kinds of element end up matching this, and the
   rule has to suit both: the span Zendesk injects into the column currently
   sorted, and the span page-requests.js creates on the other sortable columns
   so they have something to hang an icon on. Either way the icon inside is a
   Font Awesome `<i>` the kit swaps for an `<svg>`, which inherits `color`.

   Scoped to `.requests-page`, not `.requests-list-table > ...`: Zendesk puts
   its span inside the sort LINK, so it is a descendant of the table and never
   a direct child, and the old child selector matched nothing. */
.requests-page .requests-sort-symbol {
  flex: none;
  display: inline-flex;
  align-items: center;
  font-size: var(--step-0);
  color: var(--neutral-icon);
  /* Codex's gap between a header label and its indicator. */
  margin-inline-start: 0.5rem;
}

/* page-requests.js adds `.is-sorted` to the one column actually sorted. Codex
   gives that column the stronger icon colour, which is the whole active vs
   available hierarchy -- both sampled off `_datatable-header-cell` as exact
   token matches (#384649 unsorted, #10171e sorted). */
.requests-page .requests-sort-symbol.is-sorted {
  color: var(--neutral-icon-strong);
}

/* The template carries a stacked `<ul class="list-divider md:hidden">` as a
   mobile alternative to the table. We scroll the table horizontally instead,
   so this stays hidden at every width. `.md\:table-cell` and
   `.table-header-group` are gone: `td` and `thead` already default to those
   display values, and no element ever carried `.table-header-group`. */
.md\:hidden {
  display: none !important;
}
.pagination-list {
  padding-left: 0;
  margin-block: var(--space-s);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  list-style: none;
}

.pagination-first,
.pagination-prev,
.pagination-last,
.pagination-next {
  border: 1px solid var(--neutral-border);
  border-radius: var(--radius-sm);
  padding: 0.25rem 0.5rem;
  font-size: var(--step-0);
  transition:
    background-color var(--motion-duration-control) var(--ease-out),
    border-color var(--motion-duration-control) var(--ease-out);

  &:hover {
    border-color: var(--neutral-text-soft);
    background-color: var(--neutral-bg-component-hover);
  }
}

/* No `:focus-within` ring on the <li> above, which is what this had. The <a> is
   the focusable element, so css-reset.css:19 already rings IT -- an li-level
   ring would simply have been a second one, drawn further out. Pinning the
   offset on the link instead keeps one ring and keeps the convention. */
.pagination-first-link,
.pagination-prev-link,
.pagination-last-link,
.pagination-next-link {
  color: var(--neutral-text);
  text-decoration: none;
  font-size: var(--step-0);

  &:focus-visible {
    --outline-offset: 2px;
  }
}

/* The four `content: '\f0xx'` rules that used to sit here were doubly dead:
   each carried `display: none`, and the Font Awesome kit is SVG+JS, which has
   no webfont for a codepoint in `content:` to resolve against. */
.pagination-first-icon,
.pagination-prev-icon,
.pagination-last-icon,
.pagination-next-icon {
  display: none;
}

.pagination-first svg,
.pagination-prev svg,
.pagination-last svg,
.pagination-next svg {
  color: var(--neutral-icon);
}
.requests-page {
  /* A `display: table` box can't be a scroll container, so the table is
     wrapped. `tabindex` makes the overflow reachable by keyboard. */
  /* The outer border and its 12px radius live on the wrapper rather than the
     table: `border-collapse: collapse` makes a table ignore its own radius,
     and the tinted header would square the top corners off anyway. Clipping
     here rounds both ends properly. Measured off the Codex `hasBorder` variant
     — 1px --neutral-border, --radius-md. */
  .requests-table-scroll {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    margin-block-end: var(--space-xs);
    border: 1px solid var(--neutral-border);
    border-radius: var(--radius-md);

    /* The reset's `border: 2px solid` has to be held off here, or focusing the
       scroll box would double its 1px outer rule to 2px and reflow the table
       inside it. Restated as a shorthand at (0,2,0) against the reset's
       (0,1,0). */
    &:focus-visible {
      --outline-offset: 2px;
      border: 1px solid var(--neutral-border);
    }
  }

  /* Codex DataTable: tinted header, horizontal dividers only, no outer box,
     no vertical rules, 48px rows. The old block set `overflow-y: scroll` and
     `max-height: 80vh` on the table itself, which never did anything. */
  table {
    inline-size: 100%;
    min-inline-size: 44rem;
    table-layout: auto;
    border-collapse: collapse;
    border-spacing: 0;
    font-size: var(--step-0);
    color: var(--neutral-text);

    /* The bottom rule under the header row, added 2026-10-25 at Joy's request:
       "I would like to have a bottom border on the top row if at all possible."
       It was possible and it needed no restructuring -- the only reason the
       header had no bottom edge was that nothing had asked for one.

       --neutral-border, NOT --neutral-border-soft, and that is the whole
       decision here. `soft` (#c9d7d9 / #2e3e4e) is what the row dividers below
       use; reusing it would make the header/body boundary weigh exactly the
       same as a boundary between two ordinary rows, which is the one thing this
       border exists not to do. --neutral-border (#aab9bc / #3f5467) is the next
       step up and is already the wrapper's outer rule, so the table reads with
       three weights in a sensible order: outer edge and header rule at the same
       strength, row dividers quieter.

       It is visible in both tiers against both surfaces it sits between, which
       is why it is one declaration and not a declaration plus a dark override:
       #aab9bc against #deebec above and #f2fdfd below in light; #3f5467 against
       #2e3e4e above and #172029 below in dark.

       `border-collapse: collapse` does not double anything here -- the first
       body row declares only `border-block-end`, so there is no top border for
       this one to collide with.

       CODEX WOULD USE THE SOFT WEIGHT HERE, and this stays on the strong one
       anyway. Their clickable-row markup (quoted in full on the row hover below)
       puts `border-t border-neutral-soft` on every `<tr>`, so in Codex the
       header/body boundary IS the first row's top border, in --neutral-border-
       soft, indistinguishable from a divider between two rows. That is the
       arrangement Joy was looking at when she asked for a bottom border on the
       top row -- she asked because it did not read as a boundary. Matching Codex
       exactly would reproduce the thing she asked to have fixed, so the stronger
       weight is a deliberate deviation rather than an unchecked guess. Swap
       --neutral-border for --neutral-border-soft if she decides the header rule
       is too heavy; that is the whole change. */
    thead th {
      block-size: 3rem;
      padding: 0 var(--space-2xs);
      background-color: var(--neutral-bg-component);
      border-block-end: 1px solid var(--neutral-border);
      color: var(--neutral-text);
      font-size: var(--step-0);
      font-weight: var(--font-bold);
      text-align: start;
      white-space: nowrap;
      /* Matches `tbody td` below, so a header cell and a row fade at the same
         rate. Declared here rather than on the `:hover` rule so the fade runs
         on the way out as well as in. */
      transition: background-color var(--motion-duration-control)
        var(--ease-out);

      a {
        color: inherit;
        text-decoration: none;
        display: inline-flex;
        align-items: center;

        /* The cue moved to the cell -- `th:has(a:focus-visible)` below. Left to
           itself the anchor would keep the sitewide ring as well, and two rings
           2px apart is the doubling that commit removed. */
        &:focus-visible {
          outline: none;
        }
      }

      /* No `a::after` here any more, and no `:has(.requests-sort-symbol)`
         override either. Both are gone on purpose: the indicators are real
         Font Awesome elements injected by page-requests.js now, for the two
         reasons set out in that file. What used to sit here was a hand-drawn
         1.3px stroked mask standing in for Codex's pair, which measuring the
         `_datatable-header-cell` part showed to be a FILLED glyph -- so it was
         the wrong idiom, and it read as wrong the moment Zendesk's own solid
         triangle appeared in the column beside it.

         Do not reintroduce a CSS-drawn indicator. CSS can see THAT a column is
         sorted but never WHICH WAY, so it can only ever draw two of the three
         states. */
    }

    /* Column-header hover, added 2026-10-25. Joy: "I'd like to have a hover
       state on the column headers for created and last activity."

       GATED ON `:has(a)`, WHICH IS WHAT MAKES IT THOSE TWO COLUMNS AND NOT ALL
       FIVE. Only the sortable headers render an anchor -- `{{#link 'requests'
       sort_by=...}}` on Last activity always, and on the third column only when
       the filter is `my` (requests_page.hbs:108-116; under any other filter that
       cell is the plain-text "Requester" label). Subject, Id and Status are
       plain text and must not tint, because a hover on a cell that does nothing
       when clicked is a false affordance. Selecting on the anchor's presence
       rather than on a column index means the Created/Requester cell gains and
       loses the hover with the markup, automatically.

       THE TOKENS ARE THE HEADER'S OWN RAMP, one step per state:
       --neutral-bg-component (#deebec / #2e3e4e) at rest,
       --neutral-bg-component-hover (#d4e2e4 / #3f5467),
       --neutral-bg-component-active (#c9d7d9 / #536a80).
       Both tiers step lighter-to-darker in light and darker-to-lighter in dark
       and stay clear of each other, so this needs no dark override. Neither does
       the row hover below, since 2026-10-25; if a `[data-theme='dark']` block
       ever reappears on either, something has gone wrong with the tokens.

       THE HEADER HOVER IS CONFIRMED, NOT INFERRED. Joy, 2026-10-25, after
       digging the Codex docs out herself: "These are hover styles for light
       mode: var(--neutral-bg-component-soft-hover, #E5F2F3), and for headers:
       var(--neutral-bg-component-hover, #D4E2E4)." The second half is this rule
       and it stands. The first half turned out to name the wrong role for the
       ROW while giving the right colour -- see the rule below, where the markup
       she found afterwards shows Codex using `bg-neutral-highlight` there. The
       two are the same #e5f2f3 in light, which is how a wrong token survived a
       correct reading. Nothing in that correction touches the header.

       THE `-active` STEP IS CONFIRMED TOO, as of 2026-10-25, and the sentence
       that used to sit here -- "nothing confirms it; it is the ramp's own next
       notch" -- was right at the time and is now superseded. The DataTable
       Documentation frame 19918:6613 draws all three header-cell states in both
       tiers; measuring it gave #c9d7d9 / #536a80, which is this token. What the
       same measurement ALSO showed is that the state is `active/sorted`, the
       sorted column rather than a press -- see the rule below, which is where
       the `-active` fill now lives.

       It had been deduced before that arrived, and the deduction is worth
       keeping because it is how to resolve the next one of these: the Codex
       Component Library is file kfgXU57dOFwFeE1Ny3Fao5 (RECORD THIS -- earlier
       sessions used it without writing it down; `❖ DataTable` is page
       6738:49721 and its parts frame is 6738:55299). The variables bound inside
       that parts frame are exactly the six neutral component surfaces --
       component, -hover, -active and component-soft, -soft-hover, -soft-active
       -- and a datatable has exactly two interactive surfaces, the header cell
       and the row. The rows were already on the `soft` triplet, so the un-soft
       triplet is the header cell's.

       THAT DEDUCTION WAS RIGHT ABOUT THE HEADER AND WRONG ABOUT THE ROW, and the
       way it was wrong is the lesson: it could only pick from the tokens bound
       inside the frame, and the row's real hover token (--neutral-bg-highlight)
       IS bound in there -- it just reads as a highlight role rather than a
       surface-ramp step, so a ramp-shaped argument walked straight past it.
       Enumerating a frame's variables tells you the palette, never the mapping.

       CORRECTED 2026-10-25: THE STATES ARE IN FIGMA, ON THE DOCUMENTATION FRAME.
       This comment used to end by saying the file documents no labelled state at
       all and that the Codex website is where to go first. That was wrong in a
       specific and repeatable way. The PARTS frame (6738:55299) does return with
       no children and does render default variants only, which is what had been
       searched -- but `Documentation`, node 19918:6613, draws every labelled
       state for datatable-header-cell, datatable-body-cell and action-button,
       light panel beside dark. Joy found it. It is sparse to get_metadata as
       well, so the way to read one of these is a native-resolution screenshot
       and pixel sampling, not a child walk.
       **Look for a Documentation frame before concluding the file is silent.**

       `th:has(a):hover` tints the whole cell, which is the Codex look, while the
       anchor stays `inline-flex` -- so the few pixels of cell padding tint
       without being clickable. Deliberate: the alternative is an absolutely
       positioned overlay on the anchor, and the anchor already carries
       `class="relative"` for the sort symbol, so an overlay would have to fight
       that positioning context. If the whole cell should be the click target,
       that is the follow-up, not a tweak to this rule.

       THAT GAP IS NOW WIDER, KNOWINGLY: as of 2026-10-25 the focus ring is on
       the cell too (see below), so all three states are drawn to the cell's box
       while only the label navigates. The ring is the more honest of the two to
       be wrong about -- a keyboard user activates the focused cell with Enter,
       which works wherever the ring is -- but it does raise the value of
       closing the gap. */
    thead th:has(a) {
      &:hover {
        background-color: var(--neutral-bg-component-hover);
      }
    }

    /* THE SORTED COLUMN, and this is the correction that frame 19918:6613 made.
       Codex's third header-cell state is labelled `active/sorted` and it means
       THE COLUMN CURRENTLY SORTED, carrying this fill for as long as the sort
       holds. It is not a pressed state, and Codex documents no pressed state for
       a header cell at all -- so the `&:active` that used to sit on the rule
       above is gone rather than kept alongside. It was reusing exactly this
       colour, which would have made a click on an UNSORTED header flash the
       look of the sorted one for a frame.

       Only the fill was wrong. The ramp itself is confirmed by the same frame,
       at native render scale, in both tiers -- default #deebec/#2e3e4e, hover
       #d4e2e4/#3f5467, sorted #c9d7d9/#536a80, which is
       --neutral-bg-component / -hover / -active exactly. The `-active` notch had
       been the one value in this block that was deduced from the ramp rather
       than read off a source; it is now measured.

       `.is-sorted` is page-requests.js's doing, not Zendesk's -- Zendesk injects
       `.requests-sort-symbol` into the sorted column only, and the script tags
       it before standardising the icons (see the comment at :530 and the longer
       one in that file). So this selector needs no markup change, but it DOES
       depend on the script having run; with JS off the sorted column keeps the
       default fill and the sort direction is still readable from the icon
       Zendesk itself prints.

       THE NESTED `:hover` IS NOT REDUNDANT, and it is a judgement call Joy made
       on 2026-10-25: the sorted column does not move under the pointer. Codex
       gives no fourth value, so stepping past `-active` would mean inventing
       one. Specificity already favours this rule -- (0,2,2) against the hover
       rule's (0,1,3) -- but saying it out loud keeps the behaviour from drifting
       if anything more specific is ever added above. The cost, accepted
       knowingly: the one header you are most likely to re-click is the one that
       gives no hover feedback. */
    thead th:has(.requests-sort-symbol.is-sorted) {
      background-color: var(--neutral-bg-component-active);

      &:hover {
        background-color: var(--neutral-bg-component-active);
      }
    }

    /* THE RING IS ON THE CELL, NOT THE ANCHOR. Joy, 2026-10-25: "is it possible
       for the focus to go around the <th> rather than the <a> on the columns?"
       It is, and it makes the three header-cell states agree with each other --
       hover and sorted both fill the whole cell, so a ring hugging just the
       label was the one state drawn to a different box.

       TWO THINGS HERE ARE NOT INCIDENTAL.

       THE OFFSET IS NEGATIVE, so the ring paints just inside the cell's edge
       rather than outside it, and that is a requirement rather than a taste
       call. `.requests-table-scroll` is a scroll container, and `overflow-x:
       auto` makes the block axis `auto` as well -- `visible` is not a value the
       two axes are allowed to disagree on -- so it clips its descendants'
       outlines. A ring 2px outside a header cell would be cut wherever the cell
       meets the table's edge, and on the way there it would paint over the
       header's bottom rule and into the next column. Inside the border box it
       cannot be clipped and cannot shift anything. Same constraint, and the same
       answer, as the inset box-shadow named in css-reset.css.

       THE COLOUR AND WIDTH ARE WRITTEN OUT, which this theme's convention
       normally forbids -- css-reset.css:19 owns the ring sitewide and a
       component pins only `--outline-offset`. Neither half of that is available
       here: `:focus-visible` matches the focused element, so the reset's rule
       never reaches the `th` at all, and the `--outline-*` properties it
       declares are set ON the anchor, which is a descendant, so they cannot
       inherit upward either. Drawing it explicitly from --form-focus-ring is the
       established fallback for exactly this case -- css-page-header.css:2306,
       css-page-search-results.css:1404 and css-search.css:287 all do it -- and
       it keeps the token shared, so a recolour still reaches this rule. Only the
       2px and the `solid` are restated.

       Depends on `:has()`, as the hover and sorted rules above already do, so it
       adds no new support floor. The anchor's own ring is cancelled rather than
       left to sit inside this one -- two concentric rings 2px apart is the
       doubling the previous commit existed to remove. */
    thead th:has(a:focus-visible) {
      outline: 2px solid var(--form-focus-ring);
      outline-offset: -2px;
    }

    /* Both of these are confirmed against `datatable-body-cell` on the
       Documentation frame (19918:6613), measured 2026-10-25: the cell band is
       48px, which is this 3rem, and the fill is #f2fdfd light / #172029 dark,
       which is --neutral-bg-component-soft in both tiers.

       The more useful half of that reading is a NEGATIVE: the body cell's own
       hover variant paints the SAME colour as its default in both tiers. The
       hover genuinely belongs to the <tr>, not the cell, which is what the rule
       below does -- so that arrangement is Codex's and not just ours. Codex's
       body cell does have one state we have no equivalent for,
       `active` = --neutral-bg-component-soft-active (#deebec / #3f5467); it is a
       SELECTED row, and nothing here is selectable.

       THE BLOCK PADDING IS NEW, 2026-10-25, and it is a bug fix rather than a
       spacing preference. Joy: "when the <a> text wraps in the subject column,
       there is no padding on the bottom." The padding was flatly `0` on the
       block axis, and on a one-line row that was invisible -- a table cell
       treats `block-size` as a MINIMUM, so the 48px band held the row open and
       `vertical-align: middle` centred the single line inside it, which looks
       exactly like padding. A wrapped subject is two lines at line-height 1.5,
       which is 48px of content on its own: the band's minimum is met by the text
       itself, the cell grows to fit, and the glyphs run edge to edge. The
       underline on the second line then sits on the row divider, which is what
       the screenshot shows.

       So the fix is to give the cell real padding and let `block-size` go on
       being the minimum it already was. Single-line rows do not move: `3rem` is
       a border-box figure (box-sizing is global, css-reset.css:5), so a 24px
       line in a 48px band with 8px of padding has 32px of content box to sit in
       and the row stays 48px. A two-line row becomes 48 + 16 = 64px.

       Symmetric with the inline padding on purpose, rather than a new value.
       --space-2xs is fluid (8px -> 12px), so the breathing room scales with the
       viewport the same way the cell's sides already do, and there is no second
       number here to keep in step with the first. */
    tbody td {
      block-size: 3rem;
      padding: var(--space-2xs);
      background-color: var(--neutral-bg-component-soft);
      border-block-end: 1px solid var(--neutral-border-soft);
      vertical-align: middle;
      transition: background-color var(--motion-duration-control)
        var(--ease-out);
    }

    /* --neutral-bg-highlight, AND IT IS A DIFFERENT TOKEN FROM THE ONE THAT WAS
       HERE, read straight off Codex's own clickable-row markup, which Joy found
       in their website docs on 2026-10-25 after the Figma PARTS frame turned out
       not to document the states (the Documentation frame does -- see the
       correction above, which arrived later the same day and does not change
       this token):

         <tr class="border-t border-neutral-soft cursor-pointer
                    hover:bg-neutral-highlight" data-clickable="true">

       inside a table carrying `bg-neutral-component-soft [&>tr]:border-
       neutral-soft`. So the row rest surface and the divider colour match what
       this file already had, and the hover is `bg-neutral-highlight` --
       NOT --neutral-bg-component-soft-hover, which is what this rule used for
       its first two days.

       IN LIGHT THE TWO TOKENS ARE THE SAME COLOUR, both #e5f2f3, which is why
       nobody noticed: Joy's earlier reading ("hover styles for light mode:
       var(--neutral-bg-component-soft-hover, #E5F2F3)") named the wrong role and
       still produced the right pixel, and the light tier she signed off has not
       changed and does not change now. The tiers diverge only in dark:
       --neutral-bg-highlight is #1e2a35 where soft-hover is #2e3e4e
       (css-brand-tokens.css:945 and :944).

       AND THAT DIVERGENCE IS THE WHOLE POINT OF THE TOKEN. In dark, soft-hover
       (#2e3e4e) is EXACTLY --neutral-bg-component, the header surface (:939), so
       the old rule painted a hovered row the header's colour and the hover read
       as nothing -- which is the defect Joy reported. bg-highlight is Codex's
       answer to that: it is the step BETWEEN the row surface and the header
       surface in both tiers, and it exists precisely because the soft ramp has
       no such step to offer in dark (soft #172029 -> soft-hover #2e3e4e is one
       notch, with the header sitting on the notch). In light the row/header gap
       is two notches wide, so the same idea lands on soft-hover's value.

       SO THE DARK OVERRIDE IS GONE AND THIS IS ONE DECLARATION. It also means
       the hover is now DARKER than the header in dark (#1e2a35 against #2e3e4e)
       where in light it is lighter than the header (#e5f2f3 against #deebec).
       That inversion is not a bug and it is not avoidable: in light the header
       is darker than the rows, in dark it is lighter, so "one step from the row
       towards the header" cannot keep the same sign in both tiers. What IS
       constant is the thing that matters -- the hovered row lifts off its
       neighbours and is clearly distinct from the header.

       WHICH MEANS THIS DOES NOT LITERALLY DO WHAT WAS ASKED FOR, and that is
       deliberate. Joy, earlier the same day: "in dark mode the hover background
       color of the rows needs to be lighter than the top row." That was a
       prescription written against the broken state, where the hover WAS the
       header colour; the override built for it stepped to
       --neutral-bg-component-soft-active (#3f5467), one past the header, which
       satisfied the letter of it. Against #172029 that is a very bright slab
       across a whole row, nothing like the barely-there lift the approved light
       tier gives, and it is two notches off Codex. The verified token fixes the
       actual complaint instead. If the subtlety is wrong on preview, the
       override is four lines to restore:

         :root[data-theme='dark'] & {
           background-color: var(--neutral-bg-component-soft-active);
         }

       ONE THING CODEX DOES HERE THAT THIS TABLE DOES NOT: `cursor-pointer` and
       `data-clickable="true"` on the `<tr>`. Their hover tint belongs to a row
       that is itself the click target. Here only the subject cell holds a link
       (requests_page.hbs:126), so the whole row tints while only part of it is
       clickable -- the same affordance gap as the header cell's padding above.
       Making the row navigate to the request is the fix that would close both
       and match Codex. PARKED 2026-10-25 as item 1 of
       docs/brand-refresh/nice-to-have.md, which carries the approach and its two
       costs -- Joy: "let's leave it as a nice to have for now." Do not build it
       off this comment; read that entry, because the cheap-looking version loses
       the status badge's tooltip. */
    tbody tr:hover td {
      background-color: var(--neutral-bg-highlight);
    }

    /* The wrapper now draws the bottom edge, so the last divider would double. */
    tbody tr:last-child td {
      border-block-end: none;
    }

    /* Subject is the only column allowed to wrap; the rest stay on one line
       so ids and relative dates can't break mid-token. */
    th:first-child,
    td:first-child {
      padding-inline-start: var(--space-s);
      min-inline-size: 14rem;
    }

    th:last-child,
    td:last-child {
      padding-inline-end: var(--space-s);
    }

    td:not(:first-child) {
      white-space: nowrap;
    }

    /* The subject link. THE BRAND HOVER IS BACK, and this rule has now been
       round the full circle -- worth writing out, because the end state looks
       identical to the start and is not the same thing.

       Joy originally: "I want the links to the tickets to behave like other
       links with hover (the brand colors)." Built as a special case for this
       table. She withdrew it on 2026-10-24: "since we're applying these default
       hyperlink colors throughout, we need to get rid of the background
       highlight on link hover [...] So the only link where we'd see the brand
       colors would be the breadcrumbs." So the brand hover came out and Codex's
       underline thickening went in. Then, on 2026-10-25, after previewing that
       across the KB: "the hover states are not distinguishable enough from the
       standard text [...] I'd like to go back on my previous decision and make
       the default on link hover the same color that we are using for
       breadcrumbs."

       WHICH IS WHERE THIS STARTED, except that it is no longer a special case:
       the brand hover is what css-reset.css now gives EVERY link, so this rule
       is an application of the sitewide pattern rather than an exception to it.
       The old comment called itself "the first instance of the pattern rather
       than an application of it, and the thing to look at twice on preview."
       It got looked at three times and ended up as a plain application.

       So: --hyperlink-link at rest, --brand-text on hover, no fill. The reason
       the theme deviates from Codex here is on the `a:not([class])` rule in
       css-reset.css and is not repeated. This restates it rather than
       inheriting because the anchor carries `class="block"` of its own
       (requests_page.hbs:126), and `a:not([class])` tests the anchor's own
       class attribute -- so the sitewide rule cannot reach it no matter what
       the ancestors look like.

       `font-weight: var(--font-bold)` IS GONE, resolved 2026-10-25. It had been
       carried as a deliberate divergence -- read as the DataTable's emphasis of
       the subject column against the id and date columns beside it, rather than
       as part of the link treatment -- and flagged to be settled on preview,
       which is what happened. Joy: "Let's remove the bold from the objects in
       the subject column." So the column now inherits the table's weight, and
       Codex's hyperlink text styles (Inter 400) and this theme agree again.
       There is no weight declaration here at all now; do not add one back to
       "emphasise" the column.

       The row still responds to the pointer: `tbody tr:hover td` below tints
       the whole row, which is Codex's DataTable behaviour and a better
       affordance for a clickable row than tinting one word inside it. */
    td a {
      color: var(--hyperlink-link);
      transition: color var(--motion-duration-control) var(--ease-out);

      &:hover,
      &:active {
        color: var(--brand-text);
      }

      &:focus-visible {
        --outline-offset: 2px;
        border-radius: var(--radius-sm);
      }
    }
  }
}
