/* ===========================================================================
   Squadli UI layer — design tokens + component styles.
   Loaded AFTER adminlte.min.css so it wins without !important where possible.
   Dark mode piggybacks on AdminLTE's existing `body.dark-mode` class, so the
   built-in toggle keeps working untouched.
   =========================================================================== */

:root {
  /* Brand */
  --sq-primary:        #6366F1;
  --sq-primary-600:    #4F46E5;
  --sq-primary-050:    #EEF2FF;
  --sq-accent:         #059669;
  --sq-accent-050:     #ECFDF5;

  /* Surfaces — low-chroma neutrals. A saturated tint across a full-screen
     background is fatiguing over a long session; these keep the hue cue while
     dropping most of the chroma. */
  --sq-bg:             #F4F6F8;
  --sq-card:           #FFFFFF;
  --sq-border:         #E3E8EF;
  --sq-muted:          #F1F4F8;   /* subtle fill: hovers, modal footer, chips */

  /* Text */
  --sq-fg:             #1B2333;
  --sq-muted-fg:       #5A6678;

  /* Status */
  --sq-danger:         #DC2626;
  --sq-warning:        #B45309;
  --sq-ring:           #6366F1;

  /* Dense dashboard spacing scale */
  --sq-space-1: 8px;  --sq-space-2: 12px; --sq-space-3: 16px;
  --sq-space-4: 24px; --sq-space-5: 32px;

  --sq-chrome-h: calc(3.5rem + 1px);
  --sq-radius: 10px;
  --sq-shadow: 0 1px 2px rgba(16,24,40,.06), 0 1px 3px rgba(16,24,40,.10);
  --sq-shadow-lg: 0 4px 6px -2px rgba(16,24,40,.05), 0 12px 16px -4px rgba(16,24,40,.10);
  --sq-transition: 160ms cubic-bezier(.4,0,.2,1);
}

body.dark-mode {
  /* Neutral dark rather than deep navy: less blue cast, and surfaces lifted off
     pure black to reduce halation around light text. */
  --sq-bg:        #16181D;
  --sq-card:      #1F2228;
  --sq-border:    #31363F;
  --sq-muted:     #272B33;
  --sq-fg:        #E6E8EC;
  --sq-muted-fg:  #9BA3AF;
  --sq-warning:   #F59E0B;   /* the light-mode amber drops under 3:1 on dark surfaces */
  --sq-primary-050: #312E81;
  --sq-accent-050:  #064E3B;
  --sq-shadow:    0 1px 2px rgba(0,0,0,.4);
  --sq-shadow-lg: 0 12px 16px -4px rgba(0,0,0,.5);
}

/* --- Focus: never remove, always visible (WCAG 2.2) ---------------------- */
.sq-scope a:focus-visible,
.sq-scope button:focus-visible,
.sq-scope input:focus-visible,
.sq-scope select:focus-visible,
.sq-scope textarea:focus-visible,
.sq-stat:focus-visible {
  outline: 2px solid var(--sq-ring);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ===========================  STAT TILES  ================================ */
/* Replaces the 7 unrelated saturated fills. One neutral card; colour is
   carried by a small icon chip and used semantically, not decoratively.     */

.sq-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--sq-space-2);
}
/* Default auto-fit suits a handful of tiles that fit one row. A page whose
   count would strand an orphan (seven tiles land 6 + 1) opts into a fixed
   column count instead, so the last row reads as deliberate. */
.sq-stat-grid { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
@media (min-width: 1100px) {
  .sq-stat-grid--4 { grid-template-columns: repeat(4, 1fr); }
}

.sq-stat {
  display: flex;
  align-items: center;
  gap: var(--sq-space-2);
  padding: var(--sq-space-3);
  background: var(--sq-card);
  border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius);
  box-shadow: var(--sq-shadow);
  transition: box-shadow var(--sq-transition), transform var(--sq-transition);
  min-height: 88px;
}
a.sq-stat { text-decoration: none; cursor: pointer; }
a.sq-stat:hover { box-shadow: var(--sq-shadow-lg); transform: translateY(-1px); }

.sq-stat__chip {
  flex: 0 0 auto;
  width: 44px; height: 44px;              /* 44px min touch target */
  display: grid; place-items: center;
  border-radius: 10px;
  background: var(--sq-primary-050);
  color: var(--sq-primary-600);
  font-size: 20px; line-height: 1;
}
.sq-stat__body { min-width: 0; }

/* Value dominates the label — the old cards had this inverted. */
.sq-stat__value {
  font-size: 30px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--sq-fg);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
.sq-stat__label {
  font-size: 13px;
  font-weight: 500;
  color: var(--sq-muted-fg);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Semantic variants — meaning, not decoration */
.sq-stat--accent  .sq-stat__chip { background: var(--sq-accent-050);  color: var(--sq-accent); }
.sq-stat--muted   .sq-stat__chip { background: var(--sq-border);      color: var(--sq-muted-fg); }

/* ===========================  CARDS  ===================================== */
.sq-card {
  background: var(--sq-card);
  border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius);
  box-shadow: var(--sq-shadow);
  overflow: hidden;
}
.sq-card__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sq-space-2);
  padding: var(--sq-space-2) var(--sq-space-3);
  border-bottom: 1px solid var(--sq-border);
}
.sq-card__title {
  margin: 0; font-size: 15px; font-weight: 600; color: var(--sq-fg);
}
.sq-card__body { padding: var(--sq-space-3); }

/* ===========================  TOOLBAR  =================================== */
/* The old filter row was a tall empty bar with one floated select. */
.sq-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sq-space-2);
  margin-bottom: var(--sq-space-3);
}
.sq-toolbar__spacer { flex: 1 1 auto; }
.sq-toolbar label { margin: 0; font-size: 13px; color: var(--sq-muted-fg); font-weight: 500; }
.sq-toolbar select.form-control {
  width: auto; min-width: 170px; min-height: 44px;
  border-radius: 8px; border-color: var(--sq-border);
  color: var(--sq-fg); background-color: var(--sq-card);
}

/* Page title */
.sq-page-title {
  font-size: 22px; font-weight: 700; color: var(--sq-fg);
  margin: 0; letter-spacing: -.01em;
}

@media (prefers-reduced-motion: reduce) {
  .sq-stat, a.sq-stat:hover { transition: none; transform: none; }
}

/* ===========================  SIDEBAR NAV  ===============================
   The sidebar stays dark in both themes (deliberate: it reads as chrome, not
   content, and keeps the brand anchor stable when the user flips dark mode).
   ======================================================================== */

