/* ============================================================================
   Team surface — the /team route inside the app shell.

   Replaces team-dashboard.css and create-team.css, which styled two standalone
   pages with their own header, their own container width and their own card
   language. This surface is the workspace panel showing something else, so it
   borrows the panel's grammar rather than inventing a third one: white cards on
   the tinted panel, hairline borders, the same radii and insets the workspace
   grid uses.

   Horizontal insets are NOT set here — .container already picks up
   --app-shell-inset-x from app-shell.css on every shell surface. Setting them
   again would double them on this route only.

   The td-* class names are carried over from the retired dashboard so the ported
   js/team-surface.js keeps rendering the same markup. Only their appearance is new.
   ============================================================================ */

#team-surface .container {
  padding-bottom: var(--app-shell-inset);
}

/* Hiding actually hides, on this surface.
   components.css defines `.hidden { display: none }` and this stylesheet is linked
   after it, so every `display: flex` / `display: grid` rule below - all at the same
   (0,0,1,0) specificity - was winning on source order and un-hiding its own element.
   Two of them were doing real damage in production: `.td-first-member-prompt` meant
   every team saw the dashed "You're the only one here" panel no matter how many
   members it had, and `.td-hero-name-edit` meant the rename field, Save and Cancel
   sat permanently under the team name. The same trap applies to the `hidden`
   *attribute*, which an author `display` also beats - hence both selectors. */
#team-surface .hidden,
#team-surface [hidden] {
  display: none !important;
}

/* ------------------------------------------------------------ page header --- */

/* Left-aligned, like the brand header and unlike the workspace greeting: this is a
   label for the content beneath it, not a line addressed to the person reading it. */
/* Top inset. The workspace gets this in two parts — a .shell-pagehead-top spacer of
   --app-shell-inset, then the header's own 34px — which lands its first line 87px below
   the panel edge. This surface has no spacer element, so it was starting at 39px and
   sat visibly higher than every other shell route. Same two numbers, one declaration.
   Applies to invite / create / dashboard. The upsell hero takes the inset itself so
   both columns share it — see .team-hero. */
.team-pagehead {
  padding-top: calc(var(--app-shell-inset) + 34px);
  padding-bottom: var(--spacing-lg);
}
.team-pagehead--row {
  display: flex;
  align-items: center;
  gap: var(--spacing-lg);
}
.team-pagehead-main {
  flex: 1 1 auto;
  min-width: 0;
}
.team-pagehead-actions {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  flex-shrink: 0;
}

/* ------------------------------------------------------ team identity block --- */

.td-identity {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  flex: 1 1 auto;
  min-width: 0;
}

/* A team is a thing you belong to, so the page opens with a mark for it rather than
   with a line of text. Square-ish, not round: round reads as a person. */
.td-monogram {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: var(--radius-lg);
  background: var(--primary-subtle);
  color: var(--primary-dark);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
}

.td-meta-chips {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 8px 0 0;
}
.td-meta-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background: var(--surface-wash);
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}
/* The role is the one fact on the row that changes what you can do, so it is the one
   chip that carries colour. Same tint as the Owner badge in the members table. */
.td-meta-chip--role {
  background: rgba(var(--primary-rgb), 0.12);
  color: var(--primary-dark);
  font-weight: var(--weight-semibold);
}

/* ------------------------------------------------------------- overflow menu --- */

.td-menu { position: relative; }
.td-menu-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 20;
  min-width: 184px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-white);
  box-shadow: var(--shadow-lg);
}
.td-menu-item {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-radius: var(--radius-md);
  background: none;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  text-align: left;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}
.td-menu-item:hover {
  background: var(--surface-wash);
  color: var(--text-primary);
}
.td-menu-item svg { flex-shrink: 0; color: var(--text-quaternary); }
.td-menu-item--danger:hover {
  background: var(--danger-wash);
  color: var(--danger);
}
.td-menu-item--danger:hover svg { color: var(--danger); }

.team-eyebrow {
  display: inline-block;
  margin-bottom: 10px;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--primary-text);
}

/* Matches .shell-greet's ladder one step down: the workspace greeting is the app's
   focal point and this should not compete with it from a sibling route. */
.team-title {
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  line-height: 1.1;
  font-weight: var(--weight-bold);
  letter-spacing: -0.015em;
  color: var(--text-primary);
  margin: 0;
}
.team-sub {
  margin: 9px 0 0;
  max-width: 62ch;
  font-size: var(--text-md);
  line-height: 1.6;
  color: var(--text-tertiary);
}
.team-pagehead--pitch .team-sub { font-size: var(--text-lg); }

