/* Proven weak, opt-in Rip City recipes. */
@layer ripcity-app {
  /* Thin native scrollbars are the app-wide default. The zero-specificity
     theme boundary changes no box's overflow or scroll ownership. Firefox
     uses the standard property; Blink and WebKit use the restrained 8px
     pseudo-element dimensions. Light-DOM scrollers are covered here, while
     closed Web Awesome shadow roots remain component-owned. */
  :where(.wa-theme-ripcity, .wa-theme-ripcity *) {
    scrollbar-width: thin;
  }

  :where(.wa-theme-ripcity)::-webkit-scrollbar,
  :where(.wa-theme-ripcity *)::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }

  /* Opt-in construction mechanics -----------------------------------------
     These weak primitives supply proven feature-independent mechanics. Most
     have multiple consumers; the pending family has one because it captures a
     coherent accessibility and request-feedback contract. Feature sheets still
     own layout, dimensions, paint, density, and state language. */

  /* Reset a native button when a feature supplies the complete visual skin.
     Disabled treatment remains explicit because appearance:none removes the
     browser's otherwise consistent treatment. */
  :where(button.ripcity-action-reset) {
    appearance: none;
    box-sizing: border-box;
    height: auto;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    color: inherit;
    font: inherit;
    text-align: inherit;
    white-space: normal;
    transform: none;
    transition: none;
    cursor: pointer;
  }

  :where(button.ripcity-action-reset:disabled) {
    color: var(--wa-color-text-quiet);
    cursor: not-allowed;
    opacity: var(--ripcity-disabled-opacity, 0.55);
  }

  /* A sortable header is one complete cell-sized native control. The cell
     contributes no competing inset; features may override only the inline
     padding token and alignment while retaining their track geometry, header
     bands, typography, and interaction transport. */
  :where(th.ripcity-sortable) {
    --ripcity-sort-padding-inline: var(--wa-space-xs);

    padding: 0;
  }

  :where(th.ripcity-sortable > button.ripcity-sort) {
    display: inline-flex;
    inline-size: 100%;
    block-size: 100%;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding-inline: var(--ripcity-sort-padding-inline);
    white-space: nowrap;
  }

  :where(button.ripcity-sort.ripcity-sort-start) {
    justify-content: flex-start;
  }

  :where(.ripcity-sort:hover:not(:disabled)) {
    color: var(--wa-color-text-normal);
  }

  :where(
    .ripcity-sortable[aria-sort]:not([aria-sort="none"]) .ripcity-sort
  ) {
    color: var(--wa-color-text-normal);
    box-shadow: inset 0 -2px 0 var(--wa-color-neutral-fill-loud);
  }

  :where(
    .ripcity-sortable[aria-sort]:not([aria-sort="none"])
      .ripcity-sort-label
  ) {
    font-weight: var(--wa-font-weight-bold);
  }

  :where(.ripcity-sort-mark) {
    flex: none;
    font-size: 10px;
    line-height: 1;
  }

  /* A semantic column family centers its label over the leaf headers it owns.
     Feature geometry may explicitly override this weak default when a family
     is wider than the visible table viewport. */
  :where(th[scope="colgroup"]) {
    text-align: center;
  }

  /* Center a fixed-width numeric reading within its table cell while aligning
     the digits to the field's inline end. Consumers provide
     --ripcity-number-width and choose the field's display mode. */
  :where(.ripcity-number-cell) {
    text-align: center;
  }

  :where(.ripcity-number-field) {
    inline-size: var(--ripcity-number-width);
    text-align: end;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  /* Compact under-number stat reading. The direct value is the only painted
     child: its padding reserves the exact 3px gap and 2px rail cadence, and
     its pseudo-elements paint the rail, fill, centered origin, and optional
     reference tick. --ripcity-stat-share is a normalized number from 0 to 1;
     --ripcity-stat-reference is a percentage. */
  :where(.ripcity-stat) {
    --ripcity-stat-track-color: var(--ripcity-neutral-measure-track);
    --ripcity-stat-fill-color: var(--ripcity-neutral-measure-fill);
    --ripcity-stat-reference-color: var(--wa-color-neutral-border-loud);
    --ripcity-stat-origin-color: var(--wa-color-neutral-border-normal);
    --ripcity-stat-reference-size: 0px;
    --ripcity-stat-origin-size: 0px;

    text-align: center;
  }

  :where(.ripcity-stat-favorable) {
    --ripcity-stat-fill-color: var(--ripcity-favorable-measure-fill);
  }

  :where(.ripcity-stat-unfavorable) {
    --ripcity-stat-fill-color: var(--ripcity-unfavorable-measure-fill);
  }

  :where(.ripcity-stat-reference) {
    --ripcity-stat-reference-size: 1px;
  }

  :where(.ripcity-stat-centered) {
    --ripcity-stat-origin-size: 1px;
  }

  :where(.ripcity-stat > .ripcity-stat-value.ripcity-number-field) {
    position: relative;
    display: block;
    box-sizing: content-box;
    inline-size: var(--ripcity-number-width, max-content);
    margin-inline: auto;
    padding-block-end: 5px;
    font-size: 13px;
    font-weight: var(--wa-font-weight-semibold);
    line-height: 1.1;
    text-align: end;
  }

  :where(.ripcity-stat > .ripcity-stat-value.ripcity-number-field)::before,
  :where(.ripcity-stat > .ripcity-stat-value.ripcity-number-field)::after {
    content: "";
    position: absolute;
    pointer-events: none;
  }

  /* The rail and optional centered origin share one fixed layer. */
  :where(.ripcity-stat > .ripcity-stat-value.ripcity-number-field)::before {
    inset-block-end: -1px;
    inset-inline-start: 50%;
    inline-size: var(--ripcity-stat-rail, 44px);
    block-size: 4px;
    translate: -50% 0;
    background-image:
      linear-gradient(
        var(--ripcity-stat-origin-color),
        var(--ripcity-stat-origin-color)
      ),
      linear-gradient(
        var(--ripcity-stat-track-color),
        var(--ripcity-stat-track-color)
      );
    background-position: center, center;
    background-repeat: no-repeat;
    background-size: var(--ripcity-stat-origin-size) 4px, 100% 2px;
  }

  /* A zero-origin fill and optional paired reference tick share the top layer,
     keeping the tick visible when it crosses the fill. */
  :where(.ripcity-stat > .ripcity-stat-value.ripcity-number-field)::after {
    inset-block-end: -1px;
    inset-inline-start: 50%;
    inline-size: var(--ripcity-stat-rail, 44px);
    block-size: 4px;
    translate: -50% 0;
    background-image:
      linear-gradient(
        var(--ripcity-stat-reference-color),
        var(--ripcity-stat-reference-color)
      ),
      linear-gradient(
        var(--ripcity-stat-fill-color),
        var(--ripcity-stat-fill-color)
      );
    background-position: var(--ripcity-stat-reference, 0%) center, left center;
    background-repeat: no-repeat;
    background-size:
      var(--ripcity-stat-reference-size) 4px,
      calc(clamp(0, var(--ripcity-stat-share, 0), 1) * 100%) 2px;
  }

  :where(
    .ripcity-stat-centered > .ripcity-stat-value.ripcity-number-field
  )::after {
    content: none;
  }

  /* Centered fills are real rectangles anchored to the origin instead of a
     background-position calculation, so start and end remain unambiguous. */
  :where(
    .ripcity-stat-centered.ripcity-stat-start
      > .ripcity-stat-value.ripcity-number-field
  )::after,
  :where(
    .ripcity-stat-centered.ripcity-stat-end
      > .ripcity-stat-value.ripcity-number-field
  )::after {
    content: "";
    inset-block-end: 0;
    inset-inline: auto;
    inline-size: max(
      2px,
      calc(
        var(--ripcity-stat-rail, 44px) *
          clamp(0, var(--ripcity-stat-share, 0), 1) / 2
      )
    );
    block-size: 2px;
    translate: none;
    border-radius: var(--wa-border-radius-pill);
    background: var(--ripcity-stat-fill-color);
  }

  :where(
    .ripcity-stat-centered.ripcity-stat-start
      > .ripcity-stat-value.ripcity-number-field
  )::after {
    inset-inline-end: 50%;
  }

  :where(
    .ripcity-stat-centered.ripcity-stat-end
      > .ripcity-stat-value.ripcity-number-field
  )::after {
    inset-inline-start: 50%;
  }

  :where(.ripcity-stat-missing > .ripcity-stat-value.ripcity-number-field) {
    color: var(--ripcity-color-text-faint);
    font-weight: var(--wa-font-weight-normal);
  }

  :where(
    :is(.ripcity-stat-missing, .ripcity-stat-unscaled)
      > .ripcity-stat-value.ripcity-number-field
  )::before,
  :where(
    :is(.ripcity-stat-missing, .ripcity-stat-unscaled)
      > .ripcity-stat-value.ripcity-number-field
  )::after {
    content: none;
  }

  /* Inline comparison measure: one grid row pairing a nested track with the
     exact value it summarizes. This is the sole remaining contract for the
     ripcity-measure-* classes; they do not paint under-number readings. */
  :where(.ripcity-inline-measure) {
    --ripcity-measure-fill-color: var(--ripcity-comparison-measure-fill);

    display: grid;
    grid-template-columns:
      minmax(0, 1fr)
      var(--ripcity-inline-measure-value-width, 3.5rem);
    align-items: center;
    column-gap: var(--ripcity-inline-measure-gap, 0.625rem);
    inline-size: 100%;
  }

  :where(.ripcity-inline-measure > .ripcity-measure-track) {
    position: relative;
    box-sizing: border-box;
    inline-size: 100%;
    block-size: var(--ripcity-inline-measure-height, 4px);
    overflow: hidden;
    border-radius: var(--wa-border-radius-pill);
    background: var(--ripcity-measure-track-color, var(--wa-color-surface-lowered));
    box-shadow: inset 0 0 0 var(--wa-border-width-s) var(--wa-color-surface-border);
  }

  :where(
    .ripcity-inline-measure > .ripcity-measure-track > .ripcity-measure-fill
  ) {
    display: block;
    inline-size: clamp(0%, var(--ripcity-measure, 0%), 100%);
    block-size: 100%;
    border-radius: inherit;
    background: var(--ripcity-measure-fill-color);
  }

  /* Exact-value mechanics only; features own the value's semantic markup. */
  :where(.ripcity-inline-measure-value) {
    text-align: end;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  /* Expand any interactive element to its containing box without choosing its
     display mode or content alignment. The container must provide definite
     inline and block sizes. */
  :where(.ripcity-hit-area) {
    inline-size: 100%;
    block-size: 100%;
  }

  /* Carry shrinkability and clipping through a finite Grid/Flex region. This
     does not establish a height; the owning instrument must supply that bound. */
  :where(.shrink-region) {
    min-inline-size: 0;
    min-block-size: 0;
    overflow: hidden;
  }

  /* Fill an already bounded instrument region without establishing its bound. */
  :where(.region-fill) {
    box-sizing: border-box;
    inline-size: 100%;
    block-size: 100%;
  }

  /* A command band supplies only the shared one-row surface. Features retain
     track placement, finite height, stacking, and local gaps. */
  :where(.command-bar) {
    min-block-size: 0;
    display: flex;
    align-items: center;
    padding-inline: var(--wa-space-m);
    border-block-end: var(--wa-border-width-s) solid var(--wa-color-surface-border);
    background: var(--wa-color-surface-default);
  }

  :where(.command-bar[aria-busy="true"]) {
    cursor: progress;
  }

  /* A top-level finite command band may opt into Web Awesome Scroller as its
     sole horizontal overflow owner. The semantic header retains the band
     surface, height, and state; the component supplies the visible scrollbar
     and dynamic edge shadows at the available-width boundary. */
  :where(wa-scroller.ripcity-command-scroller) {
    --shadow-color: var(--wa-color-surface-default);
    --shadow-size: var(--wa-space-xl);

    min-inline-size: 0;
    inline-size: 100%;
    max-inline-size: 100%;
  }

  /* Keep the shared gutter on the intrinsic command row when this literal
     anatomy opts in, so Scroller's shadows meet the command-band edges. The
     default band keeps its original padding when no direct scroller exists. */
  :where(.command-bar:has(> wa-scroller.ripcity-command-scroller)) {
    padding-inline: 0;
  }

  :where(
    .command-bar
      > wa-scroller.ripcity-command-scroller
      > .ripcity-command-controls
  ) {
    padding-inline: var(--wa-space-m);
  }

  :where(wa-scroller.ripcity-command-scroller)::part(content) {
    overscroll-behavior-inline: contain;
  }

  :where(.ripcity-command-popup-escape):has(wa-select[open], wa-date-input[open]) {
    overflow: visible;
  }

  :where(.ripcity-command-controls) {
    display: flex;
    flex: none;
    align-items: end;
    gap: var(--wa-space-s);
    inline-size: max-content;
    min-inline-size: max-content;
    margin: 0;
  }

  :where(.ripcity-command-control) {
    display: block;
    flex: none;
    min-inline-size: 0;
  }

  :where(.ripcity-command-control)::part(form-control-label) {
    margin-block-end: 2px;
    color: var(--wa-color-text-quiet);
    font-size: 10px;
    font-weight: var(--wa-font-weight-semibold);
    letter-spacing: 0.06em;
    line-height: 1.1;
    text-transform: uppercase;
  }

  /* Error regions share only their inner composition. Features retain the
     region's geometry, scrolling, state, semantics, and recovery behavior. */
  :where(.ripcity-error-region) {
    display: grid;
    align-content: start;
    justify-items: start;
    gap: var(--wa-space-m);
    padding: var(--wa-space-l) var(--wa-space-m);
  }

  :where(.ripcity-error-callout) {
    max-width: 46rem;
  }

  :where(.ripcity-error-retry)::part(base) {
    white-space: nowrap;
  }

  /* Pending regions retain committed content in place. The content class may
     be used without an overlay; when present, the overlay is non-blocking and
     fills the region by default. The active ripcity-pending-replace modifier
     hides stale content and pairs with one ripcity-pending-status. The static
     fallback remains in the inventory but is not replacement state. Features
     provide status text/markup and may override the inset, stack level, fade,
     or duration at the region boundary. */
  :where(.ripcity-pending-region) {
    --ripcity-pending-content-opacity: 0.6;
    --ripcity-pending-overlay-inset: 0;
    --ripcity-pending-overlay-z-index: 1;
    --ripcity-pending-transition-duration: var(--wa-transition-normal);
    --ripcity-pending-spinner-size: 28px;
    --ripcity-pending-spinner-track-width: 3px;

    position: relative;
  }

  :where(.ripcity-pending-content),
  :where(.ripcity-pending-overlay) {
    transition: opacity
      var(--ripcity-pending-transition-duration, var(--wa-transition-normal)) linear;
  }

  :where(.ripcity-pending-overlay) {
    position: absolute;
    inset: var(--ripcity-pending-overlay-inset, 0);
    z-index: var(--ripcity-pending-overlay-z-index, 1);
    display: grid;
    place-items: center;
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
  }

  :where(.ripcity-pending-region[aria-busy="true"]) {
    cursor: progress;
  }

  :where(.ripcity-pending-region[aria-busy="true"] > .ripcity-pending-content) {
    opacity: var(--ripcity-pending-content-opacity, 0.6);
  }

  :where(
    .ripcity-pending-region.ripcity-pending-replace[aria-busy="true"]
      > .ripcity-pending-content
  ) {
    visibility: hidden;
    opacity: 0;
  }

  :where(.ripcity-pending-region[aria-busy="true"] > .ripcity-pending-overlay) {
    visibility: visible;
    opacity: 1;
  }

  :where(.ripcity-pending-spinner) {
    font-size: var(--ripcity-pending-spinner-size, 28px);
    --indicator-color: var(--wa-color-neutral-fill-loud);
    --track-color: color-mix(
      in oklab,
      var(--wa-color-neutral-border-normal) 42%,
      transparent
    );
    --track-width: var(--ripcity-pending-spinner-track-width, 3px);
  }

  :where(.ripcity-pending-static) {
    display: none;
    color: var(--wa-color-text-normal);
    font-size: var(--wa-font-size-s);
    font-weight: var(--wa-font-weight-semibold);
  }

  /* Replacement pending state has one exposed status without adding visible
     geometry to feature-owned Grid/Flex regions. */
  :where(.ripcity-pending-status) {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* Explicit axis owners contain scroll chaining. The two-axis form keeps a
     synchronized board's axes together without owning dimensions, sticky
     behavior, positioning, isolation, or restoration. */
  :where(.horizontal-scroll) {
    min-inline-size: 0;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-inline: contain;
  }

  :where(.vertical-scroll) {
    min-block-size: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior-block: contain;
  }

  :where(.two-axis-scroll) {
    min-inline-size: 0;
    min-block-size: 0;
    overflow: auto;
    overscroll-behavior: contain;
  }

  /* A compact flush Drawer removes its outer spacing while retaining a ruled,
     compact header. Features own the body's scroll behavior. */
  :where(.ripcity-drawer-compact-flush) {
    --spacing: 0;
  }

  :where(.ripcity-drawer-compact-flush)::part(header) {
    border-bottom: var(--wa-border-width-s) solid var(--wa-color-surface-border);
  }

  :where(.ripcity-drawer-compact-flush)::part(title) {
    font-size: var(--wa-font-size-s);
    font-weight: var(--wa-font-weight-semibold);
  }

  :where(.ripcity-drawer-compact-flush)::part(body) {
    padding: 0;
  }

  /* Sticky matrix layer invariant after positive scrolling: ordinary cells <
     frozen inline-axis cells < block-axis headers < dual-axis intersections.
     Every sticky surface must be opaque. Sticky offsets and layers stay
     feature-owned because track counts and stacked header bands differ.
     Explicitly target each intersection: an unrelated header-row selector can
     win the cascade by specificity and silently leave the corner below the
     scrolling headers even when a later class declares a larger z-index.
     Verify paint ownership by hit-testing after positive scrolling on each
     participating axis; position and bounding boxes alone cannot prove it. */

  /* A dense-board scroll primitive supplies the local containing block and
     stacking context while each instrument retains its measured tracks,
     placement, template, band height, sticky offset, layers, and dimensions. */
  :where(.table-frame) {
    position: relative;
    isolation: isolate;
  }

  :where(table.ripcity-semantic-table) {
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 0;
    font-variant-numeric: tabular-nums;
  }

  /* Stacked sticky-header warning: with separate table borders, this bottom
     rule can participate in the first header row's used block size. A second
     sticky row must start at that rendered border-box edge, not automatically
     at the first band's nominal height. Some tables with explicit <tr> sizing
     already absorb the rule, so keep the offset calculation feature-owned and
     verify rowspan and leaf bottoms after positive vertical scrolling. */
  :where(.ripcity-semantic-table th, .ripcity-semantic-table td) {
    border-bottom: var(--wa-border-width-s) solid var(--wa-color-surface-border);
    background: var(--wa-color-surface-default);
    vertical-align: middle;
    overflow: hidden;
  }

  :where(
    .ripcity-semantic-table th:not(.ripcity-sortable),
    .ripcity-semantic-table td
  ) {
    padding: 0 var(--wa-space-xs);
  }

  :where(.ripcity-semantic-table-head th) {
    color: var(--wa-color-text-quiet);
    background: var(--wa-color-surface-lowered);
    font-weight: var(--wa-font-weight-semibold);
    white-space: nowrap;
  }

  :where(.ripcity-semantic-table-columns > th) {
    font-size: 10px;
    letter-spacing: 0.03em;
    line-height: 1.2;
    text-align: center;
  }

  :where(.ripcity-semantic-table-scopes > th[rowspan]) {
    font-size: 10px;
    letter-spacing: 0.03em;
  }

  :where(.ripcity-semantic-table th[scope="colgroup"]) {
    font-size: 9px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }

  :where(.ripcity-selectable-row:not(.is-selected):hover > th),
  :where(.ripcity-selectable-row:not(.is-selected):hover > td) {
    background: var(--ripcity-row-hover-background);
  }

  :where(.ripcity-selectable-row.is-selected > th),
  :where(.ripcity-selectable-row.is-selected > td) {
    background: var(--ripcity-row-selected-background);
  }

  :where(.ripcity-semantic-empty-row > td) {
    padding: var(--wa-space-xl) var(--wa-space-m);
    color: var(--wa-color-text-quiet);
    font-size: var(--wa-font-size-s);
    line-height: 1.5;
    text-align: left;
  }

  :where(.ripcity-board-number-field) {
    display: block;
    margin-inline: auto;
    font-weight: var(--wa-font-weight-semibold);
  }

  :where(
    .ripcity-stat-missing
      > .ripcity-stat-value.ripcity-board-number-field
  ) {
    font-weight: var(--wa-font-weight-normal);
  }

  :where(.ripcity-context-head) {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--wa-space-s);
    padding-inline: var(--wa-space-m);
    border-bottom: var(--wa-border-width-s) solid var(--wa-color-surface-border);
  }

  :where(.ripcity-context-close)::part(base) {
    color: var(--wa-color-text-normal);
  }

  :where(.ripcity-context-identity) {
    min-width: 0;
    flex: 1 1 auto;
    display: grid;
    align-items: center;
    gap: var(--wa-space-s);
  }

  :where(.ripcity-context-copy) {
    min-width: 0;
  }

  :where(.ripcity-context-scroll) {
    padding: 0 var(--wa-space-m) var(--wa-space-l);
    display: grid;
    align-content: start;
    gap: var(--wa-space-m);
  }

  /* Typography only: section geometry, rules, surfaces, and sticky behavior
     remain with each of the eight exact consumers. */
  :where(.ripcity-compact-heading) {
    font-size: var(--wa-font-size-2xs);
    font-weight: var(--wa-font-weight-bold);
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

  :where(.ripcity-detail-heading) {
    margin: 0 0 var(--wa-space-2xs);
    padding-block: var(--wa-space-s) 4px;
    border-bottom: var(--wa-border-width-s) solid var(--wa-color-surface-border);
    background: var(--wa-color-surface-default);
  }

  :where(.ripcity-detail-heading-note) {
    color: var(--wa-color-text-quiet);
    font-weight: var(--wa-font-weight-normal);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
    text-transform: none;
  }

  :where(.ripcity-kv-list) {
    margin: 0;
    font-variant-numeric: tabular-nums;
  }

  :where(.ripcity-kv-row) {
    display: grid;
    align-items: baseline;
    column-gap: var(--wa-space-s);
    padding-block: 2px;
    border-bottom: var(--wa-border-width-s) solid var(--wa-color-surface-border);
  }

  :where(.ripcity-kv-row:last-child) {
    border-bottom: 0;
  }

  :where(.ripcity-kv-term) {
    min-width: 0;
    overflow: hidden;
    color: var(--wa-color-text-quiet);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  :where(.ripcity-kv-value) {
    margin: 0;
    text-align: right;
  }

  /* Current-team marks share only unframed Web Awesome Avatar paint. Their
     dimensions, placement, labels, image sources, and states remain local. */
  :where(wa-avatar.ripcity-compact-team-mark) {
    overflow: hidden;
    border: 0;
    border-radius: 0;
    background: transparent;
  }

  :where(wa-avatar.ripcity-compact-team-mark)::part(image) {
    object-fit: contain;
  }

  :where(wa-avatar.ripcity-compact-team-mark)::part(initials) {
    font-family: inherit;
    font-size: 10px;
    font-weight: var(--wa-font-weight-bold);
  }

  /* Compact current-team tricodes share one truncating text treatment. */
  :where(.ripcity-compact-team-code) {
    min-inline-size: 0;
    overflow: hidden;
    color: var(--wa-color-text-normal);
    font-size: 11px;
    font-weight: var(--wa-font-weight-semibold);
    letter-spacing: 0.06em;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Compact player identities share one exact portrait frame and truncating
     rhythm in dense rows or contextual identity. Consumers retain avatar size,
     layout, hit area, selection, responsive type overrides, and adjacent marks. */
  :where(wa-avatar.ripcity-compact-player-avatar) {
    display: block;
    overflow: hidden;
    border: var(--wa-border-width-s) solid var(--wa-color-surface-border);
    background: var(--wa-color-surface-lowered);
  }

  :where(wa-avatar.ripcity-compact-player-avatar)::part(image) {
    object-fit: cover;
    object-position: 50% 6%;
  }

  :where(wa-avatar.ripcity-compact-player-avatar)::part(initials) {
    font-family: inherit;
    font-size: 10px;
    font-weight: var(--wa-font-weight-bold);
  }

  :where(.ripcity-compact-player-copy) {
    min-width: 0;
    display: block;
  }

  :where(.ripcity-compact-player-name) {
    display: block;
    min-width: 0;
    overflow: hidden;
    color: var(--wa-color-text-normal);
    font-size: 13px;
    font-weight: var(--wa-font-weight-semibold);
    line-height: 1.2;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  :where(.ripcity-compact-player-meta) {
    display: block;
    min-width: 0;
    overflow: hidden;
    color: var(--wa-color-text-quiet);
    font-size: 10px;
    letter-spacing: 0.03em;
    line-height: 1.3;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Compact identity names share one truncating masthead rhythm. */
  :where(.ripcity-compact-identity-name) {
    margin: 0;
    overflow: hidden;
    font-size: 16px;
    font-weight: var(--wa-font-weight-semibold);
    line-height: 1.2;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* The three exact compact metadata consumers also share tabular truncation. */
  :where(.ripcity-compact-identity-meta) {
    margin: 2px 0 0;
    overflow: hidden;
    color: var(--wa-color-text-quiet);
    font-size: var(--wa-font-size-2xs);
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  @media (forced-colors: active) {
    :where(button.ripcity-action-reset:disabled) {
      color: GrayText;
      opacity: 1;
    }

    :where(
      .ripcity-sortable[aria-sort]:not([aria-sort="none"]) .ripcity-sort
    ) {
      border-block-end: 2px solid currentColor;
      box-shadow: none;
    }

    :where(.ripcity-pending-region[aria-busy="true"]) {
      outline: 1px dashed CanvasText;
      outline-offset: -1px;
    }

    :where(.ripcity-pending-region[aria-busy="true"] > .ripcity-pending-content) {
      opacity: 1;
    }

    :where(.ripcity-pending-overlay) {
      color: CanvasText;
      background: Canvas;
    }

    /* Stat marks retain distinct rail, fill, origin, and reference paint. */
    :where(.ripcity-stat) {
      --ripcity-stat-track-color: GrayText;
      --ripcity-stat-fill-color: Highlight;
      --ripcity-stat-reference-color: GrayText;
      --ripcity-stat-origin-color: CanvasText;
    }

    :where(.ripcity-stat > .ripcity-stat-value.ripcity-number-field)::before,
    :where(.ripcity-stat > .ripcity-stat-value.ripcity-number-field)::after {
      forced-color-adjust: none;
    }

    :where(.ripcity-inline-measure > .ripcity-measure-track) {
      border: 1px solid CanvasText;
      background: Canvas;
      box-shadow: none;
    }

    /* Forced colors can flatten gradient cues into opaque blocks. Scrolling
       and its visible scrollbar remain active when only the cue size is zero. */
    :where(wa-scroller.ripcity-command-scroller) {
      --shadow-size: 0;
    }

    :where(
      .ripcity-inline-measure > .ripcity-measure-track > .ripcity-measure-fill
    ) {
      background: CanvasText;
    }
  }

  /* Authored About content keeps feature-specific sections and typography. */
  :where(.ripcity-about-content) {
    display: grid;
    color: var(--wa-color-text-normal);
    line-height: var(--wa-line-height-normal);
    user-select: text;
    -webkit-user-select: text;
  }

  /* Complete prose defaults for authored explanatory sections and definition
     lists. Features opt in only when this entire reading rhythm applies. */
  :where(.ripcity-about-prose) {
    gap: var(--wa-space-l);
  }

  :where(.ripcity-about-prose section) {
    display: grid;
    gap: var(--wa-space-xs);
  }

  :where(.ripcity-about-prose h2, .ripcity-about-prose p, .ripcity-about-prose dl) {
    margin: 0;
  }

  :where(.ripcity-about-prose h2) {
    font-size: var(--wa-font-size-m);
    font-weight: var(--wa-font-weight-bold);
  }

  :where(.ripcity-about-prose dl) {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: var(--wa-space-xs) var(--wa-space-m);
  }

  :where(.ripcity-about-prose dt) {
    font-weight: var(--wa-font-weight-bold);
  }

  :where(.ripcity-about-prose dd) {
    margin: 0;
    color: var(--wa-color-text-quiet);
  }

  :where(.ripcity-about-limit) {
    color: var(--wa-color-text-quiet);
  }
}