.main-sidebar.sidebar-dark-primary { background: #131A2B; }
body.dark-mode .main-sidebar.sidebar-dark-primary { background: #0B1120; }

/* Brand row and the navbar are one continuous band across the top, so they
   share an explicit height instead of each falling out of its own padding. */
.main-header.navbar { min-height: var(--sq-chrome-h); padding: 0 12px; }
.main-sidebar .brand-link {
  display: flex; align-items: center; gap: 10px;
  min-height: var(--sq-chrome-h);
  padding: 0 16px;
  /* AdminLTE repaints this #343a40 under every layout-*-navbar-fixed variant
     at 4-5 class specificity, which is what made the logo band a different
     grey from the sidebar under it. !important is the only sane answer. */
  background-color: transparent !important;
  border-bottom: 1px solid rgba(148,163,184,.14);
  transition: background var(--sq-transition);
}
.main-sidebar .brand-link:hover { background: rgba(148,163,184,.08); }
.main-sidebar .brand-link .brand-image-sq {
  width: 32px; height: 32px; flex: 0 0 auto;
  border-radius: 8px; object-fit: contain;
}
.main-sidebar .brand-link .brand-text {
  font-weight: 600; font-size: 18px; letter-spacing: -.01em; color: #F1F5F9;
  margin: 0;
}

/* User panel: avatar, name and role read as one block. */
.main-sidebar .user-panel {
  align-items: center; gap: 10px;
  padding: 0 16px 14px !important;
  border-bottom: 1px solid rgba(148,163,184,.14);
}
.main-sidebar .user-panel .image { padding: 0; }
.main-sidebar .user-panel .info { padding: 0; line-height: 1.25; }
/* Over-qualified on purpose: AdminLTE ships `.user-panel img{height:auto;
   width:2.1rem}`, which out-specifies a lone `.sq-avatar`. With height:auto a
   portrait photo stays taller than it is wide, and border-radius:50% then draws
   an ellipse rather than a circle. Equal width and height plus object-fit make
   the frame square and crop the photo into it. */
.main-sidebar .user-panel .sq-avatar,
.sq-avatar {
  width: 36px; height: 36px; object-fit: cover; object-position: center;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(148,163,184,.28);
  transition: box-shadow var(--sq-transition);
}
.main-sidebar .user-panel a:hover .sq-avatar { box-shadow: 0 0 0 2px var(--sq-primary); }
.main-sidebar .user-panel .info a {
  color: #E2E8F0; font-weight: 600; font-size: 14px; letter-spacing: -.01em;
}
.main-sidebar .user-panel .info a:hover { color: #fff; }
.sq-userpanel__role {
  display: block; font-size: 11px; font-weight: 500;
  letter-spacing: .04em; text-transform: uppercase; color: #8E9BB0;
}

/* ==========================  HEADER ICON BUTTONS  ======================== */
/* The hamburger was a bare <i> with no hit target, and dark mode was a
   Bootstrap switch whose label ate a third of the bar. Both are now the same
   40px square control. */
.sq-chrome-btn {
  display: inline-grid; place-items: center;
  width: 40px; height: 40px; padding: 0;
  border: 1px solid transparent; border-radius: 9px;
  background: transparent; color: var(--sq-muted-fg);
  font-size: 16px; line-height: 1; cursor: pointer; text-decoration: none;
  transition: background var(--sq-transition), color var(--sq-transition),
              border-color var(--sq-transition);
}
.sq-chrome-btn:hover,
.sq-chrome-btn:focus { background: var(--sq-muted); color: var(--sq-fg); text-decoration: none; }
.sq-chrome-btn:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
.sq-chrome-btn--danger:hover { color: var(--sq-danger); }
/* The sun/moon swaps on click; a short rotation makes the swap legible. */
.sq-chrome-btn[aria-pressed] i { transition: transform 220ms cubic-bezier(.2,.9,.3,1); }
.sq-chrome-btn[aria-pressed]:hover i { transform: rotate(-18deg); }
.sq-chrome-actions { display: flex; align-items: center; gap: 4px; }
@media (prefers-reduced-motion: reduce) {
  .sq-chrome-btn i, .main-sidebar .brand-link { transition: none; }
}

/* Section headings give 10 flat links a scannable structure. */
.sq-nav__section {
  margin: 18px 0 6px;
  padding: 0 16px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #8E9BB0;   /* lifted from #64748B: that was 3.96:1 on the sidebar, below the 4.5:1 minimum */
}
.sq-nav__section:first-child { margin-top: 8px; }

.nav-sidebar .nav-item { margin: 0 8px 2px; }

.nav-sidebar .nav-link {
  display: flex; align-items: center; gap: 12px;
  min-height: 42px;                       /* comfortable pointer + touch target */
  padding: 8px 12px;
  border-radius: 8px;
  color: #94A3B8;
  font-size: 14px; font-weight: 500;
  position: relative;
  transition: background var(--sq-transition), color var(--sq-transition);
}
.nav-sidebar .nav-link .nav-icon {
  width: 18px; font-size: 15px; text-align: center; flex: 0 0 auto; margin: 0;
}
.nav-sidebar .nav-link p { margin: 0; }

.nav-sidebar .nav-link:hover { background: rgba(148,163,184,.10); color: #E2E8F0; }

/* Active: tint + a left accent bar, so state is not carried by colour alone. */
.nav-sidebar .nav-link.active,
.nav-sidebar .nav-link[aria-current="page"] {
  background: rgba(99,102,241,.16);
  color: #fff;
  font-weight: 600;
}
.nav-sidebar .nav-link.active::before,
.nav-sidebar .nav-link[aria-current="page"]::before {
  content: "";
  position: absolute; left: -8px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 22px; border-radius: 0 3px 3px 0;
  background: var(--sq-primary);
}
.nav-sidebar .nav-link.active .nav-icon { color: #A5B4FC; }

.nav-sidebar .nav-link:focus-visible {
  outline: 2px solid #A5B4FC; outline-offset: -2px;
}

/* Not-yet-built destinations: shown, but honestly marked and non-clickable
   rather than looking live and going nowhere. */
.nav-sidebar .nav-link.is-disabled {
  opacity: .45; cursor: not-allowed; pointer-events: none;
}
.sq-nav__soon {
  margin-left: auto;
  font-size: 10px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase;
  padding: 2px 6px; border-radius: 999px;
  background: rgba(148,163,184,.18); color: #CBD5E1;
}

/* Collapsed (sidebar-mini) state: hide section labels and badges. */
.sidebar-collapse .sq-nav__section,
.sidebar-collapse .sq-nav__soon { display: none; }

/* Skip link — keyboard users shouldn't tab the whole nav to reach content. */
.sq-skip {
  position: absolute; left: -9999px; top: 0; z-index: 2000;
  background: var(--sq-primary-600); color: #fff;
  padding: 10px 16px; border-radius: 0 0 8px 0; font-weight: 600;
}
.sq-skip:focus { left: 0; color: #fff; }

/* ===========================  CHART EMPTY STATE  ========================= */
.sq-chart { position: relative; min-height: 200px; }
.sq-chart__empty {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  margin: 0; padding: 0 16px;
  text-align: center;
  color: var(--sq-muted-fg);
  font-size: 14px;
}

/* ===========================  DATA TABLE  ================================ */
.sq-table-card { background: var(--sq-card); border: 1px solid var(--sq-border);
                 border-radius: var(--sq-radius); box-shadow: var(--sq-shadow); overflow: hidden; }

.sq-table-head {
  display: flex; align-items: center; gap: var(--sq-space-2); flex-wrap: wrap;
  padding: var(--sq-space-3); border-bottom: 1px solid var(--sq-border);
}
.sq-table-head h2 { margin: 0; font-size: 16px; font-weight: 600; color: var(--sq-fg); }
.sq-count {
  font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 999px;
  background: var(--sq-primary-050); color: var(--sq-primary-600);
}

/* Search */
.sq-search { position: relative; margin-left: auto; }
.sq-search input {
  width: 260px; max-width: 100%; min-height: 40px;
  padding: 8px 34px 8px 36px;
  font: inherit; font-size: 14px;
  color: var(--sq-fg); background: var(--sq-card);
  border: 1px solid var(--sq-border); border-radius: 8px;
}
.sq-search input::placeholder { color: var(--sq-muted-fg); }
.sq-search input:focus { outline: none; border-color: var(--sq-primary);
                         box-shadow: 0 0 0 3px rgba(99,102,241,.25); }
.sq-search__icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
                   color: var(--sq-muted-fg); pointer-events: none; font-size: 13px; }
.sq-search__clear { position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
                    color: var(--sq-muted-fg); text-decoration: none; font-size: 15px; line-height: 1;
                    width: 22px; height: 22px; display: grid; place-items: center; border-radius: 4px; }
.sq-search__clear:hover { background: var(--sq-muted); color: var(--sq-fg); }

/* Table */
/* The wrap must be width-constrained or it shrink-to-fits the table and the
   whole page scrolls sideways instead of just the table. */
.sq-table-wrap { overflow-x: auto; width: 100%; max-width: 100%; min-width: 0;
                 -webkit-overflow-scrolling: touch; }
.sq-table { width: 100%; min-width: 720px; border-collapse: collapse; font-size: 14px; }
.sq-table thead th {
  background: var(--sq-muted);
  padding: 10px var(--sq-space-3);
  text-align: left; white-space: nowrap;
  font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--sq-muted-fg);
  border-bottom: 1px solid var(--sq-border);
}
.sq-table tbody td { padding: 10px var(--sq-space-3); border-bottom: 1px solid var(--sq-border);
                     color: var(--sq-fg); vertical-align: middle; }
.sq-table tbody tr:last-child td { border-bottom: 0; }
.sq-table tbody tr { transition: background var(--sq-transition); }
.sq-table tbody tr:hover { background: var(--sq-primary-050); }

/* Identity cell: avatar + name + email in one column instead of three */
.sq-person { display: flex; align-items: center; gap: 10px; min-width: 0; }
.sq-person img {
  width: 36px; height: 36px; border-radius: 50%; object-fit: cover; flex: 0 0 auto;
  background: var(--sq-muted); border: 1px solid var(--sq-border);
}
.sq-person__name { font-weight: 600; color: var(--sq-fg); line-height: 1.25;
                   white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sq-person__sub  { font-size: 12.5px; color: var(--sq-muted-fg); line-height: 1.25;
                   white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Badges */
.sq-badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .02em;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
  border: 1px solid transparent;
}
.sq-badge--paid    { background: var(--sq-accent-050);  color: #047857; border-color: #A7F3D0; }
.sq-badge--free    { background: var(--sq-muted);       color: var(--sq-muted-fg); border-color: var(--sq-border); }
.sq-badge--leader  { background: var(--sq-primary-050); color: var(--sq-primary-600); border-color: #C7D2FE; }
.sq-badge--pending { background: #FEF3C7; color: #92400E; border-color: #FDE68A; }
body.dark-mode .sq-badge--paid    { background: #064E3B; color: #6EE7B7; border-color: #065F46; }
body.dark-mode .sq-badge--pending { background: #78350F; color: #FCD34D; border-color: #92400E; }
body.dark-mode .sq-badge--leader  { background: #312E81; color: #A5B4FC; border-color: #3730A3; }

/* Row actions: destructive styled as quiet-until-hover, not a permanent red slab */
.sq-actions { display: flex; gap: 6px; justify-content: flex-end; }
.sq-iconbtn {
  display: inline-grid; place-items: center;
  width: 34px; height: 34px; border-radius: 8px;
  border: 1px solid var(--sq-border); background: var(--sq-card);
  color: var(--sq-muted-fg); font-size: 13px; cursor: pointer;
  transition: all var(--sq-transition); text-decoration: none;
}
.sq-iconbtn:hover { background: var(--sq-muted); color: var(--sq-fg); }
.sq-iconbtn--danger:hover { background: #FEF2F2; border-color: #FECACA; color: var(--sq-danger); }
body.dark-mode .sq-iconbtn--danger:hover { background: #450A0A; border-color: #7F1D1D; color: #FCA5A5; }
.sq-iconbtn:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; }

.sq-table select.form-control { min-height: 38px; min-width: 168px; border-radius: 8px;
                                border-color: var(--sq-border); font-size: 13.5px;
                                color: var(--sq-fg); background-color: var(--sq-card); }

/* Empty state */
.sq-empty { padding: 48px 24px; text-align: center; color: var(--sq-muted-fg); }
.sq-empty__icon { font-size: 26px; opacity: .5; margin-bottom: 10px; }
.sq-empty__title { font-size: 15px; font-weight: 600; color: var(--sq-fg); margin-bottom: 4px; }
.sq-empty p { font-size: 14px; margin: 0 auto; max-width: 42ch; }
.sq-empty .btn, .sq-empty .link { margin-top: var(--sq-space-3); }
.sq-empty .link { display: inline-block; color: var(--sq-primary); font-weight: 500; }
.sq-empty .link:hover { color: var(--sq-primary-600); text-decoration: underline; }
.sq-empty p .link { margin-top: 0; }

.sq-table-foot { display: flex; align-items: center; justify-content: space-between;
                 gap: var(--sq-space-2); flex-wrap: wrap;
                 padding: var(--sq-space-2) var(--sq-space-3); border-top: 1px solid var(--sq-border); }
.sq-table-foot .pagination { margin: 0; }

@media (max-width: 640px) {
  .sq-search input { width: 100%; }
  .sq-search { margin-left: 0; width: 100%; }
}

/* Allow the table wrapper to actually shrink inside AdminLTE's layout so a wide
   table scrolls in its own .sq-table-wrap box rather than dragging the whole
   page sideways.

   Deliberately NOT `overflow-x: hidden` here: overflow-x:hidden computes
   overflow-y to `auto`, which makes .content-wrapper the nearest scroll
   container for `position: sticky`. Since it never actually scrolls, every
   sticky descendant silently stopped sticking. min-width/max-width below do
   the containment job without that side effect. */
.content-wrapper, .content-wrapper .content, .content-wrapper .container-fluid { min-width: 0; max-width: 100%; }
.sq-table-card { min-width: 0; }

/* Sticky header only where there is vertical room for it to help. Inside a
   horizontally-scrolling wrapper on small screens it escapes the clip and
   widens the page. */
@media (min-width: 992px) {
  .sq-table thead th { position: sticky; top: 0; z-index: 1; }
}

/* Below the sidebar breakpoint, stop the document itself from scrolling
   sideways. The wide table keeps its own horizontal scroll inside
   .sq-table-wrap; this only prevents the whole page from dragging with it.
   Scoped to small screens so desktop overlays/tooltips are unaffected. */
@media (max-width: 991.98px) {
  html, body { overflow-x: hidden; max-width: 100%; }
}

/* ===========================  SELECT CONTROL  ===========================
   Native selects render differently per-OS and looked unfinished next to the
   rest of the UI. Strip the native chrome and draw our own chevron.
   ======================================================================== */
.sq-select { position: relative; display: inline-flex; align-items: center; }
.sq-select select,
.sq-table select.form-control,
.sq-toolbar select.form-control {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-image: none;                 /* kill Bootstrap's baked-in caret */
  padding: 8px 34px 8px 12px;
  min-height: 40px;
  font: inherit; font-size: 14px; font-weight: 500;
  color: var(--sq-fg); background-color: var(--sq-card);
  border: 1px solid var(--sq-border); border-radius: 8px;
  cursor: pointer;
  transition: border-color var(--sq-transition), box-shadow var(--sq-transition);
}
.sq-select select:hover,
.sq-table select.form-control:hover { border-color: #94A3B8; }
.sq-select select:focus-visible,
.sq-table select.form-control:focus-visible,
.sq-toolbar select.form-control:focus-visible {
  outline: none; border-color: var(--sq-primary);
  box-shadow: 0 0 0 3px rgba(99,102,241,.25);
}
.sq-select__chevron {
  position: absolute; right: 11px; top: 50%; transform: translateY(-50%);
  pointer-events: none; color: var(--sq-muted-fg); font-size: 11px;
}

/* Period filter: label and control read as one unit instead of loose text
   floating beside a browser dropdown. */
.sq-filter {
  display: inline-flex; align-items: stretch;
  border: 1px solid var(--sq-border); border-radius: 9px;
  background: var(--sq-card); overflow: hidden;
}
.sq-filter__label {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 10px 0 12px; margin: 0;
  font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--sq-muted-fg); background: var(--sq-muted);
  border-right: 1px solid var(--sq-border);
  white-space: nowrap;
}
.sq-filter select {
  border: 0; border-radius: 0; background: transparent; min-height: 42px;
  padding-right: 32px;
}
.sq-filter select:focus-visible { box-shadow: none; outline: 2px solid var(--sq-ring); outline-offset: -2px; }
.sq-filter:focus-within { border-color: var(--sq-primary); box-shadow: 0 0 0 3px rgba(99,102,241,.2); }

/* Row-level upgrade control: quieter, sized to its content */
.sq-table .sq-select select { min-height: 34px; font-size: 13px; padding: 5px 30px 5px 10px; }
.sq-table .sq-select__chevron { right: 10px; font-size: 10px; }
.sq-cell-muted { color: var(--sq-muted-fg); }

/* ===================  COMPACT EMPTY CHART STATE  ======================== */
/* An empty chart previously reserved the full plot height, leaving a large
   void that unbalanced the row. Collapse it instead. */
.sq-chart.is-empty { min-height: 0; }
.sq-chart__empty {
  position: static; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px;
  padding: 22px 16px; margin: 0;
  text-align: center; color: var(--sq-muted-fg); font-size: 13.5px;
  background: var(--sq-muted); border: 1px dashed var(--sq-border);
  border-radius: 8px;
}
.sq-chart__empty::before {
  content: "\f080";                       /* Font Awesome bar-chart */
  font-family: "Font Awesome 5 Free"; font-weight: 900;
  font-size: 16px; opacity: .45;
}

/* ===========================  CHART ROW  ================================
   Bootstrap columns leave cards at their natural height, so a collapsed empty
   chart sits beside a full-height one and the row reads as broken. A grid with
   stretched items keeps every card the same height regardless of content.
   ======================================================================== */
.sq-chart-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sq-space-2);
  align-items: stretch;
}
.sq-chart-row > .card { height: 100%; display: flex; flex-direction: column; margin-bottom: 0; }
.sq-chart-row > .card > .card-body { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; }

/* The sidebar should never scroll sideways. */
.main-sidebar, .main-sidebar .sidebar { overflow-x: hidden; }

/* Secondary status shouldn't compete with the row's primary content. A filled
   amber badge repeated down every row dominated the table; an outline treatment
   keeps it findable without shouting. */
.sq-badge--pending {
  background: transparent; color: #B45309; border-color: #FCD34D;
}
body.dark-mode .sq-badge--pending {
  background: transparent; color: #FCD34D; border-color: #92400E;
}
.sq-badge--pending::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex: 0 0 auto;
}

/* Role badge is also secondary metadata, not a call to action. */
.sq-badge--leader { background: transparent; border-color: #C7D2FE; color: var(--sq-primary-600); }
body.dark-mode .sq-badge--leader { background: transparent; border-color: #3730A3; color: #A5B4FC; }

/* Search: make it obvious the magnifier submits. */
.sq-search__submit {
  position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; display: grid; place-items: center;
  border: 0; background: transparent; border-radius: 6px;
  color: var(--sq-muted-fg); cursor: pointer; font-size: 13px;
}
.sq-search__submit:hover { background: var(--sq-muted); color: var(--sq-fg); }
.sq-search__submit:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 1px; }
.sq-search__hint {
  display: block; margin-top: 4px; font-size: 11.5px; color: var(--sq-muted-fg);
}

/* AdminLTE paints its own body/content background, so set ours explicitly or
   the tokens above never show through. */
body, body.dark-mode,
.content-wrapper, body.dark-mode .content-wrapper,
.content-wrapper .content { background-color: var(--sq-bg) !important; }
.main-footer, body.dark-mode .main-footer {
  background-color: var(--sq-bg) !important;
  border-top: 1px solid var(--sq-border);
  color: var(--sq-muted-fg);
}
.main-header.navbar, body.dark-mode .main-header.navbar {
  background-color: var(--sq-card) !important;
  border-bottom: 1px solid var(--sq-border);
}
.content-header .m-0, .content-header h1 { color: var(--sq-fg); }
/* Scoped to the admin layout: these retint AdminLTE's cards, which only exist
   inside .content-wrapper. Unscoped, they also painted a surface onto the
   login page's own `.card` — which has no padding of its own, because it was
   never meant to be a surface. */
.content-wrapper .card, body.dark-mode .content-wrapper .card {
  background-color: var(--sq-card); border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius); box-shadow: var(--sq-shadow);
}
.content-wrapper .card-header, body.dark-mode .content-wrapper .card-header {
  background-color: transparent; border-bottom: 1px solid var(--sq-border);
}
.card-title { color: var(--sq-fg); }

/* ===========================  MODAL DIALOG  ============================= */
.sq-modal { position: fixed; inset: 0; z-index: 2050; display: none; }
.sq-modal[open], .sq-modal.is-open { display: block; }
.sq-modal__backdrop {
  position: absolute; inset: 0;
  background: rgba(15, 18, 24, .55);
  backdrop-filter: blur(2px);
  animation: sqFade 140ms ease-out;
}
.sq-modal__panel {
  position: relative; z-index: 1;
  width: min(440px, calc(100vw - 32px));
  margin: 12vh auto 0;
  background: var(--sq-card);
  border: 1px solid var(--sq-border);
  border-radius: 12px;
  box-shadow: 0 20px 40px -12px rgba(0,0,0,.35);
  animation: sqPop 160ms cubic-bezier(.2,.9,.3,1);
  overflow: hidden;
}
@keyframes sqFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes sqPop  { from { opacity: 0; transform: translateY(8px) scale(.98) } to { opacity: 1; transform: none } }
@media (prefers-reduced-motion: reduce) {
  .sq-modal__backdrop, .sq-modal__panel { animation: none; }
}

.sq-modal__body { display: flex; gap: 14px; padding: 20px; }
.sq-modal__icon {
  flex: 0 0 auto; width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; font-size: 17px;
  background: var(--sq-primary-050); color: var(--sq-primary-600);
}
.sq-modal--danger .sq-modal__icon { background: #FEF2F2; color: var(--sq-danger); }
body.dark-mode .sq-modal--danger .sq-modal__icon { background: #45141400; border: 1px solid #7F1D1D; color: #FCA5A5; }

.sq-modal__title { margin: 2px 0 6px; font-size: 16.5px; font-weight: 600; color: var(--sq-fg); }
.sq-modal__text  { margin: 0; font-size: 14px; line-height: 1.55; color: var(--sq-muted-fg); }
.sq-modal__text strong { color: var(--sq-fg); font-weight: 600; }

.sq-modal__foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 20px; background: var(--sq-muted);
  border-top: 1px solid var(--sq-border);
}
.sq-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  text-decoration: none;
  min-height: 40px; padding: 9px 16px;
  font: inherit; font-size: 14px; font-weight: 600;
  border-radius: 8px; cursor: pointer;
  border: 1px solid var(--sq-border); background: var(--sq-card); color: var(--sq-fg);
  transition: background var(--sq-transition), border-color var(--sq-transition);
}
.sq-btn:hover { background: var(--sq-muted); }
.sq-btn--primary { background: var(--sq-primary-600); border-color: var(--sq-primary-600); color: #fff; }
.sq-btn--primary:hover { background: #4338CA; }
.sq-btn--danger  { background: var(--sq-danger); border-color: var(--sq-danger); color: #fff; }
.sq-btn--danger:hover { background: #B91C1C; }
.sq-btn:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
.sq-btn--sm { min-height: 34px; padding: 6px 12px; font-size: 13px; gap: 6px; }
a.sq-btn:hover { text-decoration: none; }
a.sq-btn--primary:hover, a.sq-btn--danger:hover { color: #fff; }

/* ======================  MODAL CHOICE LIST  ============================= */
/* Used where a confirm needs the user to pick one option (plan upgrade). */
.sq-choice { display: grid; gap: 8px; margin-top: 14px; }
.sq-choice__item {
  display: flex; align-items: flex-start; gap: 10px; margin: 0;
  padding: 11px 13px; cursor: pointer;
  border: 1px solid var(--sq-border); border-radius: 9px;
  background: var(--sq-card);
  transition: border-color var(--sq-transition), background var(--sq-transition);
}
.sq-choice__item:hover { background: var(--sq-muted); }
.sq-choice__item input { margin: 2px 0 0; accent-color: var(--sq-primary-600); flex: 0 0 auto; }
.sq-choice__item:focus-within { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
.sq-choice__item:has(input:checked) {
  border-color: var(--sq-primary); background: var(--sq-primary-050);
}
.sq-choice__label { display: block; font-size: 14px; font-weight: 600; color: var(--sq-fg); }
.sq-choice__hint  { display: block; font-size: 12.5px; color: var(--sq-muted-fg); margin-top: 2px; }
.sq-btn--danger:focus-visible { outline-color: var(--sq-danger); }

body.sq-modal-open { overflow: hidden; }

/* ======================  INFINITE SCROLL FOOTER  ======================== */
.sq-scroll-foot { display: flex; flex-direction: column; align-items: center; gap: 10px;
                  padding: var(--sq-space-3); border-top: 1px solid var(--sq-border); }
.sq-scroll-status { font-size: 13px; color: var(--sq-muted-fg); }
.sq-sentinel { display: flex; align-items: center; justify-content: center; height: 30px; }
.sq-sentinel::after {
  content: ""; width: 18px; height: 18px; opacity: 0;
  border: 2px solid var(--sq-border); border-top-color: var(--sq-primary);
  border-radius: 50%;
}
.sq-sentinel.is-loading::after { opacity: 1; animation: sqSpin .7s linear infinite; }
@keyframes sqSpin { to { transform: rotate(360deg) } }
@media (prefers-reduced-motion: reduce) { .sq-sentinel.is-loading::after { animation-duration: 2s; } }

/* ======================  FORMS  ========================================= */
/* Labels are always visible: a placeholder disappears the moment typing
   starts, which leaves no way back to "what was this field?". */
.sq-form { max-width: 640px; }
.sq-form--wide { max-width: 880px; }
.sq-field { margin-bottom: var(--sq-space-3); }
.sq-field__label {
  display: block; margin-bottom: 6px;
  font-size: 13.5px; font-weight: 600; color: var(--sq-fg);
}
.sq-field__req { color: var(--sq-danger); margin-left: 2px; }
/* Every text-like input, rather than a list of types that goes stale the first
   time a form needs one that is not on it (password did exactly that). */
.sq-input, .sq-form select, .sq-form textarea,
.sq-form input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="hidden"]):not([type="color"]) {
  display: block; width: 100%;
  min-height: 40px; padding: 9px 12px;
  font: inherit; font-size: 14px; color: var(--sq-fg);
  background: var(--sq-card); border: 1px solid var(--sq-border);
  border-radius: 8px; box-shadow: none;
  transition: border-color var(--sq-transition), box-shadow var(--sq-transition);
}
.sq-form textarea { min-height: 140px; resize: vertical; line-height: 1.55; }
.sq-form input[type="file"] { padding: 8px 10px; }
.sq-input:focus, .sq-form select:focus, .sq-form textarea:focus,
.sq-form input:focus {
  outline: none; border-color: var(--sq-primary);
  box-shadow: 0 0 0 3px rgba(99,102,241,.2);
}
.sq-field__hint { display: block; margin-top: 5px; font-size: 12.5px; color: var(--sq-muted-fg); }
/* Error sits next to the field it belongs to, not only in a summary at the top. */
.sq-field__error { display: block; margin-top: 5px; font-size: 12.5px; font-weight: 600; color: var(--sq-danger); }
.sq-field--invalid .sq-input, .sq-field--invalid input, .sq-field--invalid textarea {
  border-color: var(--sq-danger);
}
.sq-form__actions {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
  margin-top: var(--sq-space-3);
}
.sq-form__note { font-size: 13px; color: var(--sq-muted-fg); }
.sq-form__note--ok { color: var(--sq-accent); font-weight: 600; }

/* ======================  TABLE EXTRAS  ================================== */
/* Square, not the round avatar `.sq-person img` gives — artwork, not a face.
   Specificity has to match that rule to win it. */
.sq-thumb, .sq-person img.sq-thumb {
  width: 44px; height: 44px; border-radius: 8px; object-fit: cover;
  background: var(--sq-muted); border: 1px solid var(--sq-border); padding: 2px;
}
.sq-points { font-variant-numeric: tabular-nums; font-weight: 600; }
/* Long free-text cell: readable measure, no table blow-out. */
.sq-longtext { max-width: 42ch; white-space: normal; line-height: 1.5; }
.sq-longtext summary { cursor: pointer; }
.sq-longtext summary::marker { color: var(--sq-primary); }
.sq-longtext__more { color: var(--sq-primary-600); font-weight: 600; }
.sq-longtext details[open] .sq-longtext__more { display: none; }
.sq-nowrap { white-space: nowrap; }

/* Bootstrap pagination, restyled to the token palette. */
.sq-table-foot .page-link {
  color: var(--sq-fg); background: var(--sq-card);
  border-color: var(--sq-border); font-size: 13.5px;
  min-width: 36px; min-height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
}
.sq-table-foot .page-link:hover { background: var(--sq-muted); color: var(--sq-fg); }
.sq-table-foot .page-item.active .page-link {
  background: var(--sq-primary-600); border-color: var(--sq-primary-600); color: #fff;
}
.sq-table-foot .page-item.disabled .page-link { color: var(--sq-muted-fg); background: var(--sq-muted); }
.sq-table-foot .page-link:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; box-shadow: none; }
.sq-table-foot__count { font-size: 13px; color: var(--sq-muted-fg); }

/* Current-image preview beside its replace control. */
.sq-imagefield { display: flex; align-items: flex-start; gap: var(--sq-space-2); flex-wrap: wrap; }
.sq-thumb--lg { width: 72px; height: 72px; }

/* ======================  TOASTS  ======================================== */
/* toastr 2.1.4 handles the live region and dismissal; only its 2012-era
   skin is replaced here. Type is carried by an icon chip and a left rule,
   not by a saturated fill behind the text — the same rule the stat tiles
   follow, and it keeps the text contrast fixed in both themes. */
#toast-container > div {
  opacity: 1;
  width: 340px; max-width: calc(100vw - 32px);
  padding: 13px 15px 13px 46px;
  border: 1px solid var(--sq-border);
  border-left: 3px solid var(--sq-muted-fg);
  border-radius: var(--sq-radius);
  background-color: var(--sq-card);
  box-shadow: var(--sq-shadow-lg);
  color: var(--sq-fg);
  font-size: 14px; line-height: 1.5;
}
#toast-container > div:hover { box-shadow: var(--sq-shadow-lg); opacity: 1; }
#toast-container > div::before {
  position: absolute; left: 15px; top: 14px;
  font-family: "Font Awesome 5 Free"; font-weight: 900;
  font-size: 15px; line-height: 1.2;
}
/* AdminLTE repaints these at `#toast-container .toast-*`, so the surface has to
   be re-stated per type to out-specify it rather than once on the container. */
#toast-container > .toast-success,
#toast-container > .toast-error,
#toast-container > .toast-warning,
#toast-container > .toast-info {
  background-color: var(--sq-card); color: var(--sq-fg);
  /* toastr ships its icon sprites per type at !important, so they have to be
     cleared per type too — a rule on the container loses on specificity. */
  background-image: none !important;
}
#toast-container > .toast-success  { border-left-color: var(--sq-accent); }
#toast-container > .toast-success::before  { content: "\f058"; color: var(--sq-accent); }
#toast-container > .toast-error    { border-left-color: var(--sq-danger); }
#toast-container > .toast-error::before    { content: "\f06a"; color: var(--sq-danger); }
#toast-container > .toast-warning  { border-left-color: var(--sq-warning); }
#toast-container > .toast-warning::before  { content: "\f071"; color: var(--sq-warning); }
#toast-container > .toast-info     { border-left-color: var(--sq-primary); }
#toast-container > .toast-info::before     { content: "\f05a"; color: var(--sq-primary); }

#toast-container .toast-title { font-weight: 600; margin-bottom: 2px; }
#toast-container .toast-message { color: var(--sq-fg); }
#toast-container .toast-message a { color: var(--sq-primary-600); }
#toast-container .toast-close-button {
  position: absolute; top: 8px; right: 8px;
  width: 24px; height: 24px; padding: 0;
  font-size: 17px; font-weight: 400; line-height: 22px;
  color: var(--sq-muted-fg); text-shadow: none; opacity: 1;
  border-radius: 6px;
}
#toast-container .toast-close-button:hover,
#toast-container .toast-close-button:focus { background: var(--sq-muted); color: var(--sq-fg); opacity: 1; }
#toast-container .toast-close-button:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 1px; }
#toast-container .toast-progress {
  height: 3px; opacity: 1; background: var(--sq-primary);
  border-radius: 0 0 var(--sq-radius) var(--sq-radius);
}
#toast-container > .toast-success .toast-progress { background: var(--sq-accent); }
#toast-container > .toast-error   .toast-progress { background: var(--sq-danger); }
#toast-container > .toast-warning .toast-progress { background: var(--sq-warning); }

/* ===========================================================================
   Legacy AdminLTE compat layer
   ---------------------------------------------------------------------------
   The admin (role 0) screens were converted to the .sq-* components above. The
   team-leader (role 1) screens — teams, members, invitations, behaviours,
   awards, settings, profile, benchmark, consolidated results — still ship raw
   AdminLTE markup (.card.card-secondary, .bg-gradient-*, .table), which nothing
   here styled, so they kept the stock grey chrome and the four-colour button
   set under the new dark shell.

   Rather than rewrite ~25 blades, this maps the AdminLTE classes onto the same
   tokens. Scoped to .content-wrapper so the sidebar and navbar are untouched.
   Converted pages don't use these class names, so nothing here reaches them.
   =========================================================================== */

/* --- Cards: kill .card-secondary's grey header bar ----------------------- */
.content-wrapper .card {
  background: var(--sq-card);
  border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius);
  box-shadow: var(--sq-shadow);
  color: var(--sq-fg);
  margin-bottom: var(--sq-space-4);
}
.content-wrapper .card.card-secondary,
.content-wrapper .card.card-gray,
.content-wrapper .card.card-outline { border-top: 1px solid var(--sq-border); }

.content-wrapper .card > .card-header,
.content-wrapper .card.card-secondary:not(.card-outline) > .card-header,
.content-wrapper .card.card-primary:not(.card-outline) > .card-header,
.content-wrapper .card.card-info:not(.card-outline) > .card-header,
.content-wrapper .card.card-success:not(.card-outline) > .card-header,
.content-wrapper .card.card-warning:not(.card-outline) > .card-header,
.content-wrapper .card.card-danger:not(.card-outline) > .card-header,
.content-wrapper .card.card-gray:not(.card-outline) > .card-header {
  background-color: transparent;
  border-bottom: 1px solid var(--sq-border);
  padding: var(--sq-space-2) var(--sq-space-3);
  display: flex; align-items: center; gap: var(--sq-space-2); flex-wrap: wrap;
  min-height: 0;
}
.content-wrapper .card > .card-header .card-title,
.content-wrapper .card.card-secondary:not(.card-outline) > .card-header .card-title {
  float: none; margin: 0;
  font-size: 14px; font-weight: 600; line-height: 1.4;
  color: var(--sq-fg);
}
/* Header-level actions (Pending Invites, etc.) sit right, not floated. */
.content-wrapper .card > .card-header .card-tools,
.content-wrapper .card > .card-header > .btn,
.content-wrapper .card > .card-header > a.btn { margin-left: auto; float: none; }

.content-wrapper .card > .card-body { padding: var(--sq-space-3); }
.content-wrapper .card > .card-footer {
  background: var(--sq-muted);
  border-top: 1px solid var(--sq-border);
  padding: var(--sq-space-2) var(--sq-space-3);
}
/* List rows are themselves .card — flatten so they read as rows, not stacked
   floating panels. */
.content-wrapper .card .card {
  box-shadow: none;
  background: var(--sq-muted);
  margin-bottom: var(--sq-space-2);
  transition: border-color var(--sq-transition), background var(--sq-transition);
}
.content-wrapper .card .card:hover { border-color: var(--sq-primary); }

/* --- Buttons -------------------------------------------------------------
   One filled call-to-action per toolbar. Everything else is a quiet outline,
   and destructive stays quiet until you're actually on it.
   !important is required only because AdminLTE sets .bg-gradient-* backgrounds
   with !important; the rest wins on cascade order alone. ------------------ */
.content-wrapper .btn {
  min-height: 38px;
  padding: 8px 14px;
  border-radius: 8px;
  font-size: 14px; font-weight: 500; line-height: 1.3;
  border: 1px solid transparent;
  box-shadow: none;
  transition: background var(--sq-transition), border-color var(--sq-transition),
              color var(--sq-transition);
}
.content-wrapper .btn:focus-visible {
  outline: 2px solid var(--sq-ring); outline-offset: 2px; box-shadow: none;
}
.content-wrapper .btn.btn-sm { min-height: 32px; padding: 5px 10px; font-size: 13px; }

/* Create / confirm — the one filled CTA. */
.content-wrapper .btn.bg-gradient-success,
.content-wrapper .btn.btn-success {
  background: var(--sq-accent) !important;
  border-color: var(--sq-accent); color: #fff !important;
}
.content-wrapper .btn.bg-gradient-success:hover,
.content-wrapper .btn.btn-success:hover { background: #047857 !important; }

/* Submit inside a form/modal — brand indigo. */
.content-wrapper .btn.btn-primary {
  background: var(--sq-primary); border-color: var(--sq-primary); color: #fff;
}
.content-wrapper .btn.btn-primary:hover {
  background: var(--sq-primary-600); border-color: var(--sq-primary-600); color: #fff;
}

/* Search / filter / Edit / View — supporting actions, quiet outline. */
.content-wrapper .btn.bg-gradient-primary,
.content-wrapper .btn.btn-info,
.content-wrapper .btn.bg-gradient-info,
.content-wrapper .btn.btn-secondary,
.content-wrapper .btn.btn-default {
  background: var(--sq-card) !important;
  border-color: var(--sq-border);
  color: var(--sq-fg) !important;
}
.content-wrapper .btn.bg-gradient-primary:hover,
.content-wrapper .btn.btn-info:hover,
.content-wrapper .btn.bg-gradient-info:hover,
.content-wrapper .btn.btn-secondary:hover,
.content-wrapper .btn.btn-default:hover {
  background: var(--sq-muted) !important; border-color: var(--sq-muted-fg);
  color: var(--sq-fg) !important;
}

/* Upgrade / Resend — amber, but outlined so it can't outshout the CTA. */
.content-wrapper .btn.btn-warning,
.content-wrapper .btn.bg-gradient-warning {
  background: transparent !important;
  border-color: var(--sq-warning);
  color: var(--sq-warning) !important;
}
.content-wrapper .btn.btn-warning:hover,
.content-wrapper .btn.bg-gradient-warning:hover {
  background: var(--sq-warning) !important; color: #fff !important;
}

/* Destructive — quiet until hovered, so Delete never reads as the CTA. */
.content-wrapper .btn.btn-danger,
.content-wrapper .btn.bg-gradient-danger {
  background: transparent !important;
  border-color: var(--sq-border);
  color: var(--sq-danger) !important;
}
.content-wrapper .btn.btn-danger:hover,
.content-wrapper .btn.bg-gradient-danger:hover {
  background: var(--sq-danger) !important; border-color: var(--sq-danger);
  color: #fff !important;
}
/* Modal dismiss is marked up as .btn-danger throughout — it cancels, it doesn't
   destroy, so it must not read red. */
.content-wrapper .modal-footer .btn-danger[data-dismiss="modal"],
.modal-footer .btn-danger[data-dismiss="modal"] {
  background: transparent !important;
  border-color: var(--sq-border);
  color: var(--sq-muted-fg) !important;
}
.content-wrapper .modal-footer .btn-danger[data-dismiss="modal"]:hover,
.modal-footer .btn-danger[data-dismiss="modal"]:hover {
  background: var(--sq-muted) !important; color: var(--sq-fg) !important;
}

/* Icon-only actions in list rows (the inline-styled eye / trash). */
.content-wrapper .card .btn > i.fa { color: inherit !important; }

/* --- Form controls ------------------------------------------------------- */
.content-wrapper .form-control,
.content-wrapper .custom-select,
.content-wrapper select.form-control {
  min-height: 38px;
  background: var(--sq-card);
  border: 1px solid var(--sq-border);
  border-radius: 8px;
  color: var(--sq-fg);
  font-size: 14px;
  box-shadow: none;
}
.content-wrapper .form-control::placeholder { color: var(--sq-muted-fg); opacity: 1; }
.content-wrapper .form-control:focus,
.content-wrapper .custom-select:focus {
  background: var(--sq-card); color: var(--sq-fg);
  border-color: var(--sq-primary);
  box-shadow: 0 0 0 3px rgba(99,102,241,.25);
}
.content-wrapper label { color: var(--sq-fg); font-size: 13px; font-weight: 600; }

/* --- Tables -------------------------------------------------------------- */
.content-wrapper .card .table { color: var(--sq-fg); margin-bottom: 0; }
.content-wrapper .card .table thead th {
  background: var(--sq-muted);
  border: 0; border-bottom: 1px solid var(--sq-border);
  padding: 10px var(--sq-space-3);
  font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--sq-muted-fg); white-space: nowrap;
}
.content-wrapper .card .table tbody td {
  padding: 12px var(--sq-space-3);
  border-top: 0; border-bottom: 1px solid var(--sq-border);
  vertical-align: middle; font-size: 14px;
}
.content-wrapper .card .table tbody tr:last-child td { border-bottom: 0; }
.content-wrapper .card .table-hover tbody tr:hover { background: var(--sq-muted); color: var(--sq-fg); }

/* --- Modals -------------------------------------------------------------- */
.modal-content {
  background: var(--sq-card); color: var(--sq-fg);
  border: 1px solid var(--sq-border); border-radius: var(--sq-radius);
  box-shadow: var(--sq-shadow-lg);
}
.modal-header, .modal-footer { border-color: var(--sq-border); }
/* Modal headers carry .bg-info throughout — a full-bleed blue bar that reads as
   an alert rather than a title. Neutralise it; the title alone does the job. */
.modal-header, .modal-header.bg-info, .modal-header.bg-primary,
.modal-header.bg-success, .modal-header.bg-warning, .modal-header.bg-danger {
  background-color: transparent !important; color: var(--sq-fg) !important;
}
.modal-header .modal-title { font-size: 16px; font-weight: 600; }
.modal-footer { background: var(--sq-muted); gap: var(--sq-space-1); }
/* In a modal the one button that isn't a dismiss IS the primary action,
   whatever legacy colour class it happens to wear. */
.modal-footer .btn:not([data-dismiss]):not(.btn-warning) {
  background: var(--sq-primary) !important;
  border-color: var(--sq-primary);
  color: #fff !important;
}
.modal-footer .btn:not([data-dismiss]):not(.btn-warning):hover {
  background: var(--sq-primary-600) !important; border-color: var(--sq-primary-600);
}
/* Bootstrap 4 leaves bare checkboxes at ~13px — under the 24px target minimum. */
.content-wrapper input[type="checkbox"]:not(.icheck-input),
.modal input[type="checkbox"]:not(.icheck-input) {
  width: 16px; height: 16px; vertical-align: -3px; margin-right: 4px;
  accent-color: var(--sq-primary); cursor: pointer;
}
.modal-header .close { color: var(--sq-muted-fg); text-shadow: none; opacity: 1; }
.modal-header .close:hover { color: var(--sq-fg); }

/* --- Pagination ---------------------------------------------------------- */
.content-wrapper .pagination .page-link {
  background: var(--sq-card); border-color: var(--sq-border); color: var(--sq-fg);
}
.content-wrapper .pagination .page-item.active .page-link {
  background: var(--sq-primary); border-color: var(--sq-primary); color: #fff;
}
.content-wrapper .pagination .page-item.disabled .page-link {
  background: var(--sq-muted); border-color: var(--sq-border); color: var(--sq-muted-fg);
}

/* --- intro.js onboarding tour -------------------------------------------
   introjs.min.css ships a white tooltip; under the dark shell it flared, and
   its default transparent overlay left the highlighted control unreadable
   behind the tooltip. Requires the introjs <link> to sit ABOVE this file in
   master.blade.php. ------------------------------------------------------- */
.introjs-tooltip {
  background: var(--sq-card); color: var(--sq-fg);
  border: 1px solid var(--sq-border); border-radius: var(--sq-radius);
  box-shadow: var(--sq-shadow-lg);
  min-width: 280px; max-width: 340px;
}
/* The colour is NOT redundant with .introjs-tooltip's. intro.js is loaded
   unpinned from unpkg, and a current release sets `.introjs-tooltiptext
   { color: #212121 }` — same specificity, earlier sheet, but nothing here
   opposed it, so the tour text rendered #212121 on our #1F2228 tooltip:
   a contrast ratio of 1.03:1. The text was invisible in dark mode. */
.introjs-tooltiptext { font-size: 14px; line-height: 1.5; padding: var(--sq-space-3); color: var(--sq-fg); }
.introjs-tooltipbuttons { border-top: 1px solid var(--sq-border); padding: var(--sq-space-2); }
.introjs-button {
  background: var(--sq-card); border: 1px solid var(--sq-border); border-radius: 8px;
  color: var(--sq-fg); text-shadow: none; font-size: 13px; padding: 6px 12px;
}
.introjs-button:hover, .introjs-button:focus { background: var(--sq-muted); color: var(--sq-fg); }
.introjs-button:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
.introjs-nextbutton {
  background: var(--sq-primary); border-color: var(--sq-primary); color: #fff;
}
.introjs-nextbutton:hover, .introjs-nextbutton:focus {
  background: var(--sq-primary-600); border-color: var(--sq-primary-600); color: #fff;
}
.introjs-disabled, .introjs-disabled:hover, .introjs-disabled:focus {
  background: var(--sq-muted); border-color: var(--sq-border); color: var(--sq-muted-fg);
}
.introjs-skipbutton { color: var(--sq-muted-fg); }
.introjs-skipbutton:hover { color: var(--sq-fg); }
.introjs-arrow.top { border-bottom-color: var(--sq-card); }
.introjs-arrow.bottom { border-top-color: var(--sq-card); }
.introjs-arrow.left { border-right-color: var(--sq-card); }
.introjs-arrow.right { border-left-color: var(--sq-card); }
.introjs-bullets ul li a { background: var(--sq-border); }
.introjs-bullets ul li a.active { background: var(--sq-primary); }
.introjs-overlay { background: rgba(0,0,0,.6); opacity: 1 !important; }
.introjs-helperLayer {
  background: transparent;
  border-radius: 8px;
  box-shadow: 0 0 0 2px var(--sq-primary), 0 0 0 9999px rgba(0,0,0,.6);
}
/* introjs hard-codes a white background on this label — invisible-on-white text
   under the dark shell. Also bumps the 10px checkbox to a real target. */
.introjs-dontShowAgain { padding: 0 var(--sq-space-3) var(--sq-space-2); }
.introjs-tooltip .introjs-dontShowAgain label {
  background-color: transparent; color: var(--sq-muted-fg);
  font-weight: 500; cursor: pointer;
}
.introjs-tooltip .introjs-dontShowAgain input {
  width: 16px; height: 16px; margin-bottom: 0; vertical-align: -3px; accent-color: var(--sq-primary);
}

/* Settings quick actions — four peers, so they read as one set rather than
   four different severities. */
.sq-quick-actions {
  display: grid; gap: var(--sq-space-2);
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.sq-quick-actions .btn {
  justify-content: flex-start;
  display: inline-flex; align-items: center; gap: var(--sq-space-1);
  text-align: left;
}
.sq-quick-actions .btn i { width: 16px; text-align: center; color: var(--sq-muted-fg); }
.sq-quick-actions .btn:hover i { color: var(--sq-primary); }

/* --- info-box tiles (leader + admin dashboards) --------------------------
   The stat tiles carried five arbitrary AdminLTE fills — bg-gray, bg-navy,
   bg-teal, bg-indigo, bg-info — none of which encoded anything, so the colour
   read as decoration and the block fought the converted .sq-stat tiles beside
   it. Flatten every tile to the card surface and move the accent into the icon
   chip, where an .info-box--* modifier can actually mean something.
   bg-* wins with !important in AdminLTE, hence the !important here. -------- */
.content-wrapper .info-box {
  background-color: var(--sq-card) !important;
  color: var(--sq-fg) !important;
  border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius);
  box-shadow: var(--sq-shadow);
  padding: var(--sq-space-2);
  gap: var(--sq-space-2);
}
/* `disabled` is used here purely as a style hook, not a real state — the
   summary tiles are live content and must not read as greyed out. */
.content-wrapper .info-box.disabled { opacity: 1; filter: none; }

.content-wrapper .info-box .info-box-icon {
  width: 48px; min-width: 48px; height: 48px; align-self: center;
  border-radius: 10px; font-size: 20px;
  background: var(--sq-muted) !important;
  color: var(--sq-muted-fg) !important;
}
.content-wrapper .info-box .info-box-content { line-height: 1.45; padding: 0; }
.content-wrapper .info-box .info-box-text {
  font-size: 12px; font-weight: 600; letter-spacing: .03em;
  color: var(--sq-muted-fg); white-space: normal;
}
.content-wrapper .info-box .info-box-text b { font-weight: 600; }
.content-wrapper .info-box .info-box-number {
  font-size: 24px; font-weight: 700; color: var(--sq-fg); line-height: 1.2;
}
.content-wrapper .info-box .info-box-text b,
.content-wrapper .info-box .info-box-content .info-box-text > b { color: var(--sq-fg); }

/* Semantic accents — the chip is the only place colour is allowed to differ. */
.content-wrapper .info-box--positive .info-box-icon {
  background: var(--sq-accent-050) !important; color: var(--sq-accent) !important;
}
.content-wrapper .info-box--negative .info-box-icon {
  background: rgba(220,38,38,.12) !important; color: var(--sq-danger) !important;
}
.content-wrapper .info-box--award .info-box-icon {
  background: var(--sq-primary-050) !important; color: var(--sq-primary) !important;
}
body.dark-mode .content-wrapper .info-box--positive .info-box-icon { color: #34D399 !important; }
body.dark-mode .content-wrapper .info-box--negative .info-box-icon { color: #F87171 !important; }
body.dark-mode .content-wrapper .info-box--award    .info-box-icon { color: #A5B4FC !important; }

/* ===========================================================================
   Give feedback — the product's core action, previously a broken-image form
   buried under ten charts at the bottom of the member detail page.
   =========================================================================== */
.sq-feedback { max-width: 780px; margin: 0 auto; padding-bottom: 96px; }

.sq-alert {
  display: flex; gap: var(--sq-space-2); align-items: flex-start;
  max-width: 780px; margin: 0 auto var(--sq-space-3);
  padding: var(--sq-space-2) var(--sq-space-3);
  border: 1px solid var(--sq-border); border-left-width: 3px;
  border-radius: var(--sq-radius); background: var(--sq-card);
}
.sq-alert p { margin: 2px 0 0; font-size: 14px; color: var(--sq-muted-fg); }
.sq-alert:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
.sq-alert--error { border-left-color: var(--sq-danger); }
.sq-alert--error > i { color: var(--sq-danger); font-size: 16px; margin-top: 2px; }

.sq-step { margin-bottom: var(--sq-space-3); }
.sq-step__head {
  display: flex; align-items: center; gap: var(--sq-space-2);
  padding: var(--sq-space-2) var(--sq-space-3);
  border-bottom: 1px solid var(--sq-border);
}
.sq-step__num {
  flex: none; width: 24px; height: 24px; border-radius: 999px;
  display: grid; place-items: center;
  background: var(--sq-muted); color: var(--sq-muted-fg);
  font-size: 12px; font-weight: 700;
}
.sq-step__title { margin: 0; font-size: 15px; font-weight: 600; color: var(--sq-fg); }
.sq-step__req {
  margin-left: auto; font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--sq-muted-fg);
}
.sq-step__body { padding: var(--sq-space-3); }
.sq-fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }

.sq-field__label { display: block; font-size: 13px; font-weight: 600; color: var(--sq-fg); margin-bottom: 6px; }
.sq-field__help { margin: 6px 0 0; font-size: 13px; color: var(--sq-muted-fg); }
.sq-field { width: 100%; }

/* Behaviour / visibility cards — a real radio, visibly selected, keyboard-reachable. */
.sq-choice-grid { display: grid; gap: var(--sq-space-2); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.sq-choice-grid--3 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.sq-choice { position: relative; margin: 0; cursor: pointer; }
.sq-choice input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.sq-choice__body {
  display: block; height: 100%;
  padding: var(--sq-space-2) var(--sq-space-3);
  border: 1px solid var(--sq-border); border-radius: var(--sq-radius);
  background: var(--sq-card);
  transition: border-color var(--sq-transition), background var(--sq-transition);
}
.sq-choice:hover .sq-choice__body { border-color: var(--sq-muted-fg); }
.sq-choice input:checked + .sq-choice__body {
  border-color: var(--sq-primary);
  background: var(--sq-primary-050);
  box-shadow: inset 0 0 0 1px var(--sq-primary);
}
.sq-choice input:focus-visible + .sq-choice__body { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
.sq-choice__dot { display: inline-block; width: 8px; height: 8px; border-radius: 999px; margin-right: 7px; vertical-align: 1px; }
.sq-choice__name { display: block; font-size: 14px; font-weight: 600; color: var(--sq-fg); }
.sq-choice__name i { width: 14px; margin-right: 4px; color: var(--sq-muted-fg); }
.sq-choice__desc { display: block; margin-top: 3px; font-size: 13px; line-height: 1.45; color: var(--sq-muted-fg); }

/* Emotion chips — name and signed points, because a face alone never told you
   whether you were about to hand out -1 or -3. */
.sq-emotion-group {
  margin: var(--sq-space-3) 0 var(--sq-space-1);
  font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--sq-muted-fg);
}
.sq-emotion-group:first-of-type { margin-top: var(--sq-space-2); }
/* Options are tiles rather than pills so the emoji has room: picture, name,
   then the points. Six fit a row on desktop, three on a phone. */
.sq-emotion-row {
  display: grid; gap: var(--sq-space-1);
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
.sq-emotion { position: relative; display: block; margin: 0; cursor: pointer; }
.sq-emotion input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.sq-emotion__card {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  height: 100%; padding: 10px 4px 8px;
  border: 1px solid var(--sq-border); border-radius: 10px; background: var(--sq-card);
  text-align: center; font-size: 13px; line-height: 1.25;
  transition: border-color var(--sq-transition), background var(--sq-transition);
}
.sq-emotion__art { flex: none; width: 56px; height: 56px; object-fit: contain; }
.sq-emotion__art[hidden] { display: none; }
/* Emotion art carries its own ±points in the bottom strip of the image (faces
   end at 79-83% of the height, numbers start at 83-86%). The tile prints the
   points as text, so crop that strip here rather than showing them twice. The
   box keeps the image aspect so the percentage lands in the same place on each.
   New emotion art needs the same layout: see docs/08-charts-and-emoji.md. */
.sq-emotion--pos .sq-emotion__art,
.sq-emotion--neg .sq-emotion__art {
  width: auto; height: 68px; object-fit: fill;
  clip-path: inset(0 0 17.1% 0); margin-bottom: -11px;
}
.sq-emotion__name { font-weight: 500; color: var(--sq-fg); overflow-wrap: anywhere; }
.sq-emotion__pts { margin-top: auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.sq-emotion--pos   .sq-emotion__pts { color: var(--sq-accent); }
.sq-emotion--neg   .sq-emotion__pts { color: var(--sq-danger); }
.sq-emotion--award .sq-emotion__pts { color: var(--sq-primary); }
body.dark-mode .sq-emotion--pos .sq-emotion__pts { color: #34D399; }
body.dark-mode .sq-emotion--neg .sq-emotion__pts { color: #F87171; }
body.dark-mode .sq-emotion--award .sq-emotion__pts { color: #A5B4FC; }
/* Same lift as the ranked lists: the design's green is under 3:1 on dark. */
body.dark-mode .sq-emotion--pos .sq-emotion__art { filter: brightness(1.6) saturate(1.1); }

.sq-emotion:hover .sq-emotion__card { border-color: var(--sq-muted-fg); }
/* Selection is carried by fill + weight + a heavier border, never by hue alone. */
.sq-emotion input:checked ~ .sq-emotion__card {
  border-color: var(--sq-primary); background: var(--sq-primary-050);
  box-shadow: inset 0 0 0 1px var(--sq-primary);
}
.sq-emotion input:checked ~ .sq-emotion__card .sq-emotion__name { font-weight: 700; }
.sq-emotion input:focus-visible ~ .sq-emotion__card { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
/* The light token is a saturated indigo on dark, which swallowed the red art. */
body.dark-mode .sq-emotion input:checked ~ .sq-emotion__card { background: rgba(99, 102, 241, .14); }
@media (max-width: 639.98px) {
  .sq-emotion-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .sq-emotion__card { font-size: 12px; }
}

.sq-linkbtn {
  margin-top: var(--sq-space-2); padding: 0; border: 0; background: none;
  font: inherit; font-size: 13px; color: var(--sq-primary); cursor: pointer; text-decoration: underline;
}
.sq-linkbtn:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; border-radius: 4px; }

.sq-details { margin-top: var(--sq-space-3); border-top: 1px solid var(--sq-border); padding-top: var(--sq-space-2); }
.sq-details > summary {
  cursor: pointer; font-size: 13px; font-weight: 600; color: var(--sq-fg);
  list-style: none; display: flex; align-items: center; gap: 6px;
}
.sq-details > summary::-webkit-details-marker { display: none; }
.sq-details > summary::before { content: "\f067"; font: 900 11px/1 "Font Awesome 5 Free"; color: var(--sq-muted-fg); }
.sq-details[open] > summary::before { content: "\f068"; }
.sq-details > summary:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; border-radius: 4px; }
.sq-details__hint { font-weight: 500; color: var(--sq-muted-fg); }
.sq-emotion-row--award { margin-top: var(--sq-space-2); }

/* Send bar — the submit was previously below a five-section scroll. */
.sq-sendbar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: var(--sq-space-3); flex-wrap: wrap;
  margin-top: var(--sq-space-3);
  padding: var(--sq-space-2) var(--sq-space-3);
  background: var(--sq-card);
  border: 1px solid var(--sq-border); border-radius: var(--sq-radius);
  box-shadow: var(--sq-shadow-lg);
}
.sq-sendbar__summary { margin: 0; flex: 1 1 260px; font-size: 13px; color: var(--sq-muted-fg); }
.sq-sendbar__actions { display: flex; gap: var(--sq-space-1); margin-left: auto; }
/* Until the required pieces are there, the CTA stays quiet rather than lying
   about being ready. The button is never disabled — the server still owns
   validation, and a disabled control gives no reason for being disabled. */
.content-wrapper .sq-sendbar .btn.bg-gradient-success {
  background: var(--sq-muted) !important; color: var(--sq-muted-fg) !important;
  border-color: var(--sq-border);
}
.content-wrapper .sq-sendbar .btn.bg-gradient-success.is-ready {
  background: var(--sq-accent) !important; color: #fff !important; border-color: var(--sq-accent);
}

@media (max-width: 640px) {
  .sq-sendbar__summary { flex-basis: 100%; }
  .sq-sendbar__actions { margin-left: 0; width: 100%; }
  .sq-sendbar__actions .btn { flex: 1; }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Single-task pages constrain the form; the page header has to line up with it
   or the h1 floats off on its own. */
.content-wrapper .container-fluid.sq-narrow { max-width: calc(780px + var(--sq-space-3) * 2); margin: 0 auto; }

/* --- Member roster -------------------------------------------------------
   Was a two-up card grid: ~230px of vertical space per person, a 80px goal
   knob that only ever read "0", and Delete given the same visual weight as
   View — while the leader's actual job, giving feedback, had no entry point
   at all. A table fits the whole team on one screen and puts the job first. */
.sq-roster__rank { width: 56px; text-align: center; }
.sq-rank {
  display: inline-grid; place-items: center;
  min-width: 24px; height: 24px; padding: 0 6px;
  border-radius: 999px; background: var(--sq-muted); color: var(--sq-muted-fg);
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.sq-rank--top { background: var(--sq-primary-050); color: var(--sq-primary); }
body.dark-mode .sq-rank--top { color: #C7D2FE; }

.sq-num { text-align: right; }
.sq-points { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--sq-muted-fg); }
.sq-points--pos { color: var(--sq-accent); }
.sq-points--neg { color: var(--sq-danger); }
body.dark-mode .sq-points--pos { color: #34D399; }
body.dark-mode .sq-points--neg { color: #F87171; }

.sq-meter { display: flex; align-items: center; gap: var(--sq-space-1); min-width: 120px; }
.sq-meter__track {
  flex: 1; height: 6px; border-radius: 999px;
  background: var(--sq-muted); overflow: hidden;
}
.sq-meter__fill { display: block; height: 100%; border-radius: 999px; background: var(--sq-primary); }
.sq-meter__value {
  flex: none; min-width: 36px; text-align: right;
  font-size: 13px; font-variant-numeric: tabular-nums; color: var(--sq-muted-fg);
}

.sq-roster .sq-actions { justify-content: flex-end; }
.sq-roster td:last-child { text-align: right; }

@media (max-width: 900px) {
  /* Goals is the first thing worth losing when space runs out. */
  .sq-roster th:nth-child(4), .sq-roster td:nth-child(4) { display: none; }
}
.sq-roster th:nth-child(4), .sq-roster td:nth-child(4) { width: 180px; }
.sq-roster th:nth-child(3), .sq-roster td:nth-child(3) { width: 90px; }

/* Period-over-period tiles — replaces a bar chart that shared one axis across
   a percentage, an ordinal rank and a point count. */
.sq-delta-grid { display: grid; gap: var(--sq-space-2); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.sq-delta { padding: var(--sq-space-2) var(--sq-space-3); background: var(--sq-muted); border-radius: var(--sq-radius); }
.sq-delta__label { margin: 0; font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--sq-muted-fg); }
.sq-delta__value { margin: 4px 0 2px; font-size: 26px; font-weight: 700; line-height: 1.1; color: var(--sq-fg); font-variant-numeric: tabular-nums; }
.sq-delta__change { margin: 0; font-size: 12px; line-height: 1.4; color: var(--sq-muted-fg); }
.sq-delta__change i { margin-right: 3px; }
.sq-delta__change.is-better { color: var(--sq-accent); }
.sq-delta__change.is-worse  { color: var(--sq-danger); }
body.dark-mode .sq-delta__change.is-better { color: #34D399; }
body.dark-mode .sq-delta__change.is-worse  { color: #F87171; }

.sq-cta {
  display: flex; align-items: center; gap: var(--sq-space-3); flex-wrap: wrap;
  padding: var(--sq-space-3); margin-bottom: var(--sq-space-3);
}
.sq-cta__title { margin: 0 0 2px; font-size: 16px; font-weight: 600; color: var(--sq-fg); }
.sq-cta__text p { margin: 0; font-size: 14px; color: var(--sq-muted-fg); }
.sq-cta .btn { margin-left: auto; }
.sq-cta .btn i { margin-right: 6px; }
@media (max-width: 560px) { .sq-cta .btn { margin-left: 0; width: 100%; } }
.sq-topitem__name { margin-top: 6px; font-size: 14px; font-weight: 600; color: var(--sq-fg); }

/* ===========================================================================
   Setup pages — Awards, Teams, Invitations.
   These were card grids of broken images with Edit and Delete given equal
   weight, and none of them told you the one thing you came to find out:
   which awards get used, how each team is configured, how long an invite has
   been sitting there.
   =========================================================================== */

/* One line under the page title saying what the thing on this page IS. */
.sq-lede {
  margin: 0 0 var(--sq-space-3);
  max-width: 68ch;
  font-size: 14px; line-height: 1.55; color: var(--sq-muted-fg);
}

.sq-toolbar__search { display: flex; align-items: center; gap: var(--sq-space-1); }
.sq-toolbar__search .form-control { width: 240px; }
.sq-toolbar__cta { margin-left: auto; }
.sq-toolbar__cta i { margin-right: 6px; }

.sq-cell-strong { font-weight: 600; color: var(--sq-fg); font-variant-numeric: tabular-nums; }

/* Award identity chip — stands in for art that is optional and often absent. */
.sq-awardchip {
  display: grid; place-items: center; flex: none;
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--sq-primary-050); color: var(--sq-primary); font-size: 15px;
}
body.dark-mode .sq-awardchip { color: #A5B4FC; }

.sq-awards th:nth-child(2), .sq-awards td:nth-child(2),
.sq-awards th:nth-child(3), .sq-awards td:nth-child(3) { width: 120px; }
.sq-awards td:last-child, .sq-awards th:last-child { text-align: right; }
.sq-awards .sq-actions { justify-content: flex-end; }

.sq-pagehead {
  display: flex; align-items: flex-start; gap: var(--sq-space-3);
  flex-wrap: wrap; margin-bottom: var(--sq-space-3);
}
.sq-pagehead .sq-lede { margin: 0; flex: 1 1 320px; }
.sq-pagehead__cta { margin-left: auto; flex: none; }
.sq-pagehead__cta i { margin-right: 6px; }
.sq-toolbar:empty { display: none; }
@media (max-width: 560px) { .sq-pagehead__cta { margin-left: 0; width: 100%; } }

.sq-section__title {
  margin: var(--sq-space-4) 0 var(--sq-space-2);
  font-size: 13px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--sq-muted-fg);
}
.sq-section__title:first-of-type { margin-top: 0; }

.sq-teamchip {
  display: grid; place-items: center; flex: none;
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--sq-muted); color: var(--sq-muted-fg); font-size: 15px;
}

/* Feedback permissions, previously visible only inside the Edit form. On/off is
   carried by the tick/dash icon and the text weight, not by colour alone. */
.sq-flags { display: flex; flex-wrap: wrap; gap: 6px; }
.sq-flag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--sq-border); background: var(--sq-card);
  font-size: 12px; color: var(--sq-muted-fg); white-space: nowrap;
}
.sq-flag i { font-size: 9px; }
.sq-flag.is-on {
  border-color: var(--sq-accent); color: var(--sq-accent);
  background: var(--sq-accent-050); font-weight: 600;
}
body.dark-mode .sq-flag.is-on { color: #6EE7B7; background: rgba(5,150,105,.14); }

.sq-copy.is-copied { border-color: var(--sq-accent); color: var(--sq-accent) !important; }
.sq-copy i { margin-right: 5px; }

.sq-alert--info { border-left-color: var(--sq-primary); }
.sq-alert--info > i { color: var(--sq-primary); font-size: 16px; margin-top: 2px; }
.sq-alert--wide { max-width: none; align-items: center; }
.sq-alert--wide .btn { margin-left: auto; }

.sq-empty--tight { padding: var(--sq-space-4) var(--sq-space-3); }
.sq-teams td:last-child, .sq-teams th:last-child { text-align: right; }
.sq-teams .sq-actions { justify-content: flex-end; }
.sq-teams .sq-person__name .sq-badge { margin-left: 6px; vertical-align: 1px; }

.sq-invitechip {
  display: grid; place-items: center; flex: none;
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--sq-muted); color: var(--sq-muted-fg); font-size: 14px;
}
/* Age is the reason you are on this page; a stale invite says so in words and
   an icon, not by colour alone. */
.sq-age { font-size: 13px; color: var(--sq-muted-fg); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sq-age.is-stale { color: var(--sq-warning); font-weight: 600; }
.sq-age i { margin-right: 4px; font-size: 11px; }

.sq-alert--warn { border-left-color: var(--sq-warning); }
.sq-alert--warn > i { color: var(--sq-warning); font-size: 16px; margin-top: 2px; }

.sq-invites td:last-child, .sq-invites th:last-child { text-align: right; }
.sq-invites .sq-actions { justify-content: flex-end; }
.sq-invites th:nth-child(3), .sq-invites td:nth-child(3) { width: 120px; }
.sq-toolbar__search select.form-control { width: auto; min-width: 150px; }

/* Award art picker — a labelled choice grid rather than bare images whose only
   name lived in a title tooltip. Survives the art being absent. */
.sq-artgrid { display: grid; gap: var(--sq-space-2); grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
.sq-art { position: relative; margin: 0; cursor: pointer; }
.sq-art input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.sq-art__body {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; min-height: 84px; height: 100%; padding: var(--sq-space-2);
  border: 1px solid var(--sq-border); border-radius: var(--sq-radius);
  background: var(--sq-card); text-align: center;
  transition: border-color var(--sq-transition), background var(--sq-transition);
}
.sq-art__body img { max-height: 56px; width: auto; }
.sq-art__name { font-size: 13px; font-weight: 500; color: var(--sq-fg); line-height: 1.3; }
.sq-art:hover .sq-art__body { border-color: var(--sq-muted-fg); }
.sq-art input:checked + .sq-art__body {
  border-color: var(--sq-primary); background: var(--sq-primary-050);
  box-shadow: inset 0 0 0 1px var(--sq-primary);
}
.sq-art input:checked + .sq-art__body .sq-art__name { font-weight: 700; }
.sq-art input:focus-visible + .sq-art__body { outline: 2px solid var(--sq-ring); outline-offset: 2px; }

/* Inline radio pair with the input before its label, and a target you can hit. */
.sq-radiorow { display: flex; flex-wrap: wrap; gap: var(--sq-space-3); }
.sq-radio { display: inline-flex; align-items: center; gap: 7px; margin: 0; cursor: pointer; font-weight: 500; }
.sq-radio input { width: 16px; height: 16px; margin: 0; accent-color: var(--sq-primary); cursor: pointer; }
.sq-radio span { font-size: 14px; color: var(--sq-fg); }
.sq-radio input:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; }

/* --- API tokens ---------------------------------------------------------- */
.sq-tokenchip {
  display: grid; place-items: center; flex: none;
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--sq-muted); color: var(--sq-muted-fg); font-size: 14px;
}
.sq-tokens tr.is-expired .sq-person__name { color: var(--sq-muted-fg); }
.sq-tokens td:last-child, .sq-tokens th:last-child { text-align: right; }
.sq-inlineform { display: inline; }

.sq-alert--success { border-left-color: var(--sq-accent); }
.sq-alert--success > i { color: var(--sq-accent); font-size: 16px; margin-top: 2px; }
.sq-token-reveal__body { flex: 1; min-width: 0; }

/* The token value is shown exactly once, so it has to be readable and
   selectable, not truncated into a decorative pill. */
.sq-tokenbox {
  display: flex; align-items: center; gap: var(--sq-space-2);
  margin-top: var(--sq-space-2); padding: var(--sq-space-2);
  background: var(--sq-muted); border: 1px solid var(--sq-border); border-radius: 8px;
}
.sq-tokenbox code {
  flex: 1; min-width: 0;
  font-size: 12px; line-height: 1.5; color: var(--sq-fg);
  word-break: break-all; user-select: all; background: none; padding: 0;
}
.sq-tokenbox .btn { flex: none; }

/* ===========================================================================
   Edit form pages — update behaviour / award / team / member, and profile.
   These are reached straight from lists that were already rebuilt, so they had
   to stop looking like a different application. One shape for all of them:
   a bounded column, real labels, and a footer where Save and Cancel differ.
   =========================================================================== */
/* Two fields side by side. Everything else here reuses the .sq-form component
   defined above rather than redefining it. */
.sq-formgrid { display: grid; gap: var(--sq-space-3); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.sq-formgrid .sq-field { margin-bottom: 0; }

/* Save is the primary and Cancel a quiet way out; they used to be identical. */
.sq-form__actions--end { justify-content: flex-end; padding-top: var(--sq-space-3); border-top: 1px solid var(--sq-border); }

/* Native colour input beats a hex text field: it is a real picker, keyboard
   operable, and cannot be typed into an invalid state. The hex stays visible
   beside it because that is what gets stored and pasted. */
.sq-colorfield { display: flex; align-items: center; gap: var(--sq-space-2); }
.sq-colorfield input[type="color"] {
  flex: none; width: 46px; height: 40px; padding: 3px;
  background: var(--sq-card); border: 1px solid var(--sq-border);
  border-radius: 8px; cursor: pointer;
}
.sq-colorfield input[type="color"]:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
.sq-colorfield input[type="text"] { width: 120px; font-variant-numeric: tabular-nums; }

/* Current image, with the file input beside it rather than a bare "Old Image"
   label above an orphaned thumbnail. */
.sq-imagefield { display: flex; align-items: center; gap: var(--sq-space-3); flex-wrap: wrap; }
.sq-imagefield__preview {
  flex: none; width: 64px; height: 64px; border-radius: 12px;
  display: grid; place-items: center; overflow: hidden;
  background: var(--sq-muted); color: var(--sq-muted-fg); font-size: 20px;
  border: 1px solid var(--sq-border);
}
.sq-imagefield__preview img { width: 100%; height: 100%; object-fit: cover; }
.sq-imagefield__input { flex: 1 1 220px; min-width: 0; }

/* Settings expressed as explained choices rather than bare checkboxes whose
   consequences lived only in the developer's head. */
.sq-switchlist { display: grid; gap: var(--sq-space-2); }
.sq-switch { position: relative; margin: 0; cursor: pointer; }
.sq-switch input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.sq-switch__body {
  display: flex; gap: var(--sq-space-2); align-items: flex-start;
  padding: var(--sq-space-2) var(--sq-space-3);
  border: 1px solid var(--sq-border); border-radius: var(--sq-radius);
  background: var(--sq-card);
  transition: border-color var(--sq-transition), background var(--sq-transition);
}
.sq-switch:hover .sq-switch__body { border-color: var(--sq-muted-fg); }
.sq-switch input:checked + .sq-switch__body {
  border-color: var(--sq-primary); background: var(--sq-primary-050);
  box-shadow: inset 0 0 0 1px var(--sq-primary);
}
.sq-switch input:focus-visible + .sq-switch__body { outline: 2px solid var(--sq-ring); outline-offset: 2px; }
.sq-switch__mark {
  flex: none; width: 18px; height: 18px; margin-top: 1px; border-radius: 5px;
  border: 1px solid var(--sq-border); background: var(--sq-card);
  display: grid; place-items: center; color: transparent; font-size: 10px;
}
.sq-switch input:checked + .sq-switch__body .sq-switch__mark {
  background: var(--sq-primary); border-color: var(--sq-primary); color: #fff;
}
.sq-switch__name { display: block; font-size: 14px; font-weight: 600; color: var(--sq-fg); }
.sq-switch__desc { display: block; margin-top: 2px; font-size: 13px; line-height: 1.45; color: var(--sq-muted-fg); }

/* Behaviour colour, shown in the list because it is what identifies the
   behaviour everywhere else it appears. */
.sq-swatch {
  display: block; flex: none; width: 36px; height: 36px;
  border-radius: 10px; border: 1px solid rgba(255,255,255,.18);
}
.sq-behaviours th:nth-child(2), .sq-behaviours td:nth-child(2) { width: 120px; }
.sq-behaviours td:last-child, .sq-behaviours th:last-child { text-align: right; }
.sq-behaviours .sq-actions { justify-content: flex-end; }

/* ===========================================================================
   Ranked "Top N" lists — emotions, awards, behaviours.
   These were grids of 100px images with the count buried inside a blue
   progress bar and the NAME shown nowhere at all, so with the artwork missing
   every card was an identical blank square. A ranked comparison wants the
   category and the value written down, sorted, with the bar as reinforcement.
   =========================================================================== */
.sq-ranklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; counter-reset: rank; }

.sq-rankrow {
  display: grid; align-items: center; gap: var(--sq-space-2);
  grid-template-columns: 20px minmax(0, 1.1fr) minmax(0, 1fr) auto;
  padding: 7px var(--sq-space-2);
  border-radius: 8px;
  transition: background var(--sq-transition);
}
.sq-rankrow:hover { background: var(--sq-muted); }
.sq-rankrow__pos {
  font-size: 11px; font-weight: 700; color: var(--sq-muted-fg);
  font-variant-numeric: tabular-nums; text-align: right;
}
.sq-rankrow__name {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  font-size: 14px; font-weight: 600; color: var(--sq-fg);
}
.sq-rankrow__name > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-rankrow__dot { flex: none; width: 9px; height: 9px; border-radius: 999px; }
.sq-rankrow__dot[hidden] { display: none; }

/* Emotion emoji / award artwork, restored from the original image grids.
   The emotion art is a face plus its ±points (green positive, red negative),
   shown whole at a fixed size rather than cropped into a circle. */
.sq-rankrow__emoji {
  flex: none; width: 40px; height: 44px;
  object-fit: contain;
}
.sq-rankrow__emoji[hidden] { display: none; }
/* The artwork takes 36px of the name column; give that column the width back
   so names are not cut to a few letters. */
.sq-rankrow:has(.sq-rankrow__emoji:not([hidden])) {
  grid-template-columns: 20px minmax(0, 1.6fr) minmax(0, 1fr) auto;
}
/* The positive artwork's green is dark enough to fall under 3:1 on the dark
   card. Lift it in dark mode only; the red already reads on both themes. */
body.dark-mode .sq-rankrow__emoji--pos { filter: brightness(1.6) saturate(1.1); }
@media (max-width: 639.98px) {
  /* Phones: name and emoji take the full row, cells/bar and count drop below,
     so a long emotion name is not squeezed to a few characters. */
  .sq-rankrow,
  .sq-rankrow:has(.sq-rankrow__emoji:not([hidden])) { grid-template-columns: 20px minmax(0, 1fr) auto; row-gap: 6px; }
  .sq-rankrow__name { grid-column: 2 / 4; }
  .sq-cells, .sq-rankrow__bar { grid-column: 2 / 3; }
  .sq-rankrow__emoji { width: 36px; height: 40px; }
}

/* Unit cells: one per occurrence. A max-scaled bar drew every row full width
   whenever all the counts matched, which is most lists in a young team. */
.sq-cells { display: flex; flex-wrap: wrap; gap: 3px; align-items: center; }
.sq-cells > span { width: 10px; height: 10px; border-radius: 3px; }

/* Kept for lists whose counts have outgrown one cell each. */
.sq-rankrow__bar { height: 6px; border-radius: 999px; background: var(--sq-muted); overflow: hidden; }
.sq-rankrow__bar > span { display: block; height: 100%; border-radius: 999px; }

.sq-rankrow__val { display: flex; align-items: baseline; gap: 7px; justify-content: flex-end; }
.sq-rankrow__count { font-size: 14px; font-weight: 700; color: var(--sq-fg); font-variant-numeric: tabular-nums; }
.sq-rankrow__share { font-size: 12px; color: var(--sq-muted-fg); font-variant-numeric: tabular-nums; min-width: 4ch; text-align: right; }

/* The mix across the whole card, so proportion survives even when every row
   holds the same count. */
.sq-mixbar {
  display: flex; gap: 2px; height: 8px;
  margin: 0 var(--sq-space-2) var(--sq-space-3);
  border-radius: 999px; overflow: hidden; background: var(--sq-muted);
}
.sq-mixbar > span { display: block; min-width: 3px; }

/* Comments were behind a "See Details" button that opened one modal PER ITEM —
   up to thirty modals rendered into a dashboard nobody had opened yet. A native
   disclosure keeps them in place, needs no JavaScript, and is keyboard operable
   for free. */
.sq-rankitem > summary { list-style: none; cursor: pointer; }
.sq-rankitem > summary::-webkit-details-marker { display: none; }
.sq-rankitem > summary:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: -2px; border-radius: 8px; }
.sq-rankitem[open] > summary .sq-rankrow { background: var(--sq-muted); }
.sq-rankrow__more {
  flex: none; font-size: 11px; color: var(--sq-muted-fg);
  display: inline-flex; align-items: center; gap: 4px;
}
.sq-rankitem[open] .sq-rankrow__more i { transform: rotate(180deg); }
.sq-rankrow__more i { transition: transform var(--sq-transition); }

.sq-comments {
  margin: 0 0 var(--sq-space-2);
  padding: var(--sq-space-2) var(--sq-space-3) var(--sq-space-2) 42px;
  list-style: none;
}
.sq-comments li {
  position: relative; padding: 5px 0;
  font-size: 13px; line-height: 1.5; color: var(--sq-muted-fg);
}
.sq-comments li::before {
  content: ""; position: absolute; left: -14px; top: 12px;
  width: 5px; height: 5px; border-radius: 999px; background: var(--sq-border);
}

/* Period-summary cards: two metrics that are NOT the same unit, so they get
   their own labels rather than two unlabelled gauges showing the same digits. */
.sq-summary { display: grid; gap: var(--sq-space-2); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.sq-summary__card {
  padding: var(--sq-space-3);
  background: var(--sq-card); border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius); box-shadow: var(--sq-shadow);
}
.sq-summary__head { display: flex; align-items: baseline; gap: var(--sq-space-1); margin-bottom: var(--sq-space-3); }
.sq-summary__count { font-size: 26px; font-weight: 700; line-height: 1; color: var(--sq-fg); font-variant-numeric: tabular-nums; }
.sq-summary__label { font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--sq-muted-fg); }
.sq-metric + .sq-metric { margin-top: var(--sq-space-3); }
.sq-metric__top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sq-space-2); }
.sq-metric__name { font-size: 13px; font-weight: 600; color: var(--sq-fg); }
.sq-metric__value { font-size: 15px; font-weight: 700; color: var(--sq-fg); font-variant-numeric: tabular-nums; }
.sq-metric__bar { height: 6px; margin-top: 6px; border-radius: 999px; background: var(--sq-muted); overflow: hidden; }
.sq-metric__bar > span { display: block; height: 100%; border-radius: 999px; background: var(--sq-primary); }
.sq-metric__hint { margin: 5px 0 0; font-size: 12px; line-height: 1.45; color: var(--sq-muted-fg); }

/* Paired list cards: the card body centres its content vertically, which is
   right for a chart but leaves the shorter of two ranked lists floating half
   way down while its partner starts at the top. Lists start at the top. */
.sq-chart-row > .card > .card-body:has(.sq-ranklist),
.sq-chart-row > .card > .card-body:has(.sq-delta-grid),
.sq-chart-row > .card > .card-body:has(.sq-empty) { justify-content: flex-start; }

/* --- Standings -----------------------------------------------------------
   Top 3 and Lowest 3 were two stacked cards using different column widths for
   the same thing, each a row of 60px profile photos that were usually missing.
   One card, two columns, initials instead of broken images. */
.sq-standings { display: grid; gap: var(--sq-space-4); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.sq-standings__title {
  display: flex; align-items: center; gap: 7px;
  margin: 0 0 var(--sq-space-2);
  font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--sq-muted-fg);
}
.sq-standings__title i { font-size: 12px; }
.sq-standings__title--pos i { color: var(--sq-accent); }
.sq-standings__title--neg i { color: var(--sq-danger); }
body.dark-mode .sq-standings__title--pos i { color: #34D399; }
body.dark-mode .sq-standings__title--neg i { color: #F87171; }

.sq-standings__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.sq-standings__empty { margin: 0; font-size: 13px; color: var(--sq-muted-fg); }

.sq-standing {
  display: flex; align-items: center; gap: var(--sq-space-2);
  padding: 8px var(--sq-space-2);
  border-radius: 8px; color: inherit; text-decoration: none;
  transition: background var(--sq-transition);
}
.sq-standing:hover { background: var(--sq-muted); color: inherit; }
.sq-standing:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: -2px; }
.sq-standing__name { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; color: var(--sq-fg);
                     overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-standing__pts { font-size: 14px; font-weight: 700; color: var(--sq-muted-fg); font-variant-numeric: tabular-nums; }
.sq-standing__pts.is-pos { color: var(--sq-accent); }
.sq-standing__pts.is-neg { color: var(--sq-danger); }
body.dark-mode .sq-standing__pts.is-pos { color: #34D399; }
body.dark-mode .sq-standing__pts.is-neg { color: #F87171; }

/* Initials stand in for a photo that is optional and frequently absent. */
.sq-initials {
  flex: none; display: grid; place-items: center;
  width: 32px; height: 32px; border-radius: 999px;
  background: var(--sq-primary-050); color: var(--sq-primary);
  font-size: 13px; font-weight: 700;
}
body.dark-mode .sq-initials { color: #C7D2FE; }

/* ===========================================================================
   Member cards, per-behaviour ranking and head-to-head compare.
   =========================================================================== */

/* Two buttons in the page head instead of one. */
.sq-pagehead__actions { display: flex; gap: var(--sq-space-1); flex-wrap: wrap; }
.sq-pagehead__actions .btn i { margin-right: 6px; }

/* List / cards switch ------------------------------------------------------
   Segmented control: the two options sit in one track so they read as one
   choice rather than two unrelated buttons. */
.sq-viewtoggle {
  display: inline-flex; margin-bottom: var(--sq-space-2);
  background: var(--sq-muted); border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius); padding: 3px; gap: 3px;
}
.sq-viewtoggle__btn {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  padding: 6px 14px; border-radius: calc(var(--sq-radius) - 4px);
  font-size: 13px; font-weight: 600; color: var(--sq-muted-fg);
  display: inline-flex; align-items: center; gap: 6px;
  transition: background var(--sq-transition), color var(--sq-transition);
}
.sq-viewtoggle__btn:hover { color: var(--sq-fg); }
.sq-viewtoggle__btn.is-active { background: var(--sq-card); color: var(--sq-fg); box-shadow: var(--sq-shadow); }
.sq-viewtoggle__btn:focus-visible { outline: 2px solid var(--sq-ring); outline-offset: 1px; }
body.dark-mode .sq-viewtoggle { background: #0F172A; border-color: #1E293B; }
body.dark-mode .sq-viewtoggle__btn.is-active { background: #1E293B; color: #E2E8F0; }

/* Member cards -------------------------------------------------------------
   auto-fill rather than a fixed column count: a team of three should not leave
   two empty columns, and a team of thirty should use the width it has. */
.sq-cardgrid {
  display: grid; gap: var(--sq-space-3);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.sq-membercard {
  display: flex; flex-direction: column; gap: var(--sq-space-2);
  padding: var(--sq-space-3);
  background: var(--sq-card); border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius); box-shadow: var(--sq-shadow);
}
.sq-membercard__head { display: flex; align-items: flex-start; gap: var(--sq-space-2); }
.sq-membercard__head img { flex: none; width: 56px; height: 56px; border-radius: 999px; object-fit: cover; }
.sq-membercard__who { min-width: 0; flex: 1; }
.sq-membercard__name { margin: 0; font-size: 16px; font-weight: 700; color: var(--sq-fg);
                       overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-membercard__role { margin: 2px 0 0; font-size: 13px; font-weight: 600; color: var(--sq-muted-fg); }
.sq-membercard__mail { margin: 0; font-size: 12px; color: var(--sq-muted-fg);
                       overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-membercard__head .sq-rank { flex: none; }

.sq-membercard__stats { display: grid; grid-template-columns: auto 1fr; gap: var(--sq-space-1) var(--sq-space-3); margin: 0; }
.sq-membercard__stats > div { display: contents; }
.sq-membercard__stats dt { font-size: 12px; font-weight: 600; color: var(--sq-muted-fg); text-transform: uppercase; letter-spacing: .04em; align-self: center; }
.sq-membercard__stats dd { margin: 0; align-self: center; }

.sq-membercard__teams { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sq-membercard__teamlabel { font-size: 12px; font-weight: 600; color: var(--sq-muted-fg); text-transform: uppercase; letter-spacing: .04em; }
.sq-chip {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  background: var(--sq-primary-050); color: var(--sq-primary-600);
  border: 1px solid transparent; font-size: 12px; font-weight: 600;
}
body.dark-mode .sq-chip { background: #1E1B4B; color: #A5B4FC; border-color: #312E81; }

.sq-membercard__foot { display: flex; gap: 6px; flex-wrap: wrap; margin-top: auto; padding-top: var(--sq-space-1); border-top: 1px solid var(--sq-border); }
body.dark-mode .sq-membercard { background: #111827; border-color: #1F2937; }
body.dark-mode .sq-membercard__foot { border-top-color: #1F2937; }

/* Per-behaviour ranking ----------------------------------------------------
   The +/- split sits next to the count because a high count is not
   automatically a good one, and the two are only meaningful together. */
.sq-split { display: inline-flex; align-items: center; gap: 4px; font-variant-numeric: tabular-nums; font-weight: 600; }
.sq-split__pos { color: var(--sq-accent); }
.sq-split__neg { color: var(--sq-danger); }
.sq-split__sep { color: var(--sq-muted-fg); font-weight: 400; }
body.dark-mode .sq-split__pos { color: #34D399; }
body.dark-mode .sq-split__neg { color: #F87171; }

.sq-compare-pick { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; font-weight: 600; color: var(--sq-muted-fg); cursor: pointer; }
.sq-compare-pick input { margin: 0; }

/* Sticks to the bottom so the action stays reachable without scrolling back
   up after picking someone near the end of the list. */
.sq-compare-bar {
  position: sticky; bottom: 0; z-index: 2;
  display: flex; align-items: center; justify-content: flex-end; gap: var(--sq-space-2);
  margin-top: var(--sq-space-2); padding: var(--sq-space-2);
  background: var(--sq-card); border: 1px solid var(--sq-border);
  border-radius: var(--sq-radius); box-shadow: var(--sq-shadow-lg);
  font-size: 13px; font-weight: 600; color: var(--sq-muted-fg);
}
body.dark-mode .sq-compare-bar { background: #111827; border-color: #1F2937; }

/* Head-to-head -------------------------------------------------------------- */
.sq-compare-picker { display: grid; gap: var(--sq-space-2); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); align-items: end; }
.sq-compare-picker .form-group { margin-bottom: 0; }

.sq-compare th[scope="col"] { vertical-align: bottom; }
.sq-compare th[scope="row"] { font-size: 13px; font-weight: 600; color: var(--sq-muted-fg); white-space: nowrap; }
.sq-compare td { font-variant-numeric: tabular-nums; }
.sq-compare td.is-lead .sq-compare__val { font-weight: 700; color: var(--sq-fg); }
.sq-compare__flag { margin-left: 6px; color: var(--sq-accent); }
body.dark-mode .sq-compare td.is-lead .sq-compare__val { color: #E2E8F0; }
body.dark-mode .sq-compare__flag { color: #34D399; }

.sq-person--stacked { flex-direction: column; align-items: flex-start; gap: 6px; text-align: left; }
.sq-person--stacked img { width: 48px; height: 48px; }

.sq-taglist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.sq-taglist li { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.sq-swatch--sm { width: 10px; height: 10px; }

/* The tour's "hide all guides" button. Set apart from Back/Next so it never
   gets clicked by someone reaching for the primary action. */

/* ===========================================================================
   MOBILE  (<768px)
   Every list in this app was a table with a 720px min-width sitting in a
   ~325px window. It scrolled, but nothing said so, and the right-hand column
   — always the actions: Open, Settings, Give feedback, Delete — was the part
   that fell off the edge. So on a phone the lists were read-only by accident.

   Below 768px each row becomes its own card: first cell is the heading, every
   other cell is a label/value pair taken from the <thead> (data-label is
   filled in by sqLabelTables() in squadli-ui.js), and the actions sit at the
   bottom at a thumb-sized height. Nothing scrolls sideways, nothing is hidden.

   .sq-compare opts out: it is a measure-by-person matrix, not a list, and
   stacking it would destroy the comparison. It keeps its horizontal scroll.
   =========================================================================== */
@media (max-width: 767.98px) {

  .sq-table:not(.sq-compare) { display: block; min-width: 0; }
  .sq-table:not(.sq-compare) thead { display: none; }
  .sq-table:not(.sq-compare) tbody,
  .sq-table:not(.sq-compare) tbody tr,
  .sq-table:not(.sq-compare) tbody td { display: block; width: auto; }

  .sq-table:not(.sq-compare) tbody tr {
    margin-bottom: var(--sq-space-2);
    padding: var(--sq-space-2) 0;
    border: 1px solid var(--sq-border);
    border-radius: var(--sq-radius);
    background: var(--sq-card);
  }
  .sq-table:not(.sq-compare) tbody tr:hover { background: var(--sq-card); }

  .sq-table:not(.sq-compare) tbody td {
    padding: 6px var(--sq-space-3);
    border-bottom: 0;
    text-align: left;
    width: auto !important;   /* beats the per-column widths set for desktop */
  }

  /* Label/value pair. The label is the column header it lost. */
  .sq-table:not(.sq-compare) tbody td[data-label] {
    display: grid;
    grid-template-columns: minmax(84px, 38%) 1fr;
    gap: var(--sq-space-2);
    align-items: center;
    /* A grid item stretches by default, which turned every badge, chip and
       button into a full-width block. Anything that genuinely wants the width
       asks for it below. */
    justify-items: start;
  }
  .sq-table:not(.sq-compare) tbody td[data-label] > .sq-meter,
  .sq-table:not(.sq-compare) tbody td[data-label] > .form-control { width: 100%; }
  .sq-table:not(.sq-compare) tbody td[data-label]::before {
    content: attr(data-label);
    font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
    color: var(--sq-muted-fg);
  }

  /* First cell is who/what the row is about — it reads as the card title, so
     it keeps the full width and drops its label. */
  .sq-table:not(.sq-compare) tbody td:first-child {
    display: block;
    padding-bottom: var(--sq-space-2);
    margin-bottom: 2px;
    border-bottom: 1px solid var(--sq-border);
  }
  .sq-table:not(.sq-compare) tbody td:first-child::before { content: none; }

  /* Columns hidden for want of width on desktop are worth showing again once
     each row has a whole card to itself. */
  .sq-roster tbody td:nth-child(4) { display: grid; }

  /* The roster's first cell is the rank chip, not a title, so it gets no rule
     under it — the member's name on the next line is the real heading. */
  .sq-roster tbody td:first-child { border-bottom: 0; padding-bottom: 0; }

  /* Long values (emails, invite URLs) must wrap inside their column rather
     than push the card wide. */
  /* Everything in the cell stacks under the value column; a cell with two
     badges in it (Account: "Team leader" + "Unverified") must not drop its
     second one back under the label. */
  .sq-table:not(.sq-compare) tbody td[data-label] > * { min-width: 0; grid-column: 2; }
  .sq-table:not(.sq-compare) .sq-person { min-width: 0; }
  .sq-table:not(.sq-compare) .sq-person__name,
  .sq-table:not(.sq-compare) .sq-person__sub { overflow-wrap: anywhere; }

  /* Actions: left-aligned, wrapped, thumb-sized. */
  .sq-table:not(.sq-compare) .sq-actions {
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: var(--sq-space-1);
  }
  .sq-table:not(.sq-compare) .sq-actions .btn,
  .sq-table:not(.sq-compare) .sq-actions .sq-iconbtn,
  .sq-table:not(.sq-compare) .btn.btn-sm {
    min-height: 40px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .sq-table:not(.sq-compare) .sq-actions .sq-iconbtn { min-width: 40px; }

  .sq-table:not(.sq-compare) select.form-control { width: 100%; min-width: 0; }
  .sq-table:not(.sq-compare) .sq-meter { min-width: 0; }

  /* The comparison matrix does not stack — it is measure-by-person, and
     splitting the two people apart is the one thing it must not do. Instead it
     is tightened until three columns fit, so it needs no sideways scroll. */
  .sq-compare { min-width: 0; font-size: 13px; }
  .sq-compare th, .sq-compare td { padding: 8px 10px; }
  .sq-compare thead img { width: 36px; height: 36px; }
  .sq-compare .sq-person__sub { display: none; }

  /* Toolbars: the search box was a fixed 240px next to a 150px select and a
     button, in a flex row that could not wrap, so Search fell off the edge. */
  .sq-toolbar__search { flex-wrap: wrap; width: 100%; }
  .sq-toolbar__search .form-control,
  .sq-toolbar__search select.form-control { width: 100%; min-width: 0; flex: 1 1 100%; }
  .sq-toolbar__search .btn { flex: 1 1 100%; }
  .sq-toolbar > * { min-width: 0; }
  .sq-toolbar__cta { margin-left: 0; width: 100%; }

  /* intro.js renders the tooltip INSIDE .introjs-tooltipReferenceLayer, which it
     positions over the highlighted element — so `left` on the tooltip is
     relative to the highlight, not to the screen. The dashboard guide's first
     step points at #profile-section, which on a phone is in the off-canvas
     sidebar at left:-250px, and the tooltip went off the left edge with it,
     taking the Next button with it and stranding the tour.

     Fixing the tooltip to the viewport as a bottom sheet is the only position
     that does not depend on where the highlight landed. */
  .introjs-tooltip {
    position: fixed !important;
    left: 12px !important;
    right: 12px !important;
    top: auto !important;
    bottom: 12px !important;
    width: auto !important;
    max-width: none !important;
    min-width: 0 !important;
    transform: none !important;
  }
  /* An arrow pointing at something off-screen points at nothing. */
  .introjs-arrow { display: none; }
  .introjs-tooltipbuttons { flex-wrap: wrap; }
}

/* Coarse pointers get a real target on the chrome controls too: these were
   24-34px squares sized for a mouse. */
@media (pointer: coarse) {
  .sq-chrome-btn, .sq-iconbtn { min-width: 40px; min-height: 40px; }
  .sq-btn--sm { min-height: 40px; }
}

/* ======================  PHONE PICKER (bottom sheet)  ===================== */
/* See the "Phone picker" block in squadli-ui.js. Only ever rendered on touch
   screens; desktop keeps the native dropdown. */
.sq-picker-native {
  position: absolute !important; width: 1px !important; height: 1px !important;
  padding: 0 !important; margin: -1px !important; overflow: hidden !important;
  clip: rect(0 0 0 0) !important; border: 0 !important; opacity: 0;
}
.sq-picker {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-height: 44px; height: auto; text-align: left; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sq-picker__label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-picker__chevron { flex: 0 0 auto; font-size: 12px; color: var(--sq-muted-fg); }

body.sq-sheet-open { position: fixed; left: 0; right: 0; overflow: hidden; }

.sq-sheet { position: fixed; inset: 0; z-index: 2060; }
.sq-sheet[hidden] { display: none; }
.sq-sheet__backdrop {
  position: absolute; inset: 0; background: rgba(15, 18, 24, .55);
  animation: sqFade 140ms ease-out;
}
.sq-sheet__panel {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; flex-direction: column;
  /* dvh tracks Safari's shrinking/growing toolbar; vh is the fallback. */
  max-height: 85vh; max-height: 85dvh;
  background: var(--sq-card); color: var(--sq-fg);
  border-top: 1px solid var(--sq-border);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -12px 32px -8px rgba(0,0,0,.35);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  animation: sqSheetUp 200ms cubic-bezier(.2,.9,.3,1);
}
@keyframes sqSheetUp { from { transform: translateY(24px); opacity: 0 } to { transform: none; opacity: 1 } }
@media (prefers-reduced-motion: reduce) {
  .sq-sheet__backdrop, .sq-sheet__panel { animation: none; }
}
@media (min-width: 768px) {
  /* Tablets: a centred card reads better than a full-width strip. */
  .sq-sheet__panel { left: 50%; right: auto; bottom: auto; top: 10vh; width: 480px;
                     transform: translateX(-50%); border-radius: 14px; border: 1px solid var(--sq-border);
                     max-height: 80vh; animation: none; }
}
.sq-sheet--tall .sq-sheet__panel { height: 85vh; height: 85dvh; }
@media (min-width: 768px) { .sq-sheet--tall .sq-sheet__panel { height: 80vh; } }
.sq-sheet__grip { width: 40px; height: 5px; border-radius: 3px; background: var(--sq-border); margin: 8px auto 0; }
.sq-sheet__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 8px 8px 20px; }
.sq-sheet__title { margin: 0; font-size: 17px; font-weight: 600; color: var(--sq-fg); }
.sq-sheet__close {
  width: 44px; height: 44px; border: 0; border-radius: 50%; background: transparent;
  color: var(--sq-muted-fg); font-size: 18px; display: grid; place-items: center;
}
.sq-sheet__close:active { background: var(--sq-muted); }
.sq-sheet__search { position: relative; padding: 0 16px 10px; }
.sq-sheet__search[hidden] { display: none; }
.sq-sheet__search i { position: absolute; left: 30px; top: 15px; color: var(--sq-muted-fg); font-size: 14px; pointer-events: none; }
.sq-sheet__search input {
  width: 100%; min-height: 44px; padding: 10px 12px 10px 40px;
  font: inherit; font-size: 16px; /* 16px stops iOS zooming the page on focus */
  color: var(--sq-fg); background: var(--sq-muted);
  border: 1px solid var(--sq-border); border-radius: 10px; -webkit-appearance: none; appearance: none;
}
.sq-sheet__list {
  list-style: none; margin: 0; padding: 0 8px 12px;
  overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  flex: 1 1 auto; min-height: 0;
}
.sq-sheet__list li[hidden] { display: none; }
.sq-sheet__option {
  display: flex; align-items: center; width: 100%; min-height: 48px;
  padding: 12px 44px 12px 14px; position: relative;
  font: inherit; font-size: 16px; line-height: 1.3; text-align: left;
  color: var(--sq-fg); background: transparent; border: 0; border-radius: 10px;
  overflow-wrap: anywhere; -webkit-tap-highlight-color: transparent;
}
.sq-sheet__option:active { background: var(--sq-muted); }
.sq-sheet__option.is-selected { font-weight: 600; color: var(--sq-primary-600); background: var(--sq-primary-050); }
body.dark-mode .sq-sheet__option.is-selected { color: #C7D2FE; }
.sq-sheet__option.is-selected::after {
  content: "\f00c"; font-family: "Font Awesome 5 Free"; font-weight: 900;
  position: absolute; right: 16px; top: 50%; transform: translateY(-50%); font-size: 14px;
}
.sq-sheet__empty { margin: 0; padding: 16px 20px 24px; color: var(--sq-muted-fg); font-size: 15px; text-align: center; }

/* ===========================  iPhone basics  ============================== */
/* iOS Safari zooms the whole page in when you tap a field whose text is under
   16px, and does not zoom back out. Scoped to iOS so desktop sizes stay. */
@supports (-webkit-touch-callout: none) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select, textarea { font-size: max(16px, 1em) !important; }
}
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