.team-pitch-cta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--spacing-md);
  margin-top: var(--spacing-lg);
}
.team-pitch-cta .btn {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-xs);
}
.team-pitch-trust {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

.team-sectionhead {
  margin: var(--app-shell-inset) 0 var(--spacing-lg);
}
.team-sectionhead h2 {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.team-sectionsub {
  margin: 6px 0 0;
  font-size: var(--text-md);
  color: var(--text-tertiary);
}

/* --------------------------------------------------------------- pitch hero --- */

/* Copy left, sample dashboard right. The visual is the reason this reads as a
   product rather than a price list, so it gets equal billing rather than sitting
   under the fold. Collapses to one column below 1080px — the frame stops being
   legible before the text does.

   The pagehead's top inset lives on the hero, not the left column. Leaving it on
   .team-pagehead padded only the copy, so align-items:center was centering the
   mockup against (empty padding + copy) and the frame sat visibly high. Same
   two numbers as .team-pagehead; both columns share it. */
.team-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  align-items: center;
  gap: 48px;
  padding-top: calc(var(--app-shell-inset) + 34px);
}
.team-hero .team-pagehead {
  padding-top: 0;
  padding-bottom: 0;
}
.team-hero-visual { min-width: 0; }

/* 1360, not 1080. These queries measure the viewport, but the content sits in a panel
   that is the viewport minus the rail, the gutters and the container inset — roughly
   314px narrower. At a 1200px viewport the panel is 886px, which is where a two-column
   hero and a three-across grid both start to pinch. Sized from the panel the content
   actually gets, not the window it happens to be in. */
@media (max-width: 1360px) {
  .team-hero {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--spacing-lg);
  }
  .team-hero .team-pagehead { padding-bottom: var(--spacing-xs); }
}

/* ------------------------------------------------------- sample dashboard --- */

/* A drawn dashboard, not a screenshot — hence the window chrome and the "Sample
   data" chip, which are what stop it being mistaken for the real thing. Everything
   inside is aria-hidden and inert: no ids, no controls, nothing focusable. */
.team-frame {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-white);
  box-shadow: 0 12px 34px rgba(15, 23, 42, 0.07);
  overflow: hidden;
}
.team-frame--lg { max-width: 100%; }
.team-frame-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 14px;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border);
}
.team-frame-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--border-strong);
}
.team-frame-dot:nth-child(1) { background: var(--danger-border); }
.team-frame-dot:nth-child(2) { background: var(--warning-border); }
.team-frame-dot:nth-child(3) { background: var(--success-border); }
.team-frame-title {
  margin-left: 8px;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.team-sample-note {
  margin-left: auto;
  flex-shrink: 0;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: rgba(var(--primary-rgb), 0.12);
  color: var(--primary-dark);
  font-size: var(--text-3xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.team-frame-body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
  padding: var(--spacing-md);
  background: var(--surface-canvas);
}
.team-frame-body--lg {
  gap: var(--spacing-sm);
  padding: var(--spacing-md);
}

.team-mock-card {
  padding: var(--spacing-sm) 14px 14px;
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-md);
  background: var(--surface-white);
  min-width: 0;
}
.team-mock-card-title {
  margin-bottom: 10px;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.team-mock-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: var(--spacing-sm);
}

/* Pool bar */
.team-mock-pool {
  padding: 12px 14px;
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-md);
  background: var(--surface-white);
}
.team-mock-card .team-mock-pool {
  padding: 0;
  border: none;
  background: none;
}
.team-mock-pool-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--spacing-xs);
  margin-bottom: 7px;
}
.team-mock-pool-label {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}
.team-mock-pool-count {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.team-mock-track {
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--surface-wash);
  overflow: hidden;
}
.team-mock-fill {
  height: 100%;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--primary) 0%, var(--primary-light) 100%);
}

