/* Account, auth, collection, and imported-game surfaces. */

.account-nav {
  /* Absolute (not fixed): sits at the top of the page and scrolls away with
     content instead of staying pinned. The base flex form supports constrained
     desktop widths; the desktop reference rule below restores the independent
     right anchor used by the Apps + Donate launch. */
  position: relative;
  flex: 0 0 auto;
  min-width: 0;
  max-width: 100%;
  z-index: 1001;
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px;
  font-family: 'Share Tech Mono', monospace;
}
.account-nav a,
.account-nav button {
  min-height: 32px;
  display: inline-grid;
  place-items: center;
  padding: 0 12px;
  border: 1px solid rgba(var(--tint-rgb), 0.3);
  background: rgba(var(--void-rgb), 0.78);
  color: var(--chrome);
  font: inherit;
  font-size: 0.72rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
}
.account-nav a:hover,
.account-nav button:hover {
  color: var(--white);
  border-color: var(--cyan);
  box-shadow: 0 0 16px rgba(var(--tint-rgb), 0.18);
}
.account-nav form {
  margin: 0;
}

/* ── PERSISTENT GLOBAL SEARCH ── */
.global-search {
  --global-search-inline-width: 260px;
  --global-search-trigger-width: 34px;
  --global-search-trigger-height: 32px;
  position: relative;
  flex: 0 1 auto;
  min-width: 34px;
  max-width: 260px;
  width: 34px;
  transition: width 160ms ease;
}
.global-search.is-open {
  width: var(--global-search-fit-width, var(--global-search-inline-width));
}
.global-search-form {
  width: 100%;
  min-height: 32px;
  display: flex;
  align-items: center;
  overflow: hidden;
  border: 0;
  border-bottom: 1px solid transparent;
  background: transparent;
  color: var(--muted);
  transition: border-color 160ms ease, background 160ms ease;
}
.global-search.is-open .global-search-form {
  border-bottom-color: rgba(var(--tint-rgb), 0.42);
  background: rgba(var(--void-rgb), 0.32);
}
.global-search.is-open .global-search-form:focus-within {
  border-bottom-color: var(--cyan);
}
.account-nav .global-search-trigger,
.account-nav .global-search-source {
  min-height: 32px;
  border: 0;
  background: transparent;
  box-shadow: none;
  text-transform: none;
}
.account-nav .global-search-trigger {
  width: 34px;
  min-width: 34px;
  padding: 0;
}
.account-nav .global-search-trigger:hover,
.account-nav .global-search-trigger:focus-visible,
.account-nav .global-search-source:hover,
.account-nav .global-search-source:focus-visible {
  border: 0;
  background: transparent;
  box-shadow: none;
  outline: none;
}
.global-search.is-open .global-search-trigger {
  color: var(--cyan);
}
.global-search-trigger svg,
.global-search-form svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.global-search-form input[type="search"] {
  width: 0;
  max-width: 0;
  min-width: 0;
  min-height: 30px;
  padding: 0;
  opacity: 0;
  pointer-events: none;
  border: 0;
  background: transparent;
  color: var(--white);
  box-shadow: none;
  outline: none;
  font: inherit;
  font-size: 0.84rem;
  letter-spacing: 0;
  transition: max-width 160ms ease, opacity 120ms ease, padding 160ms ease;
}
.global-search.is-open .global-search-form input[type="search"] {
  width: auto;
  max-width: 146px;
  flex: 1 1 auto;
  padding: 0 6px;
  opacity: 1;
  pointer-events: auto;
}
.global-search-form input[type="search"]:focus {
  border: 0;
  box-shadow: none;
  outline: none;
}
.account-nav .global-search-source {
  width: 0;
  max-width: 0;
  min-width: 0;
  padding: 0;
  overflow: hidden;
  opacity: 0;
  color: var(--muted);
  font-size: 0.66rem;
  letter-spacing: 0.2px;
  white-space: nowrap;
  pointer-events: none;
  transition: width 160ms ease, max-width 160ms ease, opacity 120ms ease;
}
.account-nav .global-search.is-open .global-search-source {
  width: 72px;
  max-width: 72px;
  min-width: 0;
  flex: 0 1 72px;
  opacity: 1;
  pointer-events: auto;
}
.global-search-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 1100;
  width: min(340px, calc(100vw - 32px));
  max-height: min(480px, calc(100dvh - 72px));
  padding: 4px 6px 6px;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--border);
  border-radius: var(--radius-control, 4px);
  background: rgba(var(--ink-rgb), 0.985);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.5);
  box-sizing: border-box;
}
.global-search-status {
  min-height: 0;
  margin: 0;
  padding: 5px 5px 3px;
  font-size: 0.68rem;
}
.global-search-status:empty {
  display: none;
}
.global-search-results {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.global-search-section {
  min-width: 0;
}
.account-nav .global-search-section-title.section-title {
  margin: 0;
  padding: 6px 5px 4px;
  display: flex;
  align-items: baseline;
  gap: 6px;
  color: var(--muted);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.7px;
  text-transform: uppercase;
}
.account-nav .global-search-section-title.section-title::before,
.account-nav .global-search-section-title.section-title::after {
  display: none;
}
.account-nav .global-search-result {
  width: 100%;
  min-height: 0;
  padding: 6px 6px;
  display: grid;
  place-items: initial;
  gap: 3px;
  border: 0;
  border-top: 1px solid var(--border);
  border-radius: 0;
  background: transparent;
  color: inherit;
  box-shadow: none;
  font: inherit;
  font-size: 0.78rem;
  letter-spacing: 0;
  text-align: left;
  text-transform: none;
  box-sizing: border-box;
}
.account-nav .global-search-result:hover,
.account-nav .global-search-result:focus-visible {
  border-color: var(--border);
  background: rgba(var(--tint-rgb), 0.08);
  color: inherit;
  box-shadow: inset 3px 0 0 var(--cyan);
  outline: none;
}
.account-nav .global-search-player {
  grid-template-columns: 32px minmax(0, 1fr);
  align-items: center;
  gap: 7px;
}
.global-search-portrait {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  overflow: hidden;
}
.global-search-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.global-search-monogram {
  width: 18px;
  height: 18px;
}
.global-search-result-copy {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.global-search-game-headline {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.global-search-result .pairing {
  min-width: 0;
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 5px;
}
.global-search-result-meta {
  display: block;
  overflow-wrap: anywhere;
  font-size: 0.68rem;
  line-height: 1.3;
}
.global-search-memberships {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-top: 2px;
}
.global-search-membership {
  max-width: 100%;
  padding: 1px 6px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(var(--gold-rgb), 0.08);
  color: var(--muted);
  font-size: 0.62rem;
  line-height: 1.35;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.account-nav .global-search-more {
  min-height: 32px;
  margin: 4px 4px 0;
  padding: 0;
  display: inline-flex;
  place-items: initial;
  align-items: center;
  justify-content: flex-start;
  border: 0;
  background: transparent;
  box-shadow: none;
  font-size: 0.82rem;
  letter-spacing: 0;
  text-transform: none;
}
.global-search-empty {
  margin: 9px 5px;
  font-size: 0.74rem;
}

body.site-theme-charcoal .account-nav .global-search-result .entity-kind {
  font-size: 0.58rem;
  letter-spacing: 1px;
}
body.site-theme-charcoal .account-nav .global-search-result .entity-name.is-lead,
body.site-theme-charcoal .account-nav .global-search-result .pairing.is-lead .entity-name {
  font-size: 0.9rem;
  line-height: 1.2;
}
body.site-theme-charcoal .account-nav .global-search-result .result-chip {
  font-size: 0.68rem;
}

/* ── NOTIFICATION BELL + INBOX FLYOUT ── */
.notification-menu {
  position: relative;
}
.account-nav .notification-menu-trigger {
  position: relative;
  width: 38px;
  min-width: 38px;
  padding: 0;
}
.notification-menu-trigger svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.notification-badge {
  position: absolute;
  top: -7px;
  right: -7px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  display: inline-grid;
  place-items: center;
  border: 1px solid rgba(0, 0, 0, 0.35);
  border-radius: 10px;
  background: var(--amber);
  color: var(--void);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0;
  box-sizing: border-box;
}
.notification-badge[hidden] {
  display: none;
}
/* Menus attached to a trigger sit flush against it. A 6px gap reads as a
   detached slab, and the pointer has to cross it to reach the menu it opened
   (owner, 2026-08-05: "there is a gap between the nav and the drop down").
   Floating panels that are not menus — the collection create form, the search
   help disclosure — keep their offset, because they are not anchored lists. */
.notification-menu-panel {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 1003;
  width: min(390px, calc(100vw - 32px));
  border: 1px solid rgba(var(--tint-rgb), 0.56);
  background: hsl(200 60% 12%);
  box-shadow:
    0 22px 54px rgba(0, 0, 0, 0.76),
    0 0 0 1px rgba(0, 0, 0, 0.72),
    0 0 30px rgba(var(--tint-rgb), 0.12);
}
.notification-menu-panel[hidden] {
  display: none;
}
.notification-menu-toolbar {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  height: 34px;
  padding: 1px 3px 0;
  border-bottom: 1px solid rgba(var(--tint-rgb), 0.2);
}
.account-nav .notification-menu-settings {
  width: 30px;
  min-width: 30px;
  min-height: 30px;
  padding: 0;
  border-color: transparent;
  background: transparent;
}
.notification-menu-settings svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.account-nav .notification-menu-settings:hover,
.account-nav .notification-menu-settings:focus-visible {
  border-color: rgba(var(--tint-rgb), 0.46);
  background: rgba(var(--tint-rgb), 0.08);
  box-shadow: none;
}
.account-nav .notification-menu-all {
  min-height: 0;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}
.notification-menu-list {
  max-height: min(480px, calc(100vh - 180px));
  overflow-y: auto;
}
.notification-menu-entry {
  position: relative;
  border-bottom: 1px solid rgba(var(--tint-rgb), 0.13);
  background: transparent;
}
.notification-menu-entry:last-child {
  border-bottom: 0;
}
.account-nav .notification-menu-item {
  min-height: 0;
  display: grid;
  place-items: initial;
  gap: 4px;
  padding: 12px 48px 12px 14px;
  border: 0;
  background: transparent;
  color: var(--white);
  text-transform: none;
  letter-spacing: 0.5px;
}
.account-nav .notification-menu-item:hover,
.account-nav .notification-menu-item:focus-visible {
  border-color: transparent;
  background: hsl(200 60% 15%);
  box-shadow: none;
}
.account-nav .notification-menu-item.is-unread {
  border-left: 4px solid var(--amber);
  background: linear-gradient(90deg, rgba(var(--amber-rgb), 0.17), transparent 78%);
}
.account-nav .notification-menu-item.is-unread strong {
  color: var(--white);
}
.account-nav .notification-menu-item.is-unread .notification-menu-body {
  color: var(--muted);
}
.account-nav .notification-menu-dismiss {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  width: 34px;
  min-width: 34px;
  min-height: 34px;
  padding: 0;
  border: 1px solid transparent;
  background: transparent;
  color: rgba(var(--white-rgb), 0.58);
  font-family: Arial, sans-serif;
  font-size: 1.15rem;
  line-height: 1;
  letter-spacing: 0;
}
.account-nav .notification-menu-dismiss svg {
  width: 16px;
  height: 16px;
}
.account-nav .notification-menu-dismiss:hover,
.account-nav .notification-menu-dismiss:focus-visible {
  border-color: rgba(var(--tint-rgb), 0.54);
  background: rgba(var(--tint-rgb), 0.09);
  color: var(--cyan);
  box-shadow: none;
}
.account-nav .notification-menu-dismiss:disabled {
  cursor: wait;
  opacity: 0.45;
}
.notification-menu-topic {
  color: var(--chrome);
  font-size: 0.62rem;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}
.notification-menu-item strong {
  font-size: 0.82rem;
}
.notification-menu-body {
  color: rgba(205, 220, 230, 0.66);
  font-size: 0.72rem;
  line-height: 1.35;
}
.notification-menu-loading,
.notification-menu-empty {
  margin: 0;
  padding: 22px 14px;
  color: var(--muted);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.75rem;
  text-align: center;
}
.account-nav .notification-menu-all {
  display: block;
  padding: 12px 14px;
  border-top: 1px solid rgba(var(--tint-rgb), 0.2);
  background: transparent;
  text-align: center;
}
.account-nav .notification-menu-all:hover,
.account-nav .notification-menu-all:focus-visible {
  background: rgba(var(--tint-rgb), 0.08);
}

/* ── ACCOUNT DROPDOWN MENU ── */
.account-menu {
  position: relative;
}
.account-nav .account-menu-trigger {
  min-width: 0;
  display: inline-flex;
  align-items: center;
  text-transform: none;
  gap: 8px;
}
.account-menu-name {
  /* Django permits 150-character usernames, but site chrome must have a
     deterministic footprint. Keep ordinary names unchanged, cap the visible
     chip at 10rem, and expose the complete autoescaped value through both the
     accessible button name and the template-provided title. */
  display: block;
  min-width: 0;
  max-width: 10rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Match the account/search anchor from the Apps + Donate launch. The shared
   wrapper supplies the viewport inset; this bar keeps its own right edge
   instead of stretching the primary-nav flex item across the intervening air. */
@media (min-width: 1280px) {
  html[data-device="desktop"] .account-nav {
    position: absolute;
    top: 0;
    right: 0;
    left: auto;
    flex: none;
    min-width: auto;
    max-width: none;
  }
}

/* The compact desktop rhythm also tightens only the bounded username's visible
   share. Its full autoescaped value remains the button's accessible text and
   title, while user input can never consume the search/nav gutter. */
body.header-nav-compact .account-menu-name {
  max-width: 6rem;
}

/* The desktop controller selects this mode from the actual Donate-to-search
   clearance, not a viewport proxy. Keep the trigger in the reference row and
   attach the field to that trigger's right edge; the account chip must never
   become the field's alignment anchor. */
html[data-device="desktop"] .global-search.opens-below,
html[data-device="desktop"] .global-search.opens-below.is-open {
  position: static;
  width: var(--global-search-trigger-width);
  min-width: var(--global-search-trigger-width);
  max-width: var(--global-search-trigger-width);
  flex: 0 0 var(--global-search-trigger-width);
}
html[data-device="desktop"] .global-search.opens-below.is-open .global-search-form {
  overflow: visible;
  border-bottom-color: transparent;
  background: transparent;
}
html[data-device="desktop"] .global-search.opens-below.is-open .global-search-form input[type="search"],
html[data-device="desktop"] .account-nav .global-search.opens-below.is-open .global-search-source {
  position: absolute;
  top: var(--global-search-trigger-height);
  z-index: 1101;
  min-height: 32px;
  border: 1px solid rgba(var(--tint-rgb), 0.42);
  background: rgba(var(--ink-rgb), 0.985);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.34);
}
html[data-device="desktop"] .global-search.opens-below.is-open .global-search-form input[type="search"] {
  left: auto;
  right: calc(100% - var(--global-search-trigger-width) + 72px);
  width: 188px;
  max-width: 188px;
  flex: none;
  border-right: 0;
  border-radius: 0 0 0 var(--radius-control, 4px);
}
html[data-device="desktop"] .account-nav .global-search.opens-below.is-open .global-search-source {
  left: auto;
  right: calc(100% - var(--global-search-trigger-width));
  width: 72px;
  max-width: 72px;
  border-left: 0;
  border-radius: 0 0 var(--radius-control, 4px) 0;
}
html[data-device="desktop"] .global-search.opens-below.is-open .global-search-form:focus-within input[type="search"],
html[data-device="desktop"] .account-nav .global-search.opens-below.is-open .global-search-form:focus-within .global-search-source {
  border-color: var(--cyan);
}
html[data-device="desktop"] .global-search.opens-below .global-search-panel {
  top: calc(var(--global-search-trigger-height) + 38px);
  left: auto;
  right: calc(100% - var(--global-search-trigger-width));
  width: 260px;
  max-height: min(480px, calc(100dvh - 110px));
}

@media (max-width: 1279px) {
  html[data-device="desktop"] .account-nav {
    gap: 6px;
  }
  html[data-device="desktop"] .account-nav > a,
  html[data-device="desktop"] .account-nav > button,
  html[data-device="desktop"] .account-nav > .account-menu > .account-menu-trigger,
  html[data-device="desktop"] .account-nav > .notification-menu > .notification-menu-trigger {
    min-height: 30px;
    padding-inline: 9px;
    font-size: 0.68rem;
    letter-spacing: 1.2px;
  }
  html[data-device="desktop"] .account-nav .global-search-trigger,
  html[data-device="desktop"] .account-nav .global-search-source {
    min-height: 30px;
  }
  html[data-device="desktop"] .global-search,
  html[data-device="desktop"] .global-search-trigger {
    min-width: 30px;
    width: 30px;
  }
  html[data-device="desktop"] .global-search {
    --global-search-inline-width: 220px;
    --global-search-trigger-width: 30px;
    --global-search-trigger-height: 30px;
    max-width: 220px;
  }
  html[data-device="desktop"] .global-search-form {
    min-height: 30px;
  }
  html[data-device="desktop"] .global-search-trigger svg {
    display: block;
    flex: none;
  }
  html[data-device="desktop"] .account-menu-name {
    max-width: 7rem;
  }
}
.account-menu-caret {
  font-size: 0.6rem;
  opacity: 0.8;
}
.account-menu-panel {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 1002;
  /* Sized by its rows, like the nav menus — and like them it needs
     `max-content` to read them, since shrink-to-fit measures against the
     trigger, not the row labels. */
  width: max-content;
  min-width: 150px;
  max-width: min(300px, calc(100vw - 32px));
  padding: 6px;
  border: 1px solid rgba(var(--tint-rgb), 0.42);
  background: rgba(var(--ink-rgb), 0.98);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.46), 0 0 28px rgba(var(--tint-rgb), 0.14);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.account-menu-panel[hidden] {
  display: none;
}
.account-menu-logout {
  margin: 0;
}
/* Menu rows override the generic boxed .account-nav a/button look. */
.account-menu-panel .account-menu-item {
  min-height: 36px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0 10px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--chrome);
  font-size: 0.76rem;
  text-transform: none;
  letter-spacing: 1px;
  text-align: left;
}
.account-menu-panel .account-menu-item:hover,
.account-submenu.is-open > .account-menu-item {
  color: var(--white);
  border-color: rgba(var(--tint-rgb), 0.4);
  background: rgba(var(--tint-rgb), 0.08);
  box-shadow: none;
}
.account-menu-state {
  font-size: 0.66rem;
  letter-spacing: 1px;
  color: var(--muted);
}
.account-menu-toggle[data-enabled="1"] .account-menu-state {
  color: var(--cyan);
}
.account-menu-arrow {
  font-size: 0.8rem;
  opacity: 0.75;
}

/* Flyout submenus (Board theme / Piece set) open to the left of the panel. */
.account-submenu {
  position: relative;
}
.account-submenu-panel {
  position: absolute;
  top: -6px;
  /* Flush against the row that opens it, for the same reason the menus are
     flush against their triggers: the pointer travels from the row into the
     panel, and an 8px gap is a place for the menu to close. */
  right: 100%;
  width: 300px;
  max-width: calc(100vw - 28px);
  padding: 14px;
  border: 1px solid rgba(var(--tint-rgb), 0.42);
  background: rgba(var(--ink-rgb), 0.98);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.46), 0 0 28px rgba(var(--tint-rgb), 0.14);
}
.account-submenu-panel[hidden] {
  display: none;
}

/* Board theme + piece set swatch grids (shared by the account dropdown). */
.account-menu .theme-grid,
.account-menu .piece-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.account-menu .theme-swatch,
.account-menu .piece-swatch {
  min-height: 0;
  aspect-ratio: 1;
  position: relative;
  border: 1px solid rgba(var(--tint-rgb), 0.28);
  cursor: pointer;
  padding: 0;
  display: block;
  place-items: stretch;
  transition: box-shadow 0.15s ease, transform 0.12s ease;
}
.account-menu .theme-swatch {
  background-image: linear-gradient(135deg, var(--sw-light) 0 50%, var(--sw-dark) 50% 100%);
}
.account-menu .piece-swatch {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Light board-square tone so white pieces with thin outlines stay visible. */
  background: #d6dde2;
  padding: 4px;
}
.account-menu .piece-swatch img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
}
.account-menu .theme-swatch:hover,
.account-menu .piece-swatch:hover {
  transform: translateY(-1px);
  color: inherit;
  box-shadow: none;
}
.account-menu .theme-swatch.is-selected,
.account-menu .piece-swatch.is-selected {
  border-color: var(--cyan);
  box-shadow: 0 0 0 2px var(--cyan);
}
/* A filled check badge so the chosen tile reads at a glance — a thin ring
   alone disappears against the light piece tiles. */
.account-menu .theme-swatch.is-selected::after,
.account-menu .piece-swatch.is-selected::after {
  content: '\2713';
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 15px;
  height: 15px;
  display: grid;
  place-items: center;
  background: var(--cyan);
  color: #ffffff;
  font-size: 11px;
  line-height: 1;
  border-radius: 2px;
}

/* Account interaction chrome follows the server-selected mobile device class,
   never a viewport breakpoint. Page-content reflow keeps its independent width
   rules below. */
html[data-device="mobile"] .account-nav {
  position: absolute;
  top: 12px;
  right: 18px;
  left: auto;
  justify-content: end;
  max-width: calc(100vw - 80px);
}

html[data-device="mobile"] .global-search.is-open {
  position: fixed;
  top: 12px;
  right: 18px;
  left: 68px;
  z-index: 1105;
  width: auto;
  max-width: none;
}
html[data-device="mobile"] .global-search.is-open .global-search-form {
  background: var(--ink);
  box-shadow: 0 0 0 1px rgba(var(--tint-rgb), 0.14);
}
html[data-device="mobile"] .global-search.is-open .global-search-form input[type="search"] {
  max-width: none;
}
html[data-device="mobile"] .global-search-panel {
  position: fixed;
  top: 51px;
  right: 12px;
  left: 12px;
  width: auto;
  max-height: calc(100dvh - 62px);
}
html[data-device="mobile"] .global-search-game-headline {
  align-items: flex-start;
}

/* On mobile devices the panel uses the available right edge and submenus stack
   inline instead of flying off-screen to the left. */
html[data-device="mobile"] .account-menu-panel {
  right: 0;
  max-width: calc(100vw - 36px);
}

html[data-device="mobile"] .notification-menu-panel {
  position: fixed;
  top: 56px;
  right: 12px;
  left: 12px;
  width: auto;
}

html[data-device="mobile"] .account-submenu-panel {
  position: static;
  width: auto;
  margin: 4px 0 2px;
  padding: 10px;
}

.message-stack {
  /* Fixed overlay: flash messages float over the page instead of sitting
     in flow at the top of .page, where they push the whole layout down
     when they appear. */
  position: fixed;
  top: 70px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1300;
  /* Sized by the sentence, not a 720px slab. A three-word confirmation held a
     bar most of the page wide across the top of the board and rode the scroll
     with it (owner, 2026-08-05: "this freezes and scrolls with you - thats
     annoying"). */
  width: max-content;
  max-width: min(560px, calc(100vw - 24px));
  display: grid;
  justify-items: center;
  gap: 8px;
  margin: 0;
  pointer-events: none;
}
.site-message {
  border: 1px solid rgba(255, 255, 255, 0.09);
  /* The same floating-pill language as the email verification notice: a
     translucent blurred lozenge that reads as a passing note, not a panel
     parked on the page. */
  border-radius: 999px;
  background: rgba(var(--surface-rgb), 0.68);
  backdrop-filter: blur(16px) saturate(1.2);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  color: var(--white);
  padding: 8px 16px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.78rem;
  letter-spacing: 1px;
  overflow-wrap: anywhere;
  cursor: pointer;
  pointer-events: auto;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.28);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.site-message.is-dismissing {
  opacity: 0;
  transform: translateY(-4px);
}
/* Errors and warnings keep an opaque fill. A blurred lozenge is right for a
   note that is passing through; something the reader has to act on should not
   be reading the board through it. */
.site-message.error {
  border-color: rgba(var(--danger-rgb), 0.5);
  background:
    linear-gradient(rgba(var(--danger-rgb), 0.08), rgba(var(--danger-rgb), 0.08)),
    rgb(var(--void-rgb));
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.site-message.warning {
  border-color: rgba(var(--amber-rgb), 0.5);
  background:
    linear-gradient(rgba(var(--amber-rgb), 0.08), rgba(var(--amber-rgb), 0.08)),
    rgb(var(--void-rgb));
  color: #ffe49a;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.auth-shell {
  max-width: 520px;
  margin: 0 auto 70px;
}
.auth-card,
.profile-panel {
  padding: 28px;
}
.auth-copy,
.auth-secondary,
.profile-empty {
  color: var(--muted);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.85rem;
  letter-spacing: 1px;
  line-height: 1.6;
}
.auth-form {
  display: grid;
  gap: 16px;
}
.auth-field {
  display: grid;
  gap: 7px;
  color: var(--muted);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.72rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
.auth-field input,
.auth-field select,
.auth-field textarea,
.collection-form input {
  width: 100%;
  border: 1px solid rgba(var(--tint-rgb), 0.32);
  background: rgba(0,0,0,0.32);
  color: var(--white);
  padding: 12px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.92rem;
  outline: none;
}
.auth-field select {
  min-height: 44px;
  appearance: none;
  color: var(--chrome);
  background-color: rgba(0, 0, 0, 0.38);
  background-image:
    linear-gradient(45deg, transparent 50%, var(--tint) 50%),
    linear-gradient(135deg, var(--tint) 50%, transparent 50%);
  background-position:
    calc(100% - 18px) 19px,
    calc(100% - 12px) 19px;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  cursor: pointer;
}
.auth-field textarea {
  min-height: 190px;
  resize: vertical;
  line-height: 1.55;
}
.auth-field input:focus,
.auth-field select:focus,
.auth-field textarea:focus,
.collection-form input:focus {
  border-color: var(--cyan);
  box-shadow: 0 0 18px rgba(var(--tint-rgb), 0.12);
}
.api-token-expiry-field {
  position: relative;
}
.api-token-expiry-picker {
  display: none;
  position: relative;
}
.api-token-expiry-field.is-enhanced .api-token-expiry-select {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.api-token-expiry-field.is-enhanced .api-token-expiry-picker {
  display: block;
}
.api-token-expiry-trigger {
  width: 100%;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border: 1px solid rgba(var(--tint-rgb), 0.32);
  background: rgba(0, 0, 0, 0.38);
  color: var(--chrome);
  padding: 12px 14px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.92rem;
  letter-spacing: 1px;
  text-align: left;
  cursor: pointer;
}
.api-token-expiry-trigger:hover,
.api-token-expiry-trigger:focus-visible,
.api-token-expiry-field.is-open .api-token-expiry-trigger {
  outline: none;
  border-color: var(--cyan);
  box-shadow: 0 0 18px rgba(var(--tint-rgb), 0.12);
}
.api-token-expiry-caret {
  flex: 0 0 auto;
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 7px solid var(--tint);
}
.api-token-expiry-menu {
  position: absolute;
  z-index: 60;
  left: 0;
  right: 0;
  top: 100%;
  display: grid;
  border: 1px solid rgba(var(--tint-rgb), 0.42);
  background: rgba(var(--ink-rgb), 0.98);
  box-shadow: 0 18px 36px rgba(0, 0, 0, 0.48), 0 0 28px rgba(var(--tint-rgb), 0.12);
  padding: 6px;
}
.api-token-expiry-menu[hidden] {
  display: none;
}
.api-token-expiry-option {
  width: 100%;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--white);
  padding: 10px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.88rem;
  letter-spacing: 1px;
  text-align: left;
  cursor: pointer;
}
.api-token-expiry-option:hover,
.api-token-expiry-option:focus-visible,
.api-token-expiry-option[aria-selected="true"] {
  outline: none;
  background: rgba(var(--tint-rgb), 0.12);
  color: var(--cyan);
}
.auth-field small {
  color: var(--muted);
  opacity: 0.76;
  font-size: 0.7rem;
  letter-spacing: 1px;
  text-transform: none;
}
.auth-field strong,
.auth-errors {
  color: var(--danger);
  font-size: 0.72rem;
  letter-spacing: 1px;
  text-transform: none;
}
.auth-recaptcha {
  min-height: 78px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.auth-recaptcha-fallback {
  color: var(--danger);
  font-size: 0.72rem;
  letter-spacing: 1px;
  line-height: 1.5;
  text-align: center;
  text-transform: none;
}
.auth-submit,
.collection-form button {
  border: 1px solid var(--tint);
  background: rgba(var(--tint-rgb), 0.08);
  color: var(--chrome);
  padding: 12px 18px;
  font-family: 'Orbitron', sans-serif;
  letter-spacing: 2px;
  cursor: pointer;
}
.auth-submit:hover,
.collection-form button:hover {
  color: var(--white);
  box-shadow: 0 0 20px rgba(var(--tint-rgb), 0.18);
}
.auth-primary-action {
  display: flex;
  justify-content: center;
}
.auth-secondary {
  margin-top: 20px;
  text-align: center;
}
.auth-secondary a {
  color: var(--cyan);
}
.desktop-consent {
  display: grid;
  gap: 18px;
}
.desktop-consent-mark {
  align-items: center;
  background: rgba(var(--tint-rgb), 0.12);
  border: 1px solid rgba(var(--tint-rgb), 0.38);
  border-radius: 50%;
  color: var(--cyan);
  display: flex;
  font-size: 1.45rem;
  height: 52px;
  justify-content: center;
  width: 52px;
}
.desktop-consent h2 {
  color: var(--white);
  font-family: 'Rajdhani', sans-serif;
  font-size: 1.8rem;
  line-height: 1.15;
  margin: 0;
}
.desktop-consent .prose-body {
  margin: 0;
}
.desktop-consent-details {
  border-bottom: 1px solid rgba(var(--tint-rgb), 0.18);
  border-top: 1px solid rgba(var(--tint-rgb), 0.18);
  display: grid;
  margin: 2px 0 0;
}
.desktop-consent-details > div {
  display: grid;
  gap: 14px;
  grid-template-columns: 72px minmax(0, 1fr);
  padding: 13px 0;
}
.desktop-consent-details > div + div {
  border-top: 1px solid rgba(var(--tint-rgb), 0.12);
}
.desktop-consent-details dt,
.desktop-consent-details dd {
  margin: 0;
}
.desktop-consent-details dt {
  color: var(--chrome);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.68rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
.desktop-consent-details dd,
.desktop-consent-safe {
  color: var(--muted);
  font-family: 'Rajdhani', sans-serif;
  font-size: 0.96rem;
  line-height: 1.5;
}
.desktop-consent-close {
  align-items: center;
  border-top: 1px solid rgba(var(--slate-rgb), .55);
  display: flex;
  flex-direction: column;
  gap: .65rem;
  margin-top: 1rem;
  padding-top: 1rem;
}
.desktop-consent-close .prose-body { margin: 0; }
.desktop-consent-close button { min-width: 9rem; }
.desktop-consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: flex-end;
}
.desktop-consent-result {
  min-height: 230px;
  place-content: center;
  text-align: center;
}
.desktop-consent-result .desktop-consent-mark {
  justify-self: center;
}
.desktop-consent-result.is-approved .desktop-consent-mark {
  background: rgba(var(--mint-rgb), 0.13);
  border-color: rgba(var(--mint-rgb), 0.48);
  color: var(--mint);
}
.desktop-consent-safe {
  margin: 0;
}
.auth-consent {
  margin-top: 16px;
  text-align: center;
  font-size: 0.82rem;
  color: var(--muted);
}
.auth-consent a {
  color: var(--cyan);
}
.auth-checkbox-field {
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 10px 12px;
  color: var(--muted);
  line-height: 1.5;
  text-transform: none;
}
.auth-checkbox-field input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  accent-color: var(--cyan);
}
.auth-checkbox-field a {
  color: var(--cyan);
}
.auth-checkbox-field strong {
  grid-column: 2;
}

.profile-panel,
.profile-list,
.profile-row {
  min-width: 0;
}
.profile-panel > .section-title,
.profile-panel-heading .section-title,
.collection-heading .section-title,
.bookmark-toolbar .section-title {
  font-size: 0.82rem;
  letter-spacing: 3px;
}
/* The library is ONE list, and a list is not a stack of cards. Every section —
   notebooks, imported games, collections, starred games, starred players —
   renders these two classes, so the feature has one item component instead of
   the three it grew (`.library-card`, `.notebook-card`, `.profile-row`).

   Layout only, per the role contract: the hairline, the hover tint and every
   colour come from `listing-row` and the `entity-*` roles the templates apply.
   There is no border, no fill and no gap between rows — gaps plus borders is
   what made the page read as "literally nothing except boxes" (owner,
   2026-08-05). Rows touch, and one hairline separates them. */
.profile-list {
  display: grid;
  gap: 0;
}
.profile-list.compact {
  margin-top: 12px;
}
/* Phone-only, by CSS. The rail is hidden below 860px, so without these rows a
   small screen lands on a heading and no way into any section. Above that the
   rail is on the page listing the same five destinations, and this list is a
   second copy of it (owner, 2026-08-06: "this was ment to be mobile only,
   while desktop has navigation here").

   Where it does show, it keeps the panel's full width and loses height instead.
   Narrowing the rows to fit their words read as a different page from the
   listings below them, so the correction is on one axis only ("no reason for
   these to be so long", then "now it just looks weird, revert it back to how it
   was and reduce it on the Y axis only"). */
.library-sections {
  display: none;
}
/* The list starts where the head ends. The head's own rule sat above the first
   row while no other row has a rule above it, so the top of the list looked
   like a different component from the rest of it (owner: "the gap above
   notebooks and the line when the others dont have that bothers me"). */
.account-content:has(.library-sections) .account-content-head {
  margin-bottom: 0;
  border-bottom: 0;
}
@media (max-width: 860px) {
  .library-sections {
    display: grid;
  }
  /* One column, no gap: the two-column row reserves a track for a control this
     row does not have, and the 8px gutter beside it was 8px of row that was not
     the link. The link is the row. */
  .library-sections .library-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .library-sections .profile-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    padding-top: 10px;
    padding-bottom: 10px;
  }
}
/* A library entry is something the reader made or kept, so it gets the height
   of one: a lead line, what is inside it, and the facts that let them find it
   again. At 13px of padding around three lines of 0.9rem type these were 44px
   tall and read as rows in a report. */
.profile-row {
  display: grid;
  gap: 5px;
  /* Vertical padding only at the ends: the row's left edge lines up with the
     section label above it, so the list reads as one column rather than an
     indented block floating inside the panel. */
  padding: 18px 4px;
  min-width: 0;
  color: var(--chrome);
  text-decoration: none;
}
/* The lead line of an open-only row: what the section is called, and how much
   is in it. Only the library landing draws one now — a listing of games says
   the same things in columns, under headings that name them. */
.library-row-title {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 16px;
  min-width: 0;
}
/* A row whose only action is "open it" says so with a chevron rather than a
   control: there is nothing to press but the row itself. */
.library-row-open {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  color: var(--muted);
  pointer-events: none;
}
.library-row-chevron {
  font-size: 1.3rem;
  line-height: 1;
}
.listing-row:hover .library-row-open {
  color: var(--tier-scan, var(--white));
}
.profile-import-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 42px;
  padding: 11px 16px;
  border: 1px solid rgba(126, 206, 255, 0.9);
  background: #087dff;
  color: #ffffff;
  font-family: 'Orbitron', sans-serif;
  font-size: 0.78rem;
  letter-spacing: 1.5px;
  text-decoration: none;
  text-transform: uppercase;
  box-shadow: 0 0 18px rgba(8, 125, 255, 0.26);
}
.profile-import-action:hover {
  color: #ffffff;
  background: #0a9dff;
  box-shadow: 0 0 24px rgba(10, 157, 255, 0.34);
}
.profile-secondary-action {
  background: rgba(var(--tint-rgb), 0.1);
  color: var(--chrome);
  box-shadow: none;
}
.profile-secondary-action:hover {
  background: rgba(var(--tint-rgb), 0.16);
  color: var(--white);
}
.profile-row small,
.collection-meta {
  color: var(--muted);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.74rem;
  letter-spacing: 1px;
}
.collection-create {
  position: relative;
  justify-self: end;
}
.collection-create summary {
  list-style: none;
}
.collection-create summary::-webkit-details-marker {
  display: none;
}
/* The toggle was a 42px square holding a lone `+` in Orbitron. A square with a
   symbol in it is a guess the reader has to take; the control says what it
   makes now, and wears the shared secondary action instead of its own box. */
.collection-create-toggle {
  cursor: pointer;
}
/* The collection editor: rename and delete, folded away behind one word in the
   page head. Open, it is a small panel hanging off the control that opened it —
   the same shape as the create popover, because it is the same kind of thing. */
.collection-edit {
  position: relative;
  justify-self: end;
}
.collection-edit > summary {
  list-style: none;
  cursor: pointer;
}
.collection-edit > summary::-webkit-details-marker {
  display: none;
}
.collection-edit-body {
  position: absolute;
  z-index: 8;
  right: 0;
  top: calc(100% + 10px);
  width: min(420px, calc(100vw - 56px));
  display: grid;
  gap: 10px;
  padding: 14px;
  border: 1px solid rgba(var(--tint-rgb), 0.24);
  background: rgba(var(--panel-rgb), 0.96);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.42);
}
.collection-edit-body .collection-form {
  margin-bottom: 0;
}
.collection-form {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  margin-bottom: 20px;
}
.collection-create-form {
  position: absolute;
  z-index: 8;
  right: 0;
  top: calc(100% + 10px);
  width: min(420px, calc(100vw - 56px));
  margin-bottom: 0;
  padding: 12px;
  border: 1px solid rgba(var(--tint-rgb), 0.24);
  background: rgba(var(--panel-rgb), 0.96);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.42);
}
/* Library card grid — auto-fills so a handful of collections and a packed
   account both stay tidy. Used by collection cards and the bookmark cards. */