/* Tiles */
.team-mock-tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--spacing-xs);
}
.team-mock-tiles--4 { grid-template-columns: repeat(auto-fit, minmax(min(120px, 100%), 1fr)); }
.team-mock-tile {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 12px;
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-md);
  background: var(--surface-white);
  min-width: 0;
}
.team-mock-tile-label {
  font-size: var(--text-3xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.team-mock-tile-value {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: -0.02em;
  color: var(--text-primary);
}

/* Avatar chip, shared by leaders / feed / brands */
.team-mock-av {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--primary-subtle);
  color: var(--primary-dark);
  font-size: var(--text-3xs);
  font-weight: var(--weight-bold);
}

/* Leaderboard */
.team-mock-leaders {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin-top: 14px;
}
.team-mock-leader {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
}
.team-mock-leader-name {
  flex: 0 0 68px;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.team-mock-bar {
  flex: 1 1 auto;
  height: 6px;
  min-width: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-wash);
  overflow: hidden;
}
.team-mock-bar-fill {
  display: block;
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--primary);
}
.team-mock-leader-val {
  flex: 0 0 auto;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

/* Trend bars */
.team-mock-chart {
  display: flex;
  align-items: flex-end;
  gap: 5px;
  height: 104px;
}
.team-mock-chart-bar {
  flex: 1 1 0;
  min-width: 0;
  border-radius: 3px 3px 0 0;
  background: linear-gradient(180deg, var(--primary) 0%, var(--primary-light) 100%);
  opacity: 0.85;
}

/* Members mini-table */
.team-mock-table-wrap { overflow-x: auto; scrollbar-width: thin; }
.team-mock-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-xs);
  white-space: nowrap;
}
.team-mock-table th {
  padding: 0 10px 8px 0;
  text-align: left;
  font-size: var(--text-3xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  border-bottom: 1px solid var(--border-hairline);
}
.team-mock-table td {
  padding: 8px 10px 8px 0;
  border-bottom: 1px solid var(--border-hairline);
  color: var(--text-secondary);
}
.team-mock-table tr:last-child td { border-bottom: none; }
.team-mock-table th:last-child,
.team-mock-table td:last-child { padding-right: 0; }
.team-mock-num { text-align: right; }
.team-mock-chip {
  display: inline-flex;
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  background: var(--surface-wash);
  color: var(--text-tertiary);
  font-size: var(--text-3xs);
  font-weight: var(--weight-semibold);
}
.team-mock-chip--owner {
  background: rgba(var(--primary-rgb), 0.12);
  color: var(--primary-dark);
}
.team-mock-chip--admin {
  background: var(--success-subtle);
  color: var(--success-darker);
}

/* Activity feed */
.team-mock-feed,
.team-mock-brands {
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.team-mock-feed-row,
.team-mock-brand {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  min-width: 0;
}
.team-mock-feed-line,
.team-mock-brand-name {
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.team-mock-feed-line strong,
.team-mock-brand-name {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}
.team-mock-feed-meta,
.team-mock-brand-meta {
  margin-top: 2px;
  font-size: var(--text-3xs);
  color: var(--text-tertiary);
}

/* Rename-in-place on the team's own title. */
.td-hero-name-view {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
}
.td-hero-name-edit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-xs);
}
.td-hero-name-edit-actions {
  display: flex;
  gap: var(--spacing-xs);
}

.team-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-white);
  color: var(--text-tertiary);
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease, border-color 0.14s ease;
}
.team-icon-btn:hover {
  background: var(--surface-wash);
  color: var(--text-secondary);
  border-color: var(--border-strong);
}
.team-icon-btn--danger:hover {
  background: var(--danger-wash);
  color: var(--danger);
  border-color: var(--danger-border);
}
.team-icon-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.28);
}

.td-seat-warning {
  margin: var(--spacing-sm) 0 0;
  padding: 8px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--warning-border);
  background: var(--warning-subtle);
  color: var(--warning-text);
  font-size: var(--text-sm);
}
.td-seat-warning.is-critical {
  border-color: var(--danger-border);
  background: var(--danger-subtle);
  color: var(--danger-text);
}

.td-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;
}

/* ----------------------------------------------------------------- forms --- */

.team-label {
  display: block;
  margin-bottom: 6px;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}
.team-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border-input);
  border-radius: var(--radius-md);
  background: var(--surface-white);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  transition: border-color 0.14s ease, box-shadow 0.14s ease;
}
.team-input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.14);
}
.team-input--inline { max-width: 320px; }
.team-select { cursor: pointer; }

.team-form-msg {
  margin: var(--spacing-xs) 0 0;
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  min-height: 1.2em;
}
.team-form-msg--error { color: var(--danger-text); }

/* ------------------------------------------------------- create-team state --- */

.team-create-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--spacing-sm);
  max-width: 560px;
  padding: var(--spacing-lg);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-xl);
  background: var(--surface-white);
  box-shadow: var(--shadow-sm);
}
.team-create-form .team-label {
  flex: 1 0 100%;
  margin-bottom: 0;
}
.team-create-form .team-input { flex: 1 1 260px; }
.team-create-form .btn { flex: 0 0 auto; }
.team-create-form .team-form-msg { flex: 1 0 100%; }