.library-section {
  margin-bottom: 30px;
}
.library-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 14px;
  position: relative;
}
.library-label {
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.72rem;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--chrome);
}
/* `.library-grid` and `.library-card` are further down this file: the theory
   that a collection is the same kind of object as a notebook and should render
   the same list row was tried, shown to the owner beside production, and
   reverted. See the collection block below. */
.library-empty-plus {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  color: var(--chrome);
  font-size: 0.8rem;
  line-height: 1;
  vertical-align: middle;
}

.collection-delete-form {
  margin: 0;
}
/* One action language for the whole feature. There were four removal controls
   wearing three verbs, each a text button in its own outlined box beside the
   row it acted on — which is how a one-line game ended up sharing its width
   with a red slab. The row's controls are now quiet icons inside the row, and
   the intent is carried by colour and confirmation:

     un-star  → the filled gold star, the same control that starred it
     delete   → a danger glyph plus the existing data-confirm

   `.collection-delete-form` is still the collection's own Delete Collection
   form in the editor, which IS a worded button, so this styles the row form
   only. */
.collection-game-row form button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-control, 6px);
  background: none;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.14s ease, background 0.14s ease;
}
.collection-game-row form button svg {
  width: 17px;
  height: 17px;
}
/* The star reads as filled and gold because the row it sits in exists only
   because it was starred; a hollow star here would say the opposite. */
.bookmark-remove-form button {
  color: var(--gold);
}
.bookmark-remove-form button:hover,
.bookmark-remove-form button:focus-visible {
  color: var(--white);
  background: rgba(var(--gold-rgb), 0.16);
  outline: none;
}
.library-row-form:not(.bookmark-remove-form) button:hover,
.library-row-form:not(.bookmark-remove-form) button:focus-visible {
  color: var(--danger);
  background: rgba(var(--danger-rgb), 0.14);
  outline: none;
}
.collection-toolbar {
  display: grid;
  gap: 14px;
  margin-bottom: 18px;
}
.bookmark-toolbar {
  grid-template-columns: 1fr auto;
  align-items: start;
}
.bookmark-toolbar .section-title {
  justify-content: flex-start;
  margin-bottom: 0;
}
.bookmark-toolbar .section-title::before {
  display: none;
}
/* Six sort options were six outlined boxes, which on a phone stacked into a
   2×3 wall of rectangles above a single result. They are words now, and the
   selected one is marked by weight and an underline rather than by being the
   one box with a brighter edge. Left-aligned, because the list they order is
   left-aligned and a centred row of controls above a left column reads as a
   separate object. */
.collection-sort {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 18px;
  justify-content: flex-start;
}
.collection-sort a {
  padding: 4px 0;
  border: 0;
  color: var(--muted);
  font-size: var(--fs-label, 0.9rem);
  letter-spacing: 0;
  text-transform: none;
  text-decoration: none;
  white-space: nowrap;
}
.collection-sort a:hover {
  color: var(--tier-scan, var(--white));
}
.collection-sort a.active {
  color: var(--tier-scan, var(--white));
  font-weight: 700;
  box-shadow: inset 0 -1px 0 0 currentColor;
}
/* ── The library's game listing ────────────────────────────────────────────
   Three sections of My Library list games — imported, starred, and the
   contents of a collection — and /players/<name>/games/ lists the same object.
   Until now each library section drew its own two-line row, and the reader's
   verdict on it was "this is just a line with the name of a game thats the
   wrong color ... where is the substance?".

   Both halves of that are structural. The colour: the row wrapped itself in
   `surface-link`, which exists so a card's contents keep their own voice, and
   it turned the pairing lilac — the colour the site spends on a name that is
   NOT a link. A pairing in a game listing is a link, and it is cyan on every
   other page of this site. And the substance: a pairing over a meta run
   carries no move count, no opening and no alignment, so nothing lines up
   down the column and there is nothing to scan.

   So the library lists games the way the archive lists them: date, players,
   result, moves, opening, and the one column the section owns, under a real
   heading row. It is a grid rather than a <table> because the row is one link
   and, on a phone, one swipe target — `library-swipe.ts` drags the row's
   foreground and parks its form off the right edge, and neither a <tr> nor a
   <td> can be either of those. The heading and the rows read their columns
   from the same custom property, so a column cannot drift from its heading. */