.team-create-points {
  list-style: none;
  margin: var(--spacing-lg) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: var(--text-md);
  color: var(--text-secondary);
}
.team-create-points li {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
/* A tick rather than a bullet: each line is something the plan already includes. */
.team-create-points li::before {
  content: '✓';
  color: var(--success);
  font-weight: var(--weight-bold);
  flex-shrink: 0;
}
.team-create-points strong {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}

/* ----------------------------------------------------------- invite state --- */

/* The same card the create form is, because it is doing the same job at the same point
   in the route: one decision, in one white box, on the tinted panel. Only its contents
   differ — two buttons instead of a field, so no flex-wrap ladder is needed. */
.team-invite-card {
  max-width: 560px;
  padding: var(--spacing-lg);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-xl);
  background: var(--surface-white);
  box-shadow: var(--shadow-sm);
}
.team-invite-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-sm);
}
/* Accept is the answer this card is asking for; Decline is available, not offered. */
.team-invite-actions .btn { flex: 0 0 auto; }
.team-invite-card .team-form-msg { margin-top: var(--spacing-sm); }

/* ------------------------------------------------------------ pitch state --- */

/* Three across, explicitly — not auto-fit. There are exactly six of these and the
   count is not going to change, so letting the browser pack as many as fit produced
   a 4 + 2 row that reads as a layout accident rather than a grid. 3 + 2 rows is the
   shape the content actually has. It also stops the cards at ~278px, which was too
   narrow for three-line body copy: at a third of the measure they breathe.
   The step down is 3 -> 2 -> 1, so every breakpoint stays a full row. */
.team-benefits {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--spacing-md);
  /* Was --spacing-xs, which put 8px between the hero and this grid and made the two
     read as one crowded block. The hero is a section; it gets a section's clearance. */
  margin-top: var(--app-shell-inset);
}
/* Same 1360 reasoning as the hero above: below it, three across leaves each card
   under ~300px, which is the width that made these feel cramped in the first place.
   Two rows of three becomes three rows of two — still full rows, never a ragged one. */
@media (max-width: 1360px) {
  .team-benefits { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.team-benefit {
  padding: var(--spacing-lg);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-xl);
  background: var(--surface-white);
  box-shadow: var(--shadow-sm);
}
.team-benefit-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin-bottom: var(--spacing-sm);
  border-radius: var(--radius-md);
  background: var(--primary-subtle);
  color: var(--primary);
}
.team-benefit-icon svg { width: 19px; height: 19px; }
.team-benefit-title {
  margin: 0 0 6px;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.team-benefit-text {
  margin: 0;
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--text-tertiary);
}

/* Full width, two equal columns. Capped at 760px these stopped 400px short of the
   benefits grid and the sample frame above them, so the page's right edge went ragged
   for its whole bottom half — which is most of what read as "not well laid out". */
.team-plans {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--spacing-md);
}
@media (max-width: 720px) {
  .team-plans { grid-template-columns: minmax(0, 1fr); }
}
.team-plan {
  display: flex;
  flex-direction: column;
  padding: var(--spacing-lg);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-xl);
  background: var(--surface-white);
  box-shadow: var(--shadow-sm);
}
.team-plan--featured {
  border-color: rgba(var(--primary-rgb), 0.34);
  box-shadow: 0 6px 22px rgba(var(--primary-rgb), 0.08);
}
.team-plan-tag {
  align-self: flex-start;
  margin-bottom: var(--spacing-sm);
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--primary-dark);
  background: rgba(var(--primary-rgb), 0.12);
}
.team-plan-tag--muted {
  color: var(--text-tertiary);
  background: var(--surface-wash);
}
.team-plan-name {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.team-plan-price {
  margin: 2px 0 var(--spacing-md);
  font-size: 2rem;
  font-weight: var(--weight-extrabold);
  letter-spacing: -0.02em;
  color: var(--text-primary);
}
.team-plan-price span {
  margin-left: 4px;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--text-tertiary);
}
.team-plan-list {
  list-style: none;
  margin: 0 0 var(--spacing-lg);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: var(--text-base);
  color: var(--text-secondary);
}
.team-plan-list li {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.team-plan-list li::before {
  content: '✓';
  color: var(--success);
  font-weight: var(--weight-bold);
  flex-shrink: 0;
}
.team-plan-cta { margin-top: auto; }

/* The rows run the full measure so the right edge agrees with everything above; the
   answer text inside is capped, because a 1160px line of prose is unreadable however
   tidy the box around it looks. */
.team-faq {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
}
.team-faq-item > p { max-width: 92ch; }
.team-faq-item {
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-lg);
  background: var(--surface-white);
  overflow: hidden;
}
.team-faq-item > summary {
  padding: 14px var(--spacing-md);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  cursor: pointer;
  list-style: none;
}
.team-faq-item > summary::-webkit-details-marker { display: none; }
.team-faq-item > summary::after {
  content: '+';
  float: right;
  color: var(--text-tertiary);
  font-weight: var(--weight-normal);
}
.team-faq-item[open] > summary::after { content: '−'; }
.team-faq-item > p {
  margin: 0;
  padding: 0 var(--spacing-md) var(--spacing-md);
  font-size: var(--text-base);
  line-height: 1.65;
  color: var(--text-secondary);
}