.library-games {
  --library-game-columns:
    82px minmax(220px, 1.5fr) 54px 58px minmax(200px, 1.35fr) minmax(96px, 0.8fr);
  display: grid;
  gap: 0;
}
/* Two sections carry a seventh column, and it is the one thing each of them
   knows that the game itself does not: when it was imported, and when it was
   shelved. */
.library-games.is-imported {
  --library-game-columns:
    82px minmax(220px, 1.5fr) 54px 58px minmax(200px, 1.4fr) 84px 100px;
}
.library-games.is-collection {
  --library-game-columns:
    82px minmax(220px, 1.5fr) 54px 58px minmax(200px, 1.3fr) minmax(90px, 0.8fr) 100px;
}
.library-games-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: end;
  border-bottom: 1px solid var(--tint);
}
.library-games-head-action {
  width: 30px;
}
.library-game-cells {
  display: grid;
  grid-template-columns: var(--library-game-columns);
  align-items: center;
  gap: 0 16px;
  min-width: 0;
}
.library-games-head .library-game-cells {
  padding: 0 4px 9px;
}
.collection-game-row .profile-row.library-game-cells {
  padding: 13px 4px;
  gap: 0 16px;
}
.library-game-cell {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Text wraps rather than truncating. An ellipsis is only honest when the
   column has no more room to give, and here it never does: "Ruy Lopez:
   Classical Variati…" was cut on a 1440px page with room to spare, which
   loses the half of the name a reader was looking for and gains nothing
   (owner: "we shouldnt have truncated text, like we have all this space").
   The two columns that hold names — the pairing and the opening — wrap onto a
   second line instead, which the archive's own table also does. Only the
   fixed-width cells, whose values are a date or a number, still clip. */
.library-game-cell-players,
.library-game-cell-opening,
.library-game-cell-tail.is-name {
  overflow: visible;
  white-space: normal;
}
.column-label.is-centred,
.library-game-cell-result,
.library-game-cell-moves {
  text-align: center;
}
/* The unit rides in the markup rather than in a pseudo-element so it can be
   read aloud, and it is redundant under a MOVES heading. */
.library-game-unit {
  display: none;
}
.library-game-row:hover {
  background: rgba(var(--tint-rgb), 0.04);
}

/* ── A notebook ─────────────────────────────────────────────────
   Every other thing in My Library is a listing of games and reads as one. A
   notebook is the one thing the reader wrote rather than collected, so it is
   drawn as the object it is (owner: "its supposed to look like an actual
   notebook").

   The whole design rests on one number. `--rule` is the height of a written
   line; the sheet is ruled at that step, and every line of type on it is set
   to that line-height with a padding-top that is a whole multiple of it. So
   the text sits ON the rules. Without that alignment the rules are a texture
   behind a list and the eye reads them as noise, which is what the first
   attempt shipped. The title takes two steps rather than a size of its own,
   for the same reason. */
.notebooks {
  /* The size the owner's own references were drawn at: a small dense object,
     many to a shelf. Run one per row at the content width each notebook became
     a letterbox whose ruled lines mostly ran past the last word — bigger, and
     emptier for being bigger (owner: "you just made it bigger and worse", then
     "the size was good on my references"). */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
  /* Every notebook on the shelf is the same size. Sized to its own contents,
     one card ran two rules taller than the one beside it and the shelf read as
     damaged rather than varied (owner, 2026-08-06: "we shouldnt have size
     mismatching"). `1fr` rows take the tallest and give it to all of them. */
  grid-auto-rows: 1fr;
  gap: 16px;
  /* The height of one written line. Every vertical dimension on the sheet is a
     whole multiple of it, without exception — that is what puts the type on
     the rules instead of between them, and it is the only thing separating
     this from a striped background behind a list. */
  --rule: 26px;
  --binding: 44px;
}
/* One card, one sheet of paper. The bound edge is drawn ON the page rather
   than beside it: a strip of card that is a separate colour is a sidebar, and
   the holes sitting in it read as dots next to a striped box, not as holes
   punched through paper. So the rules run the full width of the card and the
   margin washes over them. */
.notebook {
  position: relative;
  display: grid;
  overflow: hidden;
  /* Six written lines, plus the two hairlines of the card's own border. With
     `border-box` the border eats into the height, and 154px of paper is 5.9
     rules — enough to put the last line off the grid it is supposed to sit on.
     Content grows only in whole rules, so a whole-rule floor stays whole. */
  min-height: calc(var(--rule) * 6 + 2px);
  /* No vertical padding: it would offset the text from the rules drawn behind
     it. The blank first and last lines come from the content instead. */
  padding: 0 16px 0 calc(var(--binding) + 12px);
  border: 1px solid var(--border);
  /* Bound on the left, cut on the right: the spine edge is square and the
     outer corners are not, which is most of what says "book" before any
     texture is drawn. */
  border-radius: 3px 10px 10px 3px;
  background-color: #262a30;
  /* Drawn at the bottom of each step, so type set to `line-height: var(--rule)`
     rests on the line rather than straddling it. */
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(var(--tint-rgb), 0) 0,
    rgba(var(--tint-rgb), 0) calc(var(--rule) - 1px),
    rgba(var(--tint-rgb), 0.11) calc(var(--rule) - 1px),
    rgba(var(--tint-rgb), 0.11) var(--rule)
  );
  /* The sheets underneath. Two hard offset copies of the card's own edge, then
     one soft ground shadow — a single sheet floating on a shadow is a card,
     a stack of them is a notebook. */
  box-shadow:
    3px 3px 0 -1px #2b2f34,
    6px 6px 0 -2px #1b1e21,
    0 4px 10px rgba(0, 0, 0, 0.4);
  text-decoration: none;
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}
.notebook:hover {
  transform: translateY(-2px);
  border-color: var(--cyan);
  box-shadow:
    3px 3px 0 -1px #2b2f34,
    6px 6px 0 -2px #1b1e21,
    0 10px 18px rgba(0, 0, 0, 0.5);
}
/* The punched margin: the same paper, shaded, with the holes going through it
   and the brass margin rule closing it. Punched on the writing step so the
   holes line up with the rules instead of scattering down a strip. */
.notebook-binding {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--binding);
  border-right: 2px solid rgba(var(--gold-rgb), 0.68);
  background:
    radial-gradient(circle at 50% calc(var(--rule) / 2),
      #0d0f11 0 4.5px, rgba(255, 255, 255, 0.11) 4.5px 5.6px, transparent 6px)
    0 0 / 100% var(--rule) repeat-y,
    rgba(0, 0, 0, 0.2);
  pointer-events: none;
}
.notebook-sheet {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
/* The title page: title on the top written line, then who has written in it,
   then how many chapters (owner, 2026-08-06). Centred, because the owner asked
   for a centred title and a centred title over left-flush lines reads as two
   different alignments on one page. */
.notebook-title,
.notebook-people,
.notebook-foot {
  display: block;
  line-height: var(--rule);
  text-align: center;
  min-width: 0;
  overflow-wrap: anywhere;
}
.notebook-title {
  font-size: 1.02rem;
}
.notebook-people {
  color: var(--tier-ignore);
  font-size: 0.9rem;
}
/* On the last written line, not the third one (owner, 2026-08-06: "chapters and
   visibility should be on the bottom line"). The blank rules between the
   contributors and the count are the rest of the page waiting to be written on,
   which is the only reason a notebook has more lines than it has words. */
.notebook-foot {
  margin-top: auto;
  color: var(--tier-read, var(--white));
  font-size: 0.9rem;
}
.notebook-chapter-count {
  color: var(--tier-scan);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ── A collection ───────────────────────────────────────────────
   The card the owner runs on production, restored (owner, 2026-08-05:
   "literally git revert the collections to what prod uses and then go from
   there") after a replacement was ranked below it. It is the round-3 card:
   a brass spine, a knight watermark bled off the bottom-right corner, a
   direction arrow in the top-right, and the count anchored to the foot so the
   line sits at the same height on every card in the row.

   Three changes on top of it, named in the same turn: the "COLLECTION" kicker
   is gone — twelve cards each labelled with the same word under a heading that
   already says Collections is not information, and it held the title's slot so
   the name read as its subtitle — the name takes that slot, and the count is
   bold.

   Charcoal's own type replaces the Orbitron/Share Tech Mono metrics the card
   was drawn with: no tracked-out uppercase micro-caps for the count line. */
.library-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
  /* Stroked, not filled, so the weight is a number and not a font's opinion. */
  --arrow-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h15M12.5 5.5 19 12l-6.5 6.5'/%3E%3C/svg%3E");
}
.library-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 116px;
  overflow: hidden;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-left: 3px solid rgba(var(--gold-rgb), 0.55);
  border-radius: var(--radius-card, 3px);
  background: linear-gradient(158deg, #26292d, #1e2124);
  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.35);
  text-decoration: none;
  transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
/* The watermark and the arrow are decoration drawn by the card itself, so they
   are pseudo-elements rather than markup no reader ever hears. */
.library-card::before {
  content: '♞';
  position: absolute;
  right: -8px;
  bottom: -20px;
  font-size: 96px;
  line-height: 1;
  color: rgba(var(--gold-rgb), 0.09);
  pointer-events: none;
  transition: color 0.2s ease;
}
/* Drawn, not typed. The `→` glyph is whatever hairline the reader's font stack
   happens to ship and there is no weight axis to thicken it with (owner,
   2026-08-05: "lets just fix that arrow and make it bold"), so the arrow is an
   SVG mask with a stroke width this file controls, tinted by a token. */
.library-card::after {
  content: '';
  position: absolute;
  top: 15px;
  right: 15px;
  width: 18px;
  height: 18px;
  background-color: var(--chrome);
  -webkit-mask: var(--arrow-mask) center / contain no-repeat;
  mask: var(--arrow-mask) center / contain no-repeat;
  transition: background-color 0.2s ease, transform 0.2s ease;
}
.library-card:hover {
  border-color: var(--cyan);
  border-left-color: var(--cyan);
  background: linear-gradient(158deg, #2b2e33, #22252a);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4);
}
.library-card:hover::after {
  background-color: var(--cyan);
  transform: translateX(3px);
}
.library-card:hover::before {
  color: rgba(var(--gold-rgb), 0.15);
}
/* The whole card is the link, so the name is not itself wearing link voice —
   it is the card's title, at scan tier. The right padding keeps it clear of
   the arrow. */
.library-card-title {
  position: relative;
  min-width: 0;
  padding-right: 22px;
  color: var(--tier-scan, var(--white));
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
/* `margin-top: auto` is what gives the row of cards one shared baseline for
   the count no matter how many lines a name takes. */
.library-card-count {
  position: relative;
  margin-top: auto;
  min-width: 0;
  color: var(--tier-read, var(--white));
  font-size: 0.9rem;
}
.library-card-figure {
  color: var(--tier-scan, var(--white));
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Two layouts, one shape. `.collection-game-row` is the row that owns a
   removal control and therefore the phone swipe; `.library-row` is the row
   that only opens, and it never becomes a swipe container — a notebook row
   dragged left revealed a 96px hole where a delete panel would have been.
   Both are two columns: the thing, then its one control.

   The control sits inside the row rather than beside it. Stretched to the
   row's height it was a slab as tall as the listing and a quarter as wide,
   and on /library/imported/ it pushed itself off the right edge of the
   container entirely. Centred and icon-sized, the row gives its width to the
   thing being listed. */
.collection-game-row,
.library-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
}
.collection-game-row .profile-row,
.library-row .profile-row {
  min-width: 0;
}
.collection-game-row form {
  margin: 0;
  display: grid;
}
/* A PGN paste box does not need the full page width to read as the primary
   action (owner images 14, 25 "still overly massive"). At 1052px the panel was
   the widest thing on the page for a textarea whose longest line is an
   80-column PGN movetext row; 620px is that line with room around it, and the
   panel stops competing with the page title for the eye. */
.imported-game-import {
  max-width: 620px;
  margin-inline: auto;
  margin-bottom: 24px;
}
.imported-game-form {
  display: grid;
  gap: 14px;
}
.imported-game-source-panel[hidden] {
  display: none;
}
.imported-game-field {
  display: grid;
  gap: 8px;
  color: var(--muted);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.72rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
.imported-game-source {
  margin: 0;
  padding: 0;
  border: 0;
}
.imported-game-source legend {
  margin-bottom: 8px;
}
.imported-game-source-options {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  list-style: none;
}
.imported-game-source-options div {
  display: inline-flex;
}
.imported-game-source-options label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 42px;
  padding: 10px 12px;
  border: 1px solid rgba(var(--tint-rgb), 0.28);
  background: rgba(0,0,0,0.24);
  color: var(--white);
  cursor: pointer;
  box-sizing: border-box;
}
.imported-game-source-options input {
  accent-color: var(--cyan);
}
.imported-game-source-options label:has(input:checked) {
  border-color: var(--cyan);
  color: var(--cyan);
  box-shadow: 0 0 18px rgba(var(--tint-rgb), 0.12);
}
.imported-game-field textarea,
.imported-game-field input,
.imported-game-field select,
.imported-game-search input {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  border: 1px solid rgba(var(--tint-rgb), 0.32);
  border-radius: 0;
  background: rgba(0,0,0,0.32);
  color: var(--white);
  padding: 12px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.88rem;
  outline: none;
  appearance: none;
  color-scheme: dark;
}
/* A select that suppresses its native arrow has to draw one, or it is a
   rectangle with a word in it and nothing says it opens. This was the only
   one on the site that did not — audited across /import/, /settings/, the
   opening explorer, the notebook forms and the auth forms; every other
   `appearance: none` select already carries the two-gradient caret, and the
   rest keep the browser's own. It has to come after the `background`
   shorthand above, which would otherwise wipe the image, and it is drawn with
   gradients rather than an SVG so it takes the theme's own token. */
.imported-game-field select {
  padding-right: 30px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--tint) 50%),
    linear-gradient(135deg, var(--tint) 50%, transparent 50%);
  background-position:
    calc(100% - 17px) calc(50% - 2px),
    calc(100% - 12px) calc(50% - 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  cursor: pointer;
}
.imported-game-field textarea {
  /* Nine or so PGN lines, and it drags taller when a game needs more. 260px
     made the panel as tall as it was wide for a box that is usually filled by
     one paste. */
  min-height: 190px;
  resize: vertical;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  overflow-x: auto;
}
.imported-game-source-options input[type="radio"] {
  width: 16px;
  min-width: 16px;
  max-width: 16px;
  height: 16px;
  padding: 0;
  border: 0;
  background: transparent;
  appearance: auto;
  box-shadow: none;
}
.imported-game-field input[name="remote_url"] {
  font-size: 0.78rem;
}
.imported-game-field textarea:focus,
.imported-game-field input:focus,
.imported-game-field select:focus,
.imported-game-search input:focus {
  border-color: var(--cyan);
  box-shadow: 0 0 18px rgba(var(--tint-rgb), 0.12);
}
.imported-game-actions,
.imported-game-search {
  display: grid;
  grid-template-columns: minmax(180px, 260px) auto;
  gap: 12px;
  align-items: end;
}
.imported-game-search {
  grid-template-columns: minmax(220px, 1fr) auto;
  justify-self: stretch;
}
/* Both controls take the width their content asks for and sit together at the
   left. A 260px track for the word "Private" left the submit button stranded
   in the middle of the row with 250px of nothing beside it. */
.imported-game-actions {
  grid-template-columns: minmax(150px, max-content) max-content;
  justify-content: start;
}
/* `.imported-game-search button` is not listed here: that control wears the
   `action-secondary` role now. Search is not the primary action of a page whose
   point is the list below it, and a pressed-blue key above one result was the
   brightest object on the surface. */
.imported-game-form button {
  border: 1px solid var(--tint);
  border-radius: 0;
  background: #087dff;
  color: #ffffff;
  padding: 12px 18px;
  font-family: 'Orbitron', sans-serif;
  letter-spacing: 2px;
  cursor: pointer;
  appearance: none;
  box-shadow: 0 0 18px rgba(8, 125, 255, 0.24);
}
.imported-game-form button:hover {
  color: var(--white);
  background: #0a9dff;
  box-shadow: 0 0 24px rgba(10, 157, 255, 0.34);
}
.profile-settings-form {
  display: grid;
  gap: 18px;
}
.device-session-list {
  border-bottom: 1px solid rgba(var(--tint-rgb), 0.18);
  border-top: 1px solid rgba(var(--tint-rgb), 0.18);
  display: grid;
  margin-top: 12px;
}
.device-session-item {
  align-items: center;
  display: grid;
  gap: 10px 20px;
  grid-template-columns: minmax(150px, .8fr) minmax(0, 2fr) auto;
  min-width: 0;
  padding: 12px 0;
}
.device-session-item + .device-session-item {
  border-top: 1px solid rgba(var(--tint-rgb), 0.12);
}
.device-session-main strong {
  color: var(--white);
  font-size: .92rem;
}
.device-session-meta {
  color: var(--muted);
  display: grid;
  font-family: 'Share Tech Mono', monospace;
  font-size: .72rem;
  gap: 4px 14px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.device-session-action {
  margin: 0;
}
.device-session-action .action-danger {
  min-height: 34px;
  padding: 6px 11px;
}
.device-session-revoke-all {
  justify-items: start;
  margin-top: 14px;
}
.appearance-settings-form {
  margin: 0 auto;
  max-width: 720px;
  width: 100%;
}
.appearance-settings-form .settings-group {
  border: 0;
  border-top: 1px solid rgba(var(--tint-rgb), 0.18);
  margin: 0;
  padding: 18px 0 12px;
}
.appearance-settings-form .profile-setting-row,
.appearance-settings-form .profile-setting-options-block {
  grid-template-columns: minmax(150px, 190px) minmax(0, 320px);
  width: 100%;
}
.appearance-settings-form .annotation-color-buttons {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.appearance-settings-form .annotation-color-settings-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: stretch;
  position: relative;
  width: 100%;
}
.appearance-settings-form .annotation-color-settings-head .settings-reset-control {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}
.appearance-settings-form .annotation-color-button {
  justify-content: space-between;
}
.appearance-settings-form .settings-actions {
  border-top: 1px solid rgba(var(--tint-rgb), 0.18);
  padding-top: 16px;
}
.profile-setting-row {
  display: grid;
  grid-template-columns: minmax(150px, 210px) minmax(0, 320px);
  align-items: center;
  justify-content: start;
  gap: 10px 24px;
  width: fit-content;
  max-width: 100%;
  padding: 7px 0;
  color: var(--white);
  font-family: 'Share Tech Mono', monospace;
}
.setting-name,
.setting-option-label {
  color: var(--muted);
  font-size: 0.82rem;
  letter-spacing: 0.5px;
}
.setting-control {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
  color: var(--chrome);
}
.setting-control.is-checkbox {
  min-height: 32px;
}
.setting-inline-control {
  align-items: baseline;
}
.setting-help,
.settings-save-status {
  color: var(--muted);
  font-size: 0.78rem;
  letter-spacing: 0.2px;
  line-height: 1.45;
}
.setting-error {
  flex-basis: 100%;
  color: var(--danger);
  font-size: 0.78rem;
  line-height: 1.4;
}
.profile-setting-row input[type="checkbox"] {
  width: 20px;
  height: 20px;
  accent-color: var(--cyan);
}
.profile-setting-row select {
  width: min(240px, 100%);
  min-width: min(180px, 100%);
  border: 1px solid rgba(var(--tint-rgb), 0.32);
  background: rgba(0,0,0,0.32);
  color: var(--chrome);
  padding: 8px 10px;
}

.annotation-color-settings {
  display: grid;
  gap: 10px;
}
.annotation-color-settings-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.annotation-color-settings-head .settings-group-title {
  margin: 0;
}
.settings-reset-control {
  min-height: 34px;
  white-space: nowrap;
}
.annotation-color-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.annotation-color-button {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 34px;
  padding: 3px 5px 3px 10px;
  border: 1px solid rgba(var(--tint-rgb), 0.18);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.18);
  color: var(--white);
  cursor: pointer;
  font: 0.82rem 'Share Tech Mono', monospace;
  letter-spacing: 0.3px;
}
.annotation-color-button:hover,
.annotation-color-button:focus-within {
  border-color: rgba(var(--tint-rgb), 0.55);
  background: rgba(var(--tint-rgb), 0.08);
}
.annotation-color-picker {
  box-sizing: border-box;
  width: 30px;
  height: 28px;
  padding: 2px;
  border: 1px solid rgba(var(--tint-rgb), 0.34);
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.34);
  cursor: pointer;
}
.annotation-color-picker:focus-visible {
  border-color: var(--cyan);
  outline: none;
  box-shadow: 0 0 14px rgba(var(--tint-rgb), 0.14);
}
.annotation-color-errors .errorlist {
  margin: 0;
  padding: 0;
  color: var(--danger);
  font-size: inherit;
  list-style: none;
}

.viewer-layout-settings {
  display: grid;
  gap: 18px;
}

.viewer-layout-settings-summary {
  display: grid;
  grid-template-columns: auto minmax(180px, 360px) minmax(90px, 1fr);
  align-items: center;
  gap: 18px;
  min-height: 52px;
  margin: 0;
  padding: 10px 14px;
  border: 1px solid rgba(var(--tint-rgb), 0.18);
  background: rgba(0, 0, 0, 0.2);
  color: var(--muted);
  font-family: 'Share Tech Mono', monospace;
}

.viewer-layout-settings-summary select {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  height: 36px;
  padding: 0 10px;
  border: 1px solid rgba(var(--tint-rgb), 0.34);
  outline: none;
  background: rgba(0, 0, 0, 0.4);
  color: var(--white);
  font: 12px 'Share Tech Mono', monospace;
}

.viewer-layout-settings-control {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
  min-width: 0;
}

.viewer-layout-delete-preset {
  box-sizing: border-box;
  height: 36px;
  padding: 0 12px;
  border: 1px solid rgba(var(--danger-rgb), 0.48);
  background: rgba(var(--danger-rgb), 0.07);
  color: var(--danger);
  cursor: pointer;
  font: 10px 'Share Tech Mono', monospace;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.viewer-layout-delete-preset:hover,
.viewer-layout-delete-preset:focus-visible {
  border-color: var(--danger);
  outline: none;
  box-shadow: 0 0 14px rgba(var(--danger-rgb), 0.14);
}

.viewer-layout-delete-preset:disabled {
  cursor: not-allowed;
  opacity: 0.38;
  box-shadow: none;
}

.viewer-layout-settings-summary select:focus {
  border-color: var(--cyan);
  box-shadow: 0 0 14px rgba(var(--tint-rgb), 0.14);
}

.viewer-layout-settings-summary select:disabled {
  opacity: 0.58;
}

.viewer-layout-quick-switch-status {
  min-height: 1em;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 0.6px;
  text-align: right;
}

.viewer-layout-quick-switch-status.is-error {
  color: var(--danger);
}

.viewer-layout-preset-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.viewer-layout-preset-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-height: 36px;
  padding: 0 14px;
  border: 1px solid rgba(var(--tint-rgb), 0.48);
  background: rgba(var(--tint-rgb), 0.05);
  color: var(--chrome);
  font: 10px 'Share Tech Mono', monospace;
  letter-spacing: 0.8px;
  text-decoration: none;
  text-transform: uppercase;
}

.viewer-layout-preset-action:hover,
.viewer-layout-preset-action:focus-visible {
  border-color: var(--cyan);
  outline: none;
  box-shadow: 0 0 14px rgba(var(--tint-rgb), 0.14);
}

.viewer-layout-preset-action.is-disabled {
  pointer-events: none;
  opacity: 0.38;
  box-shadow: none;
}

@media (max-width: 720px) {
  .annotation-color-settings-head {
    align-items: flex-start;
  }

  .viewer-layout-settings-summary {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .viewer-layout-quick-switch-status {
    text-align: left;
  }

  .viewer-layout-settings-control {
    grid-template-columns: minmax(0, 1fr) auto;
  }
}
.profile-setting-options-block {
  display: grid;
  grid-template-columns: minmax(150px, 210px) minmax(0, 320px);
  gap: 10px 24px;
  align-items: start;
  justify-content: start;
  width: fit-content;
  max-width: 100%;
  margin: 0;
  padding: 7px 0;
  border: 0;
  color: var(--white);
  font-family: 'Share Tech Mono', monospace;
}
.profile-setting-options-block legend {
  padding: 7px 0;
}
.profile-setting-options {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.profile-setting-options > div {
  display: contents;
}
.profile-setting-options label {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 7px 10px;
  border: 1px solid rgba(var(--tint-rgb), 0.22);
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.18);
  color: var(--white);
  font-size: inherit;
}
.profile-setting-options input[type="radio"] {
  accent-color: var(--cyan);
}
.profile-setting-options label:has(input[type="radio"]:checked) {
  border-color: var(--cyan);
  background: rgba(var(--tint-rgb), 0.12);
  box-shadow: inset 0 0 0 1px rgba(var(--tint-rgb), 0.22);
}

/* Notification preferences and inbox. */
.notification-preferences-form {
  display: grid;
  gap: 18px;
}
.notification-settings-intro {
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(var(--tint-rgb), 0.18);
}
.notification-settings-heading {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}
.notification-settings-heading .settings-group-title {
  padding: 0;
}
.notification-settings-intro p {
  margin: 7px 0 0;
  color: var(--data-secondary);
  font-family: 'Rajdhani', sans-serif;
  font-size: 1rem;
  line-height: 1.55;
}
.notification-settings-intro .notification-inbox-link,
.notification-center-toolbar a {
  color: var(--chrome);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.86rem;
  letter-spacing: 1px;
  white-space: nowrap;
}
.notification-settings-intro .notification-inbox-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid rgba(var(--tint-rgb), 0.55);
  background: rgba(var(--tint-rgb), 0.07);
  text-decoration: none;
  text-transform: uppercase;
}
.notification-settings-intro .notification-inbox-link:hover,
.notification-settings-intro .notification-inbox-link:focus-visible {
  border-color: var(--cyan);
  background: rgba(var(--tint-rgb), 0.14);
  color: var(--white);
}
.notification-topic-list {
  display: grid;
  border: 1px solid rgba(var(--tint-rgb), 0.2);
}
.notification-topic-list-header,
.notification-preference-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 220px;
  align-items: center;
  gap: 24px;
}
.notification-topic-list-header {
  min-height: 54px;
  padding: 10px 18px;
  background: rgba(var(--tint-rgb), 0.075);
  color: var(--chrome);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.78rem;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}
.notification-topic-list-header > span:last-child {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
}
.notification-topic-list-header svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}
.notification-preference-row {
  min-height: 78px;
  padding: 15px 18px;
  border-top: 1px solid rgba(var(--tint-rgb), 0.12);
  cursor: pointer;
}
.notification-preference-row:first-child {
  border-top: 0;
}
.notification-preference-row:nth-child(even) {
  background: rgba(255, 255, 255, 0.018);
}
.notification-preference-topic {
  display: grid;
  gap: 5px;
  min-width: 0;
}
.notification-preference-topic strong {
  color: var(--white);
  font-family: 'Rajdhani', sans-serif;
  font-size: 1.08rem;
  font-weight: 600;
  letter-spacing: 0.25px;
}
.notification-preference-topic span {
  color: var(--data-secondary);
  font-family: 'Rajdhani', sans-serif;
  font-size: 0.98rem;
  line-height: 1.45;
}
.notification-website-choice {
  display: flex;
  align-items: center;
  justify-content: center;
}
.notification-website-choice input,
.notification-sound-setting input {
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--cyan);
}
.notification-sound-setting {
  border: 1px solid rgba(var(--tint-rgb), 0.2);
  background: rgba(var(--tint-rgb), 0.035);
  padding: 17px 18px;
}
.notification-sound-setting label {
  display: flex;
  align-items: center;
  gap: 13px;
  cursor: pointer;
}
.notification-sound-setting span {
  display: grid;
  gap: 3px;
}
.notification-sound-setting strong {
  color: var(--white);
  font-family: 'Rajdhani', sans-serif;
  font-size: 1.04rem;
  font-weight: 600;
}
.notification-sound-setting small {
  color: var(--data-secondary);
  font-family: 'Rajdhani', sans-serif;
  font-size: 0.95rem;
  line-height: 1.45;
}
.notification-secondary-button,
.notification-center-toolbar button,
.notification-center-item form button {
  border: 1px solid rgba(var(--tint-rgb), 0.35);
  background: transparent;
  color: var(--chrome);
  padding: 9px 12px;
  font-family: 'Share Tech Mono', monospace;
  cursor: pointer;
}
.notification-center {
  max-width: 860px;
  margin: 0 auto 50px;
}
.notification-center-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 15px;
  margin-bottom: 14px;
}
.notification-center-toolbar form {
  margin: 0;
}
.notification-center-list {
  display: grid;
  gap: 9px;
}
.notification-center-item {
  display: grid;
  grid-template-columns: 1fr auto;
  border: 1px solid rgba(var(--tint-rgb), 0.2);
  background: rgba(var(--ink-rgb), 0.78);
}
.notification-center-item.is-unread {
  border-left: 4px solid var(--amber);
  background: rgba(255, 184, 0, 0.045);
}
.notification-center-item > a {
  display: grid;
  gap: 5px;
  padding: 16px 18px;
  color: inherit;
  text-decoration: none;
}
.notification-center-item strong {
  color: var(--white);
  font-family: 'Orbitron', sans-serif;
  font-size: 0.85rem;
  letter-spacing: 0.8px;
}
.notification-center-item p {
  margin: 0;
  color: var(--muted);
  font-family: 'Share Tech Mono', monospace;
  line-height: 1.45;
}
.notification-center-item time,
.notification-topic {
  color: var(--chrome);
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.66rem;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.notification-center-item form {
  margin: 0;
  padding: 12px;
}
.notification-center-item form button {
  width: 32px;
  height: 32px;
  padding: 0;
  font-size: 1rem;
}
.notification-center-item form button svg {
  width: 16px;
  height: 16px;
}
.notification-empty {
  display: grid;
  place-items: center;
  gap: 8px;
  padding: 46px 20px;
  border: 1px dashed rgba(var(--tint-rgb), 0.28);
  color: var(--muted);
  text-align: center;
}
.notification-empty > span {
  color: var(--chrome);
  font-size: 2rem;
}
.notification-empty strong {
  color: var(--white);
  font-family: 'Orbitron', sans-serif;
}
.notification-empty p {
  max-width: 520px;
  margin: 0;
  font-family: 'Share Tech Mono', monospace;
  line-height: 1.5;
}

@media (max-width: 720px) {
  .notification-topic-list-header,
  .notification-preference-row {
    grid-template-columns: minmax(0, 1fr) 56px;
    gap: 12px;
  }
  .notification-topic-list-header {
    min-height: 46px;
    padding: 9px 14px;
  }
  .notification-topic-list-header > span:first-child {
    visibility: hidden;
  }
  .notification-topic-list-header > span:last-child {
    font-size: 0;
  }
  .notification-topic-list-header svg {
    width: 24px;
    height: 24px;
  }
  .notification-preference-row {
    align-items: center;
    min-height: 0;
    padding: 16px;
  }
  .notification-website-choice {
    width: auto;
  }
  .notification-center-toolbar {
    align-items: stretch;
    flex-direction: column;
  }
}

/* Move narration follows the same unboxed group and row grammar as Appearance. */
.speech-settings {
  display: grid;
  gap: 8px;
}
.speech-speed-control {
  display: flex;
  align-items: center;
  gap: 12px;
}
.speech-speed-value {
  color: var(--chrome);
  font-size: 0.9rem;
  min-width: 34px;
  text-align: right;
}
.speech-level-range {
  -webkit-appearance: none;
  appearance: none;
  width: 180px;
  max-width: 50vw;
  height: 4px;
  background: rgba(var(--tint-rgb), 0.2);
  border-radius: 2px;
  outline: none;
}
.speech-level-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 8px var(--cyan-glow);
  cursor: pointer;
  border: none;
}
.speech-level-range::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 8px var(--cyan-glow);
  cursor: pointer;
  border: none;
}
.speech-level-range::-moz-range-track {
  height: 4px;
  background: rgba(var(--tint-rgb), 0.2);
  border-radius: 2px;
}
.speech-voice-control {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.speech-voice-select {
  width: min(280px, 100%);
  max-width: 100%;
  flex: 1 1 210px;
  min-width: 0;
  border: 1px solid rgba(var(--tint-rgb), 0.32);
  background: rgba(0, 0, 0, 0.32);
  color: var(--chrome);
  padding: 8px 10px;
}
.speech-voice-select:disabled {
  opacity: 0.5;
}
.speech-test-btn {
  min-height: 34px;
  white-space: nowrap;
}
.speech-test-btn:active {
  transform: translateY(1px);
}
.speech-test-btn:disabled {
  opacity: 0.5;
  cursor: default;
}
.speech-voice-hint {
  margin: 0;
  max-width: 560px;
}

.settings-actions {
  align-items: center;
  gap: 12px;
}
.settings-save-status {
  margin-right: auto;
}
.settings-actions [data-settings-submit]:disabled {
  cursor: default;
  opacity: 0.52;
  box-shadow: none;
}

@media (max-width: 720px) {
  .device-session-item {
    align-items: start;
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .device-session-meta {
    grid-column: 1 / -1;
    grid-template-columns: 1fr;
  }
  .device-session-action {
    grid-column: 2;
    grid-row: 1;
  }
  .appearance-settings-form .profile-setting-row,
  .appearance-settings-form .profile-setting-options-block {
    grid-template-columns: minmax(0, 1fr);
  }
  .appearance-settings-form .annotation-color-buttons {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .appearance-settings-form .annotation-color-settings-head .settings-reset-control {
    position: static;
    transform: none;
  }
  .appearance-settings-form .annotation-color-settings-head {
    gap: 10px;
    justify-items: center;
  }
  .profile-setting-row,
  .profile-setting-options-block {
    grid-template-columns: minmax(0, 1fr);
    gap: 7px;
    width: 100%;
  }
  .profile-setting-row select,
  .speech-voice-select {
    width: 100%;
  }
  .speech-voice-select {
    flex: 0 0 auto;
  }
  .speech-voice-control {
    align-items: stretch;
    flex-direction: column;
  }
  .speech-test-btn {
    align-self: flex-start;
  }
}

/* OTB game management + public collection visibility */
.otb-pgn-input {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
  border: 1px solid rgba(var(--tint-rgb), 0.32);
  border-radius: 0;
  background: rgba(0, 0, 0, 0.32);
  color: var(--white);
  padding: 12px;
  margin-bottom: 14px;
  font-family: 'Share Tech Mono', monospace;
  font-size: 0.88rem;
  line-height: 1.5;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
  resize: vertical;
  outline: none;
  color-scheme: dark;
}
.otb-pgn-input:focus {
  border-color: var(--cyan);
  box-shadow: 0 0 18px rgba(var(--tint-rgb), 0.12);
}
.collection-visibility-form {
  margin: 0;
}
.collection-visibility-form button {
  border: 1px solid var(--tint);
  background: rgba(var(--tint-rgb), 0.08);
  color: var(--chrome);
  padding: 10px 14px;
  font-family: 'Share Tech Mono', monospace;
  letter-spacing: 1px;
  cursor: pointer;
}
.collection-visibility-form button:hover {
  color: var(--white);
  border-color: var(--cyan);
}
.collection-visibility-note {
  color: var(--muted);
  font-size: 0.72rem;
  letter-spacing: 0.5px;
  margin: -12px 0 24px;
}
.collection-visibility-note a {
  color: var(--cyan);
}

/* Starred players carry a face. A name alone makes the list read as a column of
   strings; the portrait is how you pick one out at a glance. This is the one
   library change that belongs at every width, so it sits outside the phone
   block. The row keeps `.profile-row`'s grid and re-splits it into portrait +
   text, so the swipe treatment below still applies unchanged. */
.starred-player-row {
  grid-template-columns: 44px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
}
.starred-player-portrait {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid rgba(var(--tint-rgb), 0.24);
  border-radius: 50%;
  background: rgba(var(--tint-rgb), 0.06);
  color: var(--chrome);
  font-size: 1.1rem;
  line-height: 1;
}
.starred-player-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Portraits are framed head-and-shoulders; centre crops the chin off. */
  object-position: center top;
  display: block;
}
.starred-player-text {
  display: grid;
  gap: 4px;
  min-width: 0;
}

/* Phone layout for the shared library row (.collection-game-row drives imported
   games, starred games/players, and collection detail). The desktop row is a
   link beside a destructive button held to equal height; on a phone that button
   is a slab as tall as the row and a quarter of it wide, and the listing gets
   whatever is left. The phone answer is the native app's swipe row: the link
   covers the full width and drags left to reveal the delete panel parked off
   the right edge. `library-swipe.ts` drives it and mirrors SwipeRow.kt --
   96px reveal, half-open snap, one row open at a time. The panel is the same
   <form> the desktop uses, so the POST, the CSRF token and the data-confirm
   handler are unchanged, and it stays keyboard-reachable: focus inside that
   form opens the reveal for anyone who tabs to it rather than swiping. */
@media (max-width: 720px) {
  .collection-game-row {
    position: relative;
    display: block;
    overflow: hidden;
  }
  .collection-game-row .profile-row {
    position: relative;
    z-index: 1;
    padding: 14px;
    gap: 5px;
    /* Vertical scrolling stays with the page; horizontal is ours to read. */
    touch-action: pan-y;
    transition: transform 160ms ease;
  }
  /* Six columns do not fit a phone, and a sideways-scrolling listing fights
     the swipe that deletes a row. So the columns become a paragraph: the
     pairing takes the first line with its result, and the rest of the game
     wraps under it as a run of values. Nothing is dropped — a phone reader
     gets the same date, move count, opening and provenance a desktop reader
     does, in the order that matters when there is one column to spend. */
  .library-games-head {
    display: none;
  }
  .collection-game-row .profile-row.library-game-cells {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 5px 14px;
    /* Restated because the desktop rule that sets the grid is one class more
       specific than the phone row's own padding, so it would otherwise win
       here and inset the row by 4px inside a 14px list. */
    padding: 14px;
  }
  .library-game-cell-players {
    flex: 1 1 auto;
    order: 1;
    white-space: normal;
  }
  .library-game-cell-result { order: 2; }
  /* The first value of the second line claims the whole width, which is what
     breaks the line after the pairing without a wrapper element to do it. */
  .library-game-cell-date { order: 3; flex: 1 0 100%; }
  .library-game-cell-moves { order: 4; text-align: left; }
  .library-game-cell-tail { order: 5; }
  .library-game-cell-opening { order: 6; flex: 1 1 100%; }
  .library-game-unit { display: inline; }

  /* Row forms only. `.collection-delete-form` is also the collection's own
     Delete Collection form in the editor card, and parking that off the right
     edge loses the control entirely and leaves a hole where it sat. */
  .collection-game-row form {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 96px;
    margin: 0;
    display: block;
    transform: translateX(96px);
    transition: transform 160ms ease;
  }
  /* Revealed, the control is a panel rather than the desktop icon: it is the
     full height of the row and the finger has to land on it deliberately. */
  .collection-game-row form button {
    width: 100%;
    min-width: 0;
    height: 100%;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 0;
    background: var(--danger);
    color: #ffffff;
  }
  .collection-game-row form button svg {
    width: 22px;
    height: 22px;
  }
  .collection-game-row form button:hover {
    color: #ffffff;
    border-color: transparent;
    filter: brightness(1.12);
  }
  /* Un-starring is not destructive, so its panel is the gold the star wears
     rather than the delete red. Two intents, two colours — the same split the
     desktop row draws with the icon alone. */
  .bookmark-remove-form button {
    min-width: 0;
    height: 100%;
    background: var(--gold);
    color: #14161a;
  }
  /* Focus opens the reveal only for focus inside the form. `:focus-within` on
     the row matches the row's own link too, so tapping a game -- which focuses
     that link -- slid the delete panel out from under the finger before the
     game opened. Tapping a game and revealing its delete are opposite intents
     and a tap must only ever do the first. */
  .collection-game-row.is-swiped .profile-row,
  .collection-game-row:has(form:focus-within) .profile-row {
    transform: translateX(-96px);
  }
  .collection-game-row.is-swiped form,
  .collection-game-row form:focus-within {
    transform: translateX(0);
  }
  /* While a finger is down the row tracks it directly; a transition here would
     lag the drag behind the thumb. */
  .collection-game-row.is-dragging .profile-row,
  .collection-game-row.is-dragging form {
    transition: none;
  }

  /* The rename input shares its row with the Rename button, which on a phone
     leaves it too narrow to show the collection's own name -- it truncated
     mid-word. The editor becomes one stack: name, rename, then the
     destructive action, each at the touch floor. Scoped to the editor panel
     because `.collection-form` is also the create-collection popover, which
     sizes itself against its own panel. */
  .collection-edit-body .collection-form {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
    margin-bottom: 0;
  }
  .collection-edit-body .collection-form input {
    min-height: 44px;
    font-size: 16px;
  }
  .collection-edit-body .collection-form button,
  .collection-edit-body .collection-delete-form button {
    width: 100%;
    min-height: 44px;
    padding: 0 16px;
    font-size: 0.78rem;
    letter-spacing: 1.5px;
  }

  /* Six sort options are still six words on a phone, not six boxes: one line
     that scrolls sideways if it has to. Laid out as a 2×3 grid of outlined
     rectangles they took a third of the screen before the first result, which
     is the wall this rebuild exists to remove. */
  .collection-sort {
    flex-wrap: nowrap;
    gap: 20px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .collection-sort::-webkit-scrollbar {
    display: none;
  }
  .collection-sort a {
    display: flex;
    align-items: center;
    min-height: 40px;
    padding: 0;
    text-align: left;
  }

  /* Every library section leads with its own name; centring the block puts the
     title on the page's axis and gives its action a deliberate place under it
     instead of hanging off to one side above the toolbar. */
  .account-shell-page .account-content-head {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 12px;
  }
  .account-shell-page .account-content-lead {
    flex: 0 1 auto;
  }

  /* The search button is the loudest element on the page at this width: full
     Orbitron at 2px tracking with a glow, next to a 14px input that iOS zooms
     the whole page to focus. */
  .imported-game-search {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px;
    align-items: stretch;
  }
  .imported-game-search input {
    min-height: 44px;
    padding: 10px 12px;
    font-size: 16px;
  }
  .imported-game-search button {
    min-height: 44px;
    padding: 0 14px;
    font-size: 0.72rem;
    letter-spacing: 1px;
    box-shadow: none;
  }
}

.account-confirm-dialog {
  position: fixed;
  inset: 0;
  z-index: 1400;
  display: grid;
  place-items: center;
  background: rgba(var(--ink-rgb), 0.68);
}

.account-confirm-dialog[hidden] {
  display: none;
}

.account-confirm-dialog-box {
  box-sizing: border-box;
  width: min(360px, calc(100vw - 48px));
  padding: 16px 18px 18px;
  border: 1px solid rgba(var(--tint-rgb), 0.5);
  background: rgba(var(--ink-rgb), 0.98);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.6), 0 0 24px rgba(var(--tint-rgb), 0.12);
}

.account-confirm-dialog-box h2 {
  margin: 0 0 12px;
  color: var(--chrome);
  font: 12px 'Orbitron', sans-serif;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}

.account-confirm-dialog-box p {
  margin: 0 0 14px;
  color: var(--muted);
  font: 12px 'Share Tech Mono', monospace;
  letter-spacing: 0.4px;
  overflow-wrap: anywhere;
}

.account-confirm-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.account-confirm-dialog-button {
  box-sizing: border-box;
  height: 32px;
  padding: 0 14px;
  border: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.42);
  color: var(--chrome);
  cursor: pointer;
  font: 10px 'Share Tech Mono', monospace;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.account-confirm-dialog-button:hover,
.account-confirm-dialog-button:focus-visible {
  border-color: var(--cyan);
  outline: none;
  box-shadow: 0 0 14px rgba(var(--tint-rgb), 0.16);
}

.account-confirm-dialog-danger {
  border-color: rgba(var(--danger-rgb), 0.48);
  background: rgba(var(--danger-rgb), 0.07);
  color: var(--danger);
}

.account-confirm-dialog-danger:hover,
.account-confirm-dialog-danger:focus-visible {
  border-color: var(--danger);
  box-shadow: 0 0 14px rgba(var(--danger-rgb), 0.14);
}