/* ------------------------------------------------------------------ tabs --- */

.team-tabs {
  display: flex;
  align-items: flex-end;
  gap: var(--spacing-lg);
  margin-bottom: var(--spacing-lg);
  /* Full-bleed rule under the row rather than the inline-flex width .underline-tabs
     uses on the workspace: there the tabs sit in a header beside other controls, here
     they span the panel and the line reads as the top edge of the content below. */
  width: 100%;
}
.team-tabs .td-tab.hidden { display: none; }

/* Active state, drawn in CSS rather than by the shared component.
   .underline-tabs paints its active tab with a separate .underline-tabs__indicator
   element that JS measures and slides — and this row has never contained one, so the
   only thing marking the current tab was a colour step from #475569 to #0f172a. That
   is too quiet to find at a glance, which is exactly how it read.
   A static border needs no measurement: it is right on the first paint, and it cannot
   be left stranded at width 0 the way a JS-positioned indicator can when the row is
   measured while its panel is still display:none. The trade is the sliding animation
   the workspace tabs have; at rest the two rows look the same.
   Overrides `border: none` and the colour from .underline-tabs .tab-btn — equal
   specificity, and this stylesheet is linked after components.css. */
.team-tabs .td-tab {
  border-bottom: 2px solid transparent;
  /* Pulls the border down over the row's 1px rule instead of stacking on top of it. */
  margin-bottom: -1px;
  transition: color 0.16s ease, border-color 0.16s ease;
}
.team-tabs .td-tab.is-active {
  border-bottom-color: var(--primary);
  color: var(--text-primary);
}
.team-tabs .td-tab:hover:not(.is-active) {
  border-bottom-color: var(--border-strong);
}

/* ----------------------------------------------------------------- cards --- */

/* One gap owned by the panel instead of a bottom margin on every card. Cards that are
   hidden contribute nothing to a flex gap, so a role that hides two of three blocks no
   longer leaves their margins behind as dead space. */
.td-tabpanel {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

.td-card {
  padding: var(--spacing-lg);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-xl);
  background: var(--surface-white);
  box-shadow: var(--shadow-sm);
}

/* Pool and activity, side by side. The pool is the wider of the two because its
   leaderboard rows need the room; the feed is a list of short lines. */
.td-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
  gap: var(--spacing-md);
  align-items: start;
}
/* One visible child spans the row rather than sitting in a half-width column with a
   hole beside it — which is what a member (no pool card) would otherwise see. */
.td-columns > .td-card:only-child,
.td-columns > .hidden + .td-card,
.td-columns > .td-card:has(+ .hidden) { grid-column: 1 / -1; }

@media (max-width: 1040px) {
  .td-columns { grid-template-columns: minmax(0, 1fr); }
}

.td-card-title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.td-card > .td-muted {
  margin: 4px 0 var(--spacing-md);
}
.td-muted {
  color: var(--text-tertiary);
  font-size: var(--text-base);
}

.td-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-md);
  margin-bottom: var(--spacing-md);
  flex-wrap: wrap;
}
.td-card-title-group {
  display: flex;
  align-items: center;
  gap: 6px;
}
.td-head-pill {
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background: var(--surface-wash);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--text-tertiary);
}

/* Info tooltip on the analytics header. */
.td-info-wrap { position: relative; display: inline-flex; }
.td-info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: none;
  color: var(--text-quaternary);
  cursor: help;
}
.td-info-tooltip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 260px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  background: var(--text-primary);
  color: var(--surface-white);
  font-size: var(--text-xs);
  line-height: 1.45;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.14s ease;
  z-index: 5;
  pointer-events: none;
}
.td-info-wrap:hover .td-info-tooltip,
.td-info-btn:focus-visible + .td-info-tooltip {
  opacity: 1;
  visibility: visible;
}

/* ------------------------------------------------------------ stat tiles --- */

/* The band sits directly on the panel, so the tiles are the cards - they carry the
   white, the hairline and the shadow that the wrapper used to. */
.td-statband { min-width: 0; }
.td-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr));
  gap: var(--spacing-md);
}
.td-stat-card {
  padding: var(--spacing-md) var(--spacing-lg);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-xl);
  background: var(--surface-white);
  box-shadow: var(--shadow-sm);
  min-width: 0;
}
.td-stat-label {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.td-stat-value {
  margin-top: 6px;
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  letter-spacing: -0.02em;
  color: var(--text-primary);
  line-height: 1.15;
}
/* Says what the number counts. The old layout put "Last 30 days" in a pill on the
   wrapper's header, which claimed the window applied to all four tiles - it doesn't. */
.td-stat-foot {
  margin-top: 4px;
  font-size: var(--text-xs);
  color: var(--text-quaternary);
}

/* ------------------------------------------------------------ export pool --- */

/* The "Top exporters this month" list that team-usage.js renders had NO stylesheet of
   its own on either surface that used it: the <h3> fell back to the browser default
   (18.7px/700 — louder than the card title above it), the avatar was a bare letter on
   its own full-width line, and the bar track and fill were both 0px tall, so the bars
   were simply invisible. This section is that missing stylesheet. */
/* No margin of its own: .team-usage-block already puts 20px between the bar and this,
   and adding 16 on top left the rule sitting 36px below the bar but 16px above its own
   label - closer to the thing it introduces than the thing it separates from. */
.team-usage-leaders {
  padding-top: var(--spacing-lg);
  border-top: 1px solid var(--border-hairline);
}
.team-usage-leaders-title {
  margin: 0 0 var(--spacing-sm);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.team-usage-leaders-list {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
}
.team-usage-leaders-empty {
  margin: 0;
  font-size: var(--text-base);
  color: var(--text-tertiary);
}
.team-usage-leader-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  min-width: 0;
}
.team-usage-leader-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--primary-subtle);
  color: var(--primary-dark);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
}
.team-usage-leader-body {
  flex: 1 1 auto;
  min-width: 0;
}
.team-usage-leader-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--spacing-xs);
  margin-bottom: 5px;
}
.team-usage-leader-name {
  font-size: var(--text-base);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.team-usage-leader-count {
  flex-shrink: 0;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.team-usage-leader-track {
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-wash);
  overflow: hidden;
}
.team-usage-leader-fill {
  height: 100%;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--primary) 0%, var(--primary-light) 100%);
}

/* ---------------------------------------------------- first-member prompt --- */

.td-first-member-prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--spacing-xl) var(--spacing-lg);
  border: 1.5px dashed rgba(var(--primary-rgb), 0.3);
  border-radius: var(--radius-xl);
  background: var(--surface-white);
}
.td-first-member-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  margin-bottom: var(--spacing-sm);
  border-radius: 50%;
  background: var(--primary-subtle);
  color: var(--primary);
}
.td-first-member-title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  color: var(--text-primary);
}
.td-first-member-text {
  margin: 4px 0 var(--spacing-md);
  font-size: var(--text-base);
  color: var(--text-tertiary);
}

/* ---------------------------------------------------------- empty states --- */

.td-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--spacing-lg) var(--spacing-md);
}
.td-empty-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--spacing-sm);
  border-radius: 50%;
  background: var(--surface-canvas);
  color: var(--text-quaternary);
}
.td-empty-title {
  margin: 0;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}
.td-empty-text {
  margin: 4px 0 0;
  max-width: 34ch;
  font-size: var(--text-base);
  line-height: 1.55;
  color: var(--text-tertiary);
}

/* -------------------------------------------------------------- activity --- */

.td-activity-list {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
}
/* Six rows, then a toggle. Fixed at author time rather than measured, so the card
   does not resize as rows arrive. */
.td-activity-list--collapsed > .td-activity-row:nth-child(n + 7) { display: none; }
.td-activity-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}
.td-activity-avatar,
.td-brand-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--primary-subtle);
  color: var(--primary-dark);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
}
.td-activity-body { min-width: 0; }
.td-activity-line {
  font-size: var(--text-base);
  color: var(--text-secondary);
}
.td-activity-line strong { color: var(--text-primary); font-weight: var(--weight-semibold); }
.td-activity-meta {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}
.td-activity-toggle {
  margin-top: var(--spacing-sm);
  padding: 0;
  border: none;
  background: none;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--primary-text);
  cursor: pointer;
}
.td-activity-toggle:hover { text-decoration: underline; }

/* ---------------------------------------------------------------- tables --- */

/* The members table is the one block here that can genuinely exceed the panel, so it
   scrolls inside its own box rather than pushing the panel sideways. */
.td-table-wrap {
  overflow-x: auto;
  scrollbar-width: thin;
}
.td-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-base);
}
.td-table th {
  padding: 0 var(--spacing-sm) 10px;
  text-align: left;
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.td-table td {
  padding: 12px var(--spacing-sm);
  border-bottom: 1px solid var(--border-hairline);
  color: var(--text-secondary);
  vertical-align: middle;
}
.td-table tr:last-child td { border-bottom: none; }
.td-table td strong { color: var(--text-primary); font-weight: var(--weight-semibold); }
.td-table th:first-child,
.td-table td:first-child { padding-left: 0; }
.td-table th:last-child,
.td-table td:last-child { padding-right: 0; }
.td-num { text-align: right; }
.td-activity-when { white-space: nowrap; }

.td-actions-cell {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
}
.td-inline-select {
  width: auto;
  min-width: 104px;
  padding: 5px 8px;
  font-size: var(--text-sm);
}
.td-btn-compact {
  padding: 5px 10px;
  font-size: var(--text-sm);
  white-space: nowrap;
}

.td-role-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
}
.td-role-owner {
  color: var(--primary-dark);
  background: rgba(var(--primary-rgb), 0.12);
}
/* Green, as the retired stylesheet had it — but via the real tokens. That file wrote
   the admin tint as a literal rgba(16, 185, 129, 0.10), which is the exact drift
   DESIGN_TOKENS.md exists to prevent. (--info-* is documented there but is not
   actually defined in style.css, so it is not an option.) */
.td-role-admin {
  color: var(--success-darker);
  background: var(--success-subtle);
}
.td-role-member {
  color: var(--text-tertiary);
  background: var(--surface-wash);
}

/* ---------------------------------------------------------------- invites --- */

/* The invite form used to be its own white card above the roster. It is a control for
   the table underneath it, so it is now a tinted strip at the top of that same card. */
.td-inviterow {
  margin-bottom: var(--spacing-lg);
  padding: var(--spacing-md);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-lg);
  background: var(--surface-canvas);
}
.td-inviterow .team-form-msg:empty { display: none; }

.td-invite-fields {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--spacing-sm);
}
.td-invite-field { flex: 1 1 220px; min-width: 0; }
.td-invite-field--role { flex: 0 1 150px; }
.td-invite-fields .btn { flex: 0 0 auto; }

/* Pending invites: a second section of the members card, not a second card. */
.td-subsection {
  margin-top: var(--spacing-lg);
  padding-top: var(--spacing-lg);
  border-top: 1px solid var(--border-hairline);
}
.td-subsection-title {
  margin-bottom: var(--spacing-sm);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* Demoted from a card of its own to a quiet footnote on the members card - the same
   content is also one hover away from the "?" beside the card title. */
.td-roles-card {
  margin-top: var(--spacing-lg);
  padding-top: var(--spacing-md);
  border-top: 1px solid var(--border-hairline);
}
.td-roles-card > summary {
  cursor: pointer;
  list-style: none;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-tertiary);
}
.td-roles-card > summary:hover { color: var(--text-secondary); }
.td-roles-card > summary::-webkit-details-marker { display: none; }
.td-roles-card > summary::after {
  content: '+';
  float: right;
  color: var(--text-tertiary);
  font-weight: var(--weight-normal);
}
.td-roles-card[open] > summary::after { content: '−'; }
.td-role-tips {
  margin: var(--spacing-sm) 0 0;
  padding-left: var(--spacing-md);
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: var(--text-base);
  line-height: 1.55;
  color: var(--text-secondary);
}
.td-role-tips strong { color: var(--text-primary); font-weight: var(--weight-semibold); }

/* -------------------------------------------------------------- analytics --- */

/* A sentence, not a callout. As a grey rounded box it read like a warning banner and
   was the loudest thing on a tab whose job is the charts underneath it. */
.td-efficiency {
  margin: 0 0 var(--spacing-lg);
  max-width: 68ch;
  font-size: var(--text-md);
  line-height: 1.6;
  color: var(--text-tertiary);
}
.td-efficiency strong { color: var(--text-primary); font-weight: var(--weight-semibold); }

.td-charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 0;
}
/* The trend line reads as the header chart, so it takes the full row when there is
   more than one column to take. */
.td-chart-card:first-child { grid-column: 1 / -1; }
/* Regions of the analytics card, divided by hairlines - not three bordered boxes
   floating inside a fourth. The vertical rule only exists while they sit side by side. */
.td-chart-card {
  padding: var(--spacing-lg) 0 0;
  margin-top: var(--spacing-lg);
  border-top: 1px solid var(--border-hairline);
  min-width: 0;
}
.td-chart-card:first-child {
  padding-top: 0;
  margin-top: 0;
  border-top: none;
}
.td-chart-card + .td-chart-card + .td-chart-card {
  padding-left: var(--spacing-lg);
  border-left: 1px solid var(--border-hairline);
}
/* The middle chart is the one to the left of that rule; without this its canvas runs
   flush into the divider while the right-hand one sits 24px clear of it. */
.td-chart-card + .td-chart-card:has(+ .td-chart-card) {
  padding-right: var(--spacing-lg);
}
@media (max-width: 700px) {
  .td-chart-card + .td-chart-card + .td-chart-card {
    padding-left: 0;
    border-left: none;
  }
  .td-chart-card + .td-chart-card:has(+ .td-chart-card) { padding-right: 0; }
}
/* Chart.js sizes a maintainAspectRatio:false canvas to its parent's content box, so the
   height has to live on a wrapper - a canvas cannot size itself. Fixed rather than
   aspect-derived: a sparse month and a busy one should occupy the same space. */
.td-chart-canvas {
  position: relative;
  height: 200px;
}
.td-chart-canvas--trend { height: 240px; }
.td-chart-canvas canvas { display: block; }

.td-chart-title {
  margin-bottom: var(--spacing-sm);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.td-range {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: var(--radius-pill);
  background: var(--surface-wash);
}
.td-range-btn {
  padding: 4px 12px;
  border: none;
  border-radius: var(--radius-pill);
  background: none;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-tertiary);
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}
.td-range-btn:hover { color: var(--text-secondary); }
.td-range-btn.is-active {
  background: var(--surface-white);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}

/* ----------------------------------------------------------------- brands --- */

.td-brands-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap: var(--spacing-sm);
}
/* Spans the grid so each owner's brands sit under their own name. */
.td-brand-group-label {
  grid-column: 1 / -1;
  margin-top: var(--spacing-sm);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.td-brand-group-label:first-child { margin-top: 0; }
/* Hairline only, no fill: a tinted tile inside a white card is the third surface in
   two levels, and with a dozen brands the grid turned into a wall of grey blocks. */
.td-brand-card {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-sm) var(--spacing-md);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-lg);
  background: var(--surface-white);
  min-width: 0;
  transition: border-color 0.14s ease, background 0.14s ease;
}
.td-brand-card:hover {
  border-color: var(--border-strong);
  background: var(--surface-canvas);
}
.td-brand-body { min-width: 0; }
.td-brand-name {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.td-brand-mine {
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  background: rgba(var(--primary-rgb), 0.12);
  color: var(--primary-dark);
  font-size: var(--text-3xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.td-brand-meta {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ------------------------------------------------------------ boot skeleton --- */

/* Must match .team-pagehead exactly, or the whole surface jumps upward the moment the
   session resolves and the skeleton hands over to a real state. */
.team-boot { padding-top: calc(var(--app-shell-inset) + 34px); }

/* Below 980px the rail becomes a drawer and a floating nav toggle sits where the logo
   was. app-shell.css raises the workspace spacer from --app-shell-inset to 60px there
   so the page header clears that button; this surface has the same button over it and
   needs the same clearance. Breakpoint copied from app-shell.css deliberately — if it
   moves there, it has to move here. */
@media (max-width: 980px) {
  .team-pagehead,
  .team-boot { padding-top: calc(60px + 34px); }
}
.team-skel-title { width: min(340px, 60%); height: 32px; }
.team-skel-sub { width: min(460px, 78%); height: 16px; margin-top: 14px; }
.team-skel-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: var(--spacing-md);
  margin-top: var(--app-shell-inset);
}
.team-skel-card { height: 148px; border-radius: var(--radius-xl); }

/* ------------------------------------------------------------------ narrow --- */

@media (max-width: 720px) {
  /* The identity block keeps its row (mark beside name); it is the actions that drop
     under it, full width, rather than squeezing a button and a menu beside the title. */
  .team-pagehead--row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--spacing-md);
  }
  .td-monogram { width: 40px; height: 40px; }
  /* Left-packed under the name rather than pushed to the far edge of the panel. The
     menu keeps its right-edge anchor, which at this width puts it comfortably inside
     the content column - anchoring it left instead ran it past the panel's edge. */
  .team-pagehead-actions { justify-content: flex-start; }
  .td-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--spacing-sm); }
  /* Scrolls rather than wraps: a wrapped tab row changes the height of the block above
     the content every time the active tab moves. */
  .team-tabs {
    gap: var(--spacing-md);
    overflow-x: auto;
    scrollbar-width: none;
  }
  .team-tabs::-webkit-scrollbar { display: none; }
  .td-card { padding: var(--spacing-md); }
  .team-create-form { padding: var(--spacing-md); }
  .td-chart-card:first-child { grid-column: auto; }

  /* The sample frame stays, but it stops pretending to be a desktop app: the window
     chrome shrinks and the tiles go two-up rather than squeezing four across 300px. */
  .team-frame-body,
  .team-frame-body--lg { padding: var(--spacing-xs); }
  .team-mock-tiles,
  .team-mock-tiles--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .team-mock-chart { height: 78px; }
  .team-mock-leader-name { flex-basis: 56px; }

  .team-benefits { grid-template-columns: minmax(0, 1fr); }
}
