/* =====================================================================
   GoDartsPro — Team area, 2026
   /wp-content/themes/dart/assets/css/team-2026.css

   The team area and the Performance Center are one product to a coach:
   they move between them constantly, and a coach who clicks through to a
   player's stats should not feel the seam. So this sheet does not invent
   a palette. It uses the Performance Center's own tokens, copied from
   engine/engine.css, with the same names.

   WHY COPIED RATHER THAN IMPORTED. The PC's tokens are declared on
   .stats-dashboard, so they resolve to nothing out here. Referencing
   var(--sd-green) outside that scope yields the guaranteed-invalid value
   and the property silently drops: text goes transparent, borders
   vanish, and nothing errors. Redeclaring them on .gdp-team is the only
   way a value like `var(--sd-line)` means anything in the team area.

   KEEP THE TWO BLOCKS IN STEP. If engine.css changes a token, change it
   here too. There is no build step that will notice.

   Everything is scoped under .gdp-team so the rest of the theme is
   untouched, and so this can be reverted by removing one class from the
   template.
   ===================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@300;400;500;600;700&family=Hanken+Grotesk:wght@400;500;600;700&display=swap');

.gdp-team{
  /* --- palette: Night Oche, identical to engine.css --- */
  --sd-bg:         #0e131a;
  --sd-surface:    #181f29;
  --sd-surface-2:  #212a36;
  --sd-line:       rgba(173, 194, 224, 0.10);
  --sd-line-2:     rgba(173, 194, 224, 0.18);
  --sd-text:       #e9eef5;
  --sd-muted:      #93a1b5;
  --sd-faint:      #93a1b5;
  --sd-green:      #27d2a3;
  --sd-blue:       #4cb3d4;
  /* The site's brand orange. This was #f4b740, a softer amber that did not
     match the orange used everywhere else on GoDartsPro. */
  --sd-gold:       #ffa200;
  /* Its lighter partner for hover. Was repeated as #ffd27a in four places,
     which is how a palette drifts. */
  --sd-gold-hi:    #ffc04d;
  --sd-red:        #ef4d63;
  --sd-purple:     #c07ae8;

  --sd-good-bg:     rgba(39, 210, 163, 0.12);
  --sd-good-border: rgba(39, 210, 163, 0.30);
  --sd-good-text:   #8fe9cf;
  --sd-bad-bg:      rgba(239, 77, 99, 0.12);
  --sd-bad-border:  rgba(239, 77, 99, 0.30);
  --sd-bad-text:    #f4b3bd;

  background: var(--sd-bg);
  color: var(--sd-text);
  font-family: "Hanken Grotesk", system-ui, sans-serif;
  font-feature-settings: "tnum" 1;
  -webkit-font-smoothing: antialiased;
  line-height: 1.45;
}

.gdp-team *,
.gdp-team *::before,
.gdp-team *::after{ box-sizing: border-box; }

/* ---------------------------------------------------------------------
   Type

   Oswald carries numbers and labels, Hanken Grotesk carries running
   text. Same division as the Performance Center: a condensed display
   face is excellent for a score and hard work for a sentence.
   ------------------------------------------------------------------ */

.gdp-team .app-header-l,
.gdp-team .app-header-m,
.gdp-team .app-header-s,
.gdp-team .app-header-xs,
.gdp-team .site-header-xs{
  font-family: "Oswald", sans-serif;
  color: var(--sd-text);
}
.gdp-team .app-header-l { font-size: 22px; font-weight: 500; letter-spacing: .01em; }
.gdp-team .app-header-m { font-size: 15px; font-weight: 500; }
.gdp-team .app-header-s { font-size: 12px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--sd-muted); }
.gdp-team .app-header-xs,
.gdp-team .site-header-xs{ font-size: 11px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--sd-muted); }

/* The theme's "orange-text" is the accent hook used all over the team
   markup. Repointed rather than renamed, so every existing call site
   picks up the new accent without being edited. */
.gdp-team .orange-text,
.gdp-team a.orange-text{ color: var(--sd-gold); }
.gdp-team .orange-text:hover{ color: var(--sd-gold-hi); }

.gdp-team .clickable{ cursor: pointer; }
.gdp-team .notranslate{ font-family: inherit; }

/* ---------------------------------------------------------------------
   Header and menu
   ------------------------------------------------------------------ */

/* ONE HEADER FOR EVERY TEAM.

   This used to carry the team's own image as a background photo, so a
   team with one and a team without one were visibly different pages, and
   a light badge needed a heavy scrim over it just to keep the text
   readable. The photo is gone and every team header is now identical.

   background-size and background-position went with it: they only ever
   described how to fit a photo that is no longer there. */
.gdp-team .teamHeader{
  height: auto;
  min-height: 84px;
  background-color: var(--sd-bg);
  border-bottom: 1px solid var(--sd-line);
  position: relative;
}
/* The gradient stays. It was added as a scrim for the photo, but it is
   also what lifts the header away from the page behind it, and removing
   it would flatten the top of every team page. Over a flat colour it
   simply reads as a subtle depth. */
.gdp-team .teamHeader::after{
  content:""; position:absolute; inset:0;
  background: linear-gradient(180deg, rgba(14,19,26,.55) 0%, rgba(14,19,26,.86) 100%);
  pointer-events:none;
}
.gdp-team .teamHeader > *{ position: relative; z-index: 1; }
.gdp-team .teamHeader .app-header-l{ font-size: 26px; font-weight: 600; }
.gdp-team .teamHeader .app-header-m{ color: var(--sd-muted); letter-spacing: .16em; text-transform: uppercase; font-size: 12px; }

.gdp-team .team-submenu-wrapper{ background: var(--sd-bg); }
.gdp-team .team-submenu{ padding: 0; }
.gdp-team .team-submenu a{
  display: block;
  font-family: "Oswald", sans-serif;
  font-size: 14px; font-weight: 500;
  letter-spacing: .06em;
  color: var(--sd-muted);
  padding: 12px 14px;
  border-bottom: 2px solid transparent;
  transition: color .15s, border-color .15s;
}
.gdp-team .team-submenu a:hover{ color: var(--sd-text); text-decoration: none; }
/* The current tab. The underline was green, which in this palette means
   support and completion, not "you are here" — the brand guide gives that
   job to orange. Now both the label and the rule are orange, so the tab
   states one thing in one colour.

   The label colour is stated rather than inherited: something in the
   theme's own stylesheet is colouring .orange-text and this makes the
   intent explicit either way. */
.gdp-team .team-submenu a.orange-text{
  color: var(--sd-gold);
  border-bottom-color: var(--sd-gold);
}
.gdp-team .team-submenu:hover{ background: transparent; }

/* ---------------------------------------------------------------------
   Surfaces
   ------------------------------------------------------------------ */

.gdp-team .teambox{
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: 14px;
  padding: 18px;
  color: var(--sd-text);
}
.gdp-team .teambox:hover{ background: var(--sd-surface); }

.gdp-team .teambox-heading{
  background: transparent;
  color: var(--sd-muted);
  /* line-height was 1. On the one heading that did wrap, the two lines sat
     directly on top of each other. 1.3 so a wrap is at least readable. */
  font: 600 12px/1.3 "Oswald", sans-serif;
  letter-spacing: .16em;
  text-transform: uppercase;
  padding: 0 0 12px 0;
  margin: 0 0 14px 0;
  border-bottom: 1px solid var(--sd-line);
}

/* THE HEADINGS FIT ON ONE LINE.
   "LATEST TEAM MESSAGE FROM COACH" is 30 characters, which at 12px with
   .16em tracking is about 274px — against roughly 276px of inner width on
   a 320px phone. It fitted or wrapped depending on the device, which is
   the worst of both.

   11px and .11em brings the longest heading to 234px, so every one of
   them clears a 320px screen with room to spare rather than by luck. */
@media (max-width: 767px){
  .gdp-team .teambox-heading{ font-size: 11px; letter-spacing: .11em; }
}

.gdp-team .tablelist tr{ background: transparent; color: var(--sd-muted); }
.gdp-team .tablerow:nth-child(even){ background: rgba(173,194,224,.03); color: var(--sd-text); }
.gdp-team .tablerow:hover{ background: rgba(173,194,224,.06); }

/* ---------------------------------------------------------------------
   Period cards, the spine of the coaching page
   ------------------------------------------------------------------ */

.gdp-team .period-card{
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: 14px;
  margin-bottom: 18px;
  overflow: hidden;
}
.gdp-team .period-head{
  background: rgba(173,194,224,.04);
  border-bottom: 1px solid var(--sd-line);
  padding: 14px 18px;
}
.gdp-team .period-dates{
  font-family: "Oswald", sans-serif;
  font-size: 20px; font-weight: 500;
  color: var(--sd-text);
  letter-spacing: .01em;
}
.gdp-team .period-meta{
  font-size: 12px;
  color: var(--sd-muted);
  margin-top: 3px;
}

.gdp-team .player-row{
  padding: 12px 18px;
  border-bottom: 1px solid var(--sd-line);
}
.gdp-team .player-row:last-child{ border-bottom: 0; }
.gdp-team .player-row:hover{ background: rgba(173,194,224,.04); }
.gdp-team .player-name{ font-size: 14px; font-weight: 500; }
.gdp-team .player-name a{ color: var(--sd-text); }
.gdp-team .player-name a:hover{ color: var(--sd-green); text-decoration: none; }
.gdp-team .player-routines{ color: var(--sd-muted); font-size: 12px; }

.gdp-team .routine-chip{
  border: 1px solid var(--sd-line-2);
  border-radius: 6px;
  padding: 2px 7px;
  font-size: 11px;
  color: var(--sd-muted);
  background: transparent;
}
.gdp-team .routine-chip.done{
  background: var(--sd-good-bg);
  border-color: var(--sd-good-border);
  color: var(--sd-good-text);
}

.gdp-team .pace-bar{
  height: 6px;
  border-radius: 3px;
  background: rgba(173,194,224,.12);
}
.gdp-team .pace-marker{ background: var(--sd-text); opacity: .55; }
.gdp-team .pace-text{ color: var(--sd-muted); font-size: 11px; }
.gdp-team .pace-ahead{ color: var(--sd-green); }
.gdp-team .pace-behind{ color: var(--sd-red); }

/* ---------------------------------------------------------------------
   Presets
   ------------------------------------------------------------------ */

.gdp-team .preset-card{
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: 14px;
  margin-bottom: 14px;
  overflow: hidden;
}
.gdp-team .preset-card-head{
  padding: 14px 18px;
  background: rgba(173,194,224,.04);
  border-bottom: 1px solid var(--sd-line);
}
.gdp-team .preset-card-body{ padding: 12px 18px 16px; }

/* ---- collapse -------------------------------------------------------
   The whole header is the control, so it says so on hover and takes a
   focus ring. Rename and Delete sit inside it and stop the click before
   it reaches the toggle. */
.gdp-team .preset-card-head{ cursor: pointer; user-select: none; }
.gdp-team .preset-card-head:hover{ background: rgba(173,194,224,.06); }
.gdp-team .preset-card-head:focus-visible{ outline: 2px solid var(--sd-gold); outline-offset: -2px; }

.gdp-team .preset-chev{
  display: inline-block; width: 12px; margin-right: 8px;
  font-size: 11px; color: var(--sd-muted);
  transform: rotate(90deg); transition: transform .16s;
}
.gdp-team .preset-card.is-shut .preset-chev{ transform: rotate(0deg); }

/* display:none rather than a height animation. A card can hold forty
   games; animating that height is a lot of layout work for a flourish
   nobody asked for, and it also keeps the hidden rows out of the
   accessibility tree and out of tab order. */
.gdp-team .preset-card.is-shut .preset-card-body{ display: none; }

.gdp-team .js-preset-allshut:hover{ color: var(--sd-text); }
.gdp-team .preset-game-row{
  padding: 8px 0;
  border-bottom: 1px solid var(--sd-line);
}
.gdp-team .preset-game-row:last-child{ border-bottom: 0; }
.gdp-team .preset-game-name{ color: var(--sd-text); font-size: 14px; }
.gdp-team .preset-game-meta{ color: var(--sd-muted); font-size: 12px; }
.gdp-team .preset-empty{ color: var(--sd-muted); }
.gdp-team .preset-blocked{ color: var(--sd-gold); }

/* ---------------------------------------------------------------------
   Controls
   ------------------------------------------------------------------ */

.gdp-team .form-control,
.gdp-team input[type="text"],
.gdp-team input[type="date"],
.gdp-team select,
.gdp-team textarea{
  background: var(--sd-surface-2);
  border: 1px solid var(--sd-line-2);
  border-radius: 8px;
  color: var(--sd-text);
  font-family: "Hanken Grotesk", sans-serif;
  font-size: 14px;
  box-shadow: none;
}
.gdp-team .form-control:focus,
.gdp-team select:focus,
.gdp-team textarea:focus{
  border-color: var(--sd-green);
  box-shadow: none;
  outline: none;
}
.gdp-team ::placeholder{ color: var(--sd-muted); opacity: 1; }

/* Date inputs render a near-black native picker glyph on a dark field,
   which is invisible. Inverting it is the only reliable fix in Chrome. */
.gdp-team input[type="date"]::-webkit-calendar-picker-indicator{
  filter: invert(0.8);
  cursor: pointer;
}

.gdp-team .ghost-button,
.gdp-team .btn-clean,
.gdp-team button{
  font-family: "Oswald", sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  background: transparent;
  border: 1px solid var(--sd-line-2);
  border-radius: 8px;
  color: var(--sd-text);
  padding: 9px 16px;
  transition: border-color .15s, color .15s, background .15s;
}
.gdp-team .ghost-button:hover,
.gdp-team .btn-clean:hover,
.gdp-team button:hover{
  border-color: var(--sd-green);
  color: var(--sd-green);
  background: transparent;
}
.gdp-team button[disabled],
.gdp-team .ghost-button[disabled]{
  opacity: .4;
  cursor: not-allowed;
  border-color: var(--sd-line);
  color: var(--sd-muted);
}
.gdp-team .btn-clean-danger{
  border-color: var(--sd-bad-border);
  color: var(--sd-bad-text);
}

.gdp-team .row-button{
  background: transparent;
  border: 1px solid var(--sd-line-2);
  border-radius: 6px;
  color: var(--sd-muted);
  font-size: 12px;
  padding: 4px 8px;
}
.gdp-team .row-button:hover{ color: var(--sd-text); border-color: var(--sd-line-2); }

/* ---------------------------------------------------------------------
   Modal
   ------------------------------------------------------------------ */

/* The close control. Sits above the scrolling wrapper, and clear of the
   scroll gutter: at the old right:20px it landed on top of the
   scrollbar. */
.gdp-team .gdp-modal-x{
  position: absolute; top: 14px; right: 16px; z-index: 100;
  width: 30px; height: 30px; border-radius: 99px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(9,10,12,.55); border: 1px solid var(--sd-line);
  transition: border-color .15s, background .15s;
}
.gdp-team .gdp-modal-x:hover{ border-color: var(--sd-line-2); background: rgba(9,10,12,.8); }
.gdp-team .gdp-modal-x img{ width: 16px !important; height: auto; opacity: .8; }
.gdp-team .gdp-modal-x:hover img{ opacity: 1; }

/* The panel's own heading, which the picker sits under. */
.gdp-team .js-modal-title{
  font-family: "Oswald", sans-serif; font-size: 19px; font-weight: 500;
  color: var(--sd-text); margin-bottom: 14px; padding-right: 34px;
}

/* A POPUP, NOT A TALL PAGE.

   Bootstrap 3 gives .modal `overflow-y:auto` and lets .modal-content grow
   as tall as its contents. With a grid of eighty games inside, the box
   grew past the screen and the browser scrolled the whole modal, so the
   page ended up with two scrollbars and the picker's own grid could not
   be reached without moving the outer one first.

   The dialog is centred and capped against the viewport instead, and the
   content column scrolls internally. */
/* The scroll container has to BE the viewport, or a max-height on the
   panel inside it has nothing sensible to measure against. The theme was
   giving this element a max-width and a 60px top margin, which is what
   defeated every earlier attempt at capping the panel. Stated here with
   !important so a stray rule elsewhere cannot quietly do it again. */
.gdp-modal.modal{
  padding: 0 !important;
  margin: 0 !important;
  max-width: none !important;
  width: auto !important;
}
.gdp-modal .modal-dialog{
  display: flex; align-items: center; justify-content: center;
  min-height: 100%; width: auto; max-width: 760px;
  margin: 0 auto; padding: 18px;
}
/* Bootstrap slides the dialog in from -25%. Harmless when the dialog is
   short; with a tall one it starts a quarter of a viewport above the top
   and the modal scrolls to accommodate it. */
.gdp-modal.fade .modal-dialog{ transform: none; }
.gdp-modal .modal-content,
.gdp-team .modal-content{
  width: 100%;
  /* A DIALOG, NOT A SHEET. Capped well below the viewport so it reads as
     something laid over the page rather than replacing it. On a tall
     monitor a full-height popup is just a second page. */
  max-height: min(660px, calc(100vh - 64px));
  display: flex; flex-direction: column;
  overflow: hidden;
  background: var(--sd-surface);
  border: 1px solid var(--sd-line-2);
  border-radius: 16px;
  padding: 22px;
  color: var(--sd-text);
  font-family: "Hanken Grotesk", system-ui, sans-serif;
  box-shadow: 0 24px 60px rgba(0,0,0,.55);
}
/* The wrapper is what scrolls, so the close button and anything pinned
   inside the picker stay where they are. */
/* flex:1 1 auto so it takes the height the capped panel gives it, and
   min-height:0 so it is allowed to be shorter than its contents. Without
   the second, a flex item refuses to shrink below its content and the
   panel grows past its own max-height again. */
.gdp-modal .js-coaching-wrapper{
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column;
  /* A gutter for the scrollbar, so it runs beside the content instead of
     over the last column of tiles. */
  padding-right: 10px; margin-right: -4px;
  scrollbar-width: thin;
  scrollbar-color: rgba(173,194,224,.28) transparent;
}
.gdp-modal .js-coaching-wrapper::-webkit-scrollbar{ width: 8px; }
.gdp-modal .js-coaching-wrapper::-webkit-scrollbar-track{ background: transparent; }
.gdp-modal .js-coaching-wrapper::-webkit-scrollbar-thumb{
  background: rgba(173,194,224,.22); border-radius: 99px;
  border: 2px solid transparent; background-clip: content-box;
}
.gdp-modal .js-coaching-wrapper::-webkit-scrollbar-thumb:hover{ background: rgba(173,194,224,.38); background-clip: content-box; }
.gdp-modal .modal-backdrop.in{ opacity: .72; }

@media (max-width: 560px){
  .gdp-modal .modal-dialog{ padding: 10px; }
  .gdp-modal .modal-content{ max-height: calc(100vh - 20px); padding: 16px 14px; }
}

/* The game shelf. The artwork is the content, so the frame stays quiet. */
.gdp-team .game-item,
.gdp-modal .game-item{
  cursor: pointer;
  border-radius: 8px;
  padding: 4px;
  transition: background .15s;
}
.gdp-team .game-item:hover,
.gdp-modal .game-item:hover{ background: rgba(173,194,224,.06); }
.gdp-team .game-title-small,
.gdp-modal .game-title-small{
  font-family: "Oswald", sans-serif;
  font-size: 11px;
  color: var(--sd-muted);
  letter-spacing: .02em;
}

/* jQuery UI accordion headers inside the shelf. The default theme paints
   them light grey, which is the one place the old look survives a
   restyle because the widget writes its own classes. */
.gdp-team .ui-accordion-header,
.gdp-modal .ui-accordion-header{
  background: rgba(173,194,224,.05) !important;
  border: 1px solid var(--sd-line) !important;
  border-radius: 8px !important;
  color: var(--sd-text) !important;
  font-family: "Oswald", sans-serif !important;
  font-size: 13px !important;
  letter-spacing: .06em;
  margin-bottom: 6px;
}
.gdp-team .ui-accordion-header.ui-state-active,
.gdp-modal .ui-accordion-header.ui-state-active{
  background: rgba(39,210,163,.10) !important;
  border-color: var(--sd-good-border) !important;
  color: var(--sd-green) !important;
}
.gdp-team .ui-accordion-content,
.gdp-modal .ui-accordion-content{
  background: transparent !important;
  border: 0 !important;
  color: var(--sd-text) !important;
}

/* ---------------------------------------------------------------------
   Messages
   ------------------------------------------------------------------ */

.gdp-team .mess-coach,
.gdp-team .mess-player{
  background: var(--sd-surface-2);
  border: 1px solid var(--sd-line);
  border-radius: 10px;
  padding: 9px 12px;
}
.gdp-team .mess-coach{ border-left: 2px solid var(--sd-green); }
.gdp-team .mess-player{ border-right: 2px solid var(--sd-blue); }
.gdp-team .mess-header{ color: var(--sd-muted); font-size: 11px; font-weight: 500; }
.gdp-team .mess-content{ color: var(--sd-text); font-size: 13px; }

.gdp-team .message-empty{ color: var(--sd-muted); opacity: .5; }
.gdp-team .message-full{ color: var(--sd-gold); opacity: 1; }

/* ---------------------------------------------------------------------
   Team select cards
   ------------------------------------------------------------------ */

.gdp-team .teamselect{
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: 14px;
  color: var(--sd-text);
  box-shadow: none;
}
.gdp-team .teamselect:hover{ border-color: var(--sd-green); background: var(--sd-surface-2); }
.gdp-team .teamselect.color_1{ border-color: var(--sd-good-border); }

.gdp-team .team-image{ border: 2px solid var(--sd-line-2); }

/* ---------------------------------------------------------------------
   Members list

   A dense table a coach scans down. Names and numbers first; the tools
   only once they are looked for.
   ------------------------------------------------------------------ */

.gdp-team .members-table{ width: 100%; }
.gdp-team .members-table td{ padding: 7px 8px; vertical-align: middle; }
.gdp-team .members-table > tbody > tr:first-child td{
  border-bottom: 1px solid var(--sd-line);
  padding-bottom: 10px;
}
.gdp-team .members-table .tablerow td{ border-bottom: 1px solid var(--sd-line); }
.gdp-team .members-table .tablerow:last-child td{ border-bottom: 0; }
/* THE USERNAME IS THE LINK. It is what a player publishes; the real name
   beside it is incidental to the profile and should not be the thing that
   navigates.

   Quieter than the name, and in brackets, so the row still reads
   "who is this" first and "where does this go" second. Underlined on
   hover only: forty underlined names is a wall of rules, and the colour
   change is enough once a pointer is on it. */
/* The real name links to the player's card. It carries the row's normal
   colour rather than looking like a link, because in a list of forty
   every name would be one and the page would read as a wall of links. The
   hover states are what distinguish the two destinations. */
.gdp-team .col-realname{ color: var(--sd-text); }
.gdp-team .col-realname:hover{ color: var(--sd-green); text-decoration: underline; }

/* ONE ROW PER MEMBER, HOWEVER LONG THE NAME.

   "Matthias Orn Fridriksson" plus a SEAT badge plus a username pushed
   the username onto a second line, so that row stood a head taller than
   every other and the eye caught on it while scanning a list of forty.

   TRUNCATED BY WIDTH, NOT BY A CHARACTER COUNT. A fixed limit has to be
   chosen for the narrowest case and then wastes room in every other, and
   it cuts the same name differently depending on how wide the window
   happens to be. Ellipsis lets the name use whatever space that column
   actually has and shortens only when it genuinely runs out.

   The whole name stays in the DOM, so browser search, copy and screen
   readers all still see it, and the title attribute below puts it in a
   tooltip. A PHP substr would have thrown the rest away.

   min-width:0 on the cell is what makes it work: a table cell will not
   shrink below its content's intrinsic width without it, so the name
   would push the row wider instead of ellipsing. */
.gdp-team .col-name{ min-width: 0; }
.gdp-team .col-realname{
  display: inline-block; vertical-align: bottom;
  max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The badge and the username must not be pushed onto a second line
   either: they are short, so the name is the only part that should give. */
.gdp-team .col-name{ white-space: nowrap; }

/* A NAME NEEDS MORE ROOM THAN A USERNAME. Without a cap the name would
   take the whole cell and the username would ellipse instead, which is
   the wrong way round: the username is how a coach recognises a player
   in game. 62% leaves the shorter half of the pair intact. */
@media (min-width: 768px){
  .gdp-team .col-realname{ max-width: 62%; }
}

.gdp-team .col-username{ margin-left: 8px; white-space: nowrap; }
.gdp-team .col-username::before{ content: "("; color: var(--sd-muted); }
.gdp-team .col-username::after { content: ")"; color: var(--sd-muted); }
.gdp-team .col-username a{ color: var(--sd-muted); }
.gdp-team .col-username a:hover{ color: var(--sd-green); text-decoration: underline; }

/* On a phone the name line is about 26 characters, so a long pairing has
   to give somewhere. The username is the part that wraps out of sight
   rather than the name, and the row remains tappable for the snapshot. */
@media (max-width: 767px){
  .gdp-team .col-username{ margin-left: 6px; font-size: 12px; }
}

/* Row actions. Fixed 30px squares rather than text-sized glyphs with a
   background, which is what made the old ones as tall as the row: a
   filled inline element paints its whole line box, not just the icon. */
.gdp-team .row-tools{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.gdp-team .row-btn{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  flex: 0 0 auto;
  border: 1px solid var(--sd-line);
  border-radius: 7px;
  background: transparent;
  color: var(--sd-muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  transition: color .15s, border-color .15s, background .15s;
}
.gdp-team .row-btn:hover,
.gdp-team .row-btn:focus{
  color: var(--sd-green);
  border-color: var(--sd-good-border);
  background: var(--sd-good-bg);
  text-decoration: none;
}
/* The two word buttons, -01 and LOG. Same height so the row of controls
   sits on one baseline, width free so neither label is clipped. */
.gdp-team .row-btn--text{
  width: auto;
  padding: 0 9px;
  font-family: "Oswald", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .08em;
}

/* The MICO figure opens a popup, so it reads as a control rather than as
   a number that happens to be underlined. */
.gdp-team .btn-mico-popup{
  color: var(--sd-gold);
  cursor: pointer;
  font-family: "Oswald", sans-serif;
  font-weight: 500;
  border-bottom: 1px dotted rgba(244,183,64,.5);
  display: inline-block;
}
.gdp-team .btn-mico-popup u{ text-decoration: none; }
.gdp-team .btn-mico-popup:hover{ color: var(--sd-gold-hi); border-bottom-color: var(--sd-gold-hi); }

.gdp-team .mico-popup-wrapper{
  border: 1px solid var(--sd-line-2);
  border-radius: 10px;
  background: var(--sd-surface-2);
  box-shadow: 0 8px 24px rgba(0,0,0,.45);
}
.gdp-team .mico-popup-avg{ font-family: "Oswald", sans-serif; color: var(--sd-gold); }
.gdp-team .mico-popup-qty,
.gdp-team .mico-popup-month{ color: var(--sd-muted); }

.gdp-team .orange-circle{
  border: 1px solid var(--sd-line-2);
  background: var(--sd-surface-2);
}

/* ---------------------------------------------------------------------
   The range control above the members list. Same segmented treatment as
   the profile page's tabs: a recessed track with the chosen option
   raised out of it, because a selected segment that is the same colour as
   its track is not a selection anybody can see.
   ------------------------------------------------------------------ */
.gdp-team .range-bar{
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 4px 0 12px;
}
.gdp-team .range-note{ font-size: 12px; color: var(--sd-muted); }
.gdp-team .range-toggle{
  display: inline-flex; gap: 3px; padding: 3px;
  background: var(--sd-bg); border: 1px solid var(--sd-line-2); border-radius: 10px;
}
.gdp-team .range-btn{
  padding: 6px 12px; border: 1px solid transparent; border-radius: 8px;
  font-family: "Oswald", sans-serif; font-size: 12px; font-weight: 500;
  letter-spacing: .06em; color: var(--sd-muted); white-space: nowrap;
  transition: color .15s, background .15s, border-color .15s;
}
.gdp-team .range-btn:hover{ color: var(--sd-text); text-decoration: none; }
.gdp-team .range-btn.is-on{
  background: var(--sd-surface-2); color: var(--sd-text);
  border-color: var(--sd-line); box-shadow: 0 1px 2px rgba(0,0,0,.45);
}

@media (max-width: 767px){
  .gdp-team .range-bar{ justify-content: center; }
  .gdp-team .range-note{ flex: 1 1 100%; text-align: center; order: 2; }
  .gdp-team .range-btn{ padding: 7px 14px; }
}

/* ---------------------------------------------------------------------
   MEMBERS LIST ON A PHONE

   The table is eight columns. At 380px that truncated the name to about
   ten characters and spent most of the row on five buttons. The same
   cells are re-laid as a two-line grid: no duplicate markup, no second
   render, and the table is untouched above this width.

     card | name .................... | ›
     card | mico   jdc      last seen | ›

   PLACED EXPLICITLY, not with grid-template-areas. Areas read nicely but
   a single token out of step silently invalidates the whole property and
   the cells fall back to auto-placement, which is a hard thing to see in
   a screenshot. Row and column per cell cannot fail that way.
   ------------------------------------------------------------------ */
@media (max-width: 767px){
  /* THE LIST RUNS ALMOST TO THE EDGE.

     Three separate paddings were stacking: Bootstrap's column at 15px,
     the teambox at 14px and the row at 8px, so every row started 37px in
     from each side of a 380px screen. Nearly a fifth of the width was
     margin.

     Now 6 + 6 + 4, so 16px a side. The list is a full-width surface with
     the content near its edges, which is what a phone wants. */
  /* The side padding is zeroed unconditionally further up, not here —
     see the note by .gdp-team .members-list. */
  .gdp-team .members-list .teambox{ padding: 10px 6px; border-radius: 12px; }
  .gdp-team .members-list .teambox-heading{ padding-bottom: 8px; margin-bottom: 8px; }
  .gdp-team .members-list .range-bar{ margin: 2px 0 10px; }

  .gdp-team .members-table thead,
  .gdp-team .members-table > tbody > tr:first-child,
  .gdp-team .cell-dot,
  .gdp-team .cell-rank,
  .gdp-team .cell-darts,
  .gdp-team .cell-active,
  .gdp-team .row-tools{ display: none !important; }

  /* THE PHONE ROW SHOWS THE SAME THREE FIGURES IN EVERY RANGE.
     Played games and when they last threw are scanned; a JDC average with
     its quantity is a two-part figure that has to be read, and darts and
     active days are in the snapshot a tap away. Which three are shown no
     longer depends on the range, so a coach switching from 30 days to All
     time sees the same row with different numbers in it.

     Written against the 0-3-2 baseline set by
     `.gdp-team .members-table tr.tablerow > td`; a short selector here is
     silently outranked and the cell stays visible. */
  .gdp-team .members-table tr.tablerow > td.cell-jdc,
  .gdp-team .members-table tr.tablerow > td.cell-darts,
  .gdp-team .members-table tr.tablerow > td.cell-active{ display: none; }

  .gdp-team .members-table,
  .gdp-team .members-table > tbody{ display: block; width: 100%; }

  .gdp-team .members-table tr.tablerow{
    display: grid;
    grid-template-columns: 22px minmax(0,1fr) auto auto 14px;
    align-items: center;
    column-gap: 8px; row-gap: 0;
    padding: 7px 4px;
    border-bottom: 1px solid var(--sd-line);
    cursor: pointer;
  }
  .gdp-team .members-table tr.tablerow:active{ background: rgba(173,194,224,.07); }
  .gdp-team .members-table tr.tablerow > td{
    display: block; padding: 0; border: 0; text-align: left;
    line-height: 1.25;
  }

  /* THE RIGHT-HAND FIGURES SPAN BOTH ROWS, label above value.
     Row one was empty to the right of the name, and the labels were
     sitting inline in front of their numbers on row two, eating the width
     the numbers needed. Stacked, each figure gets a caption for free and
     the row reads as a small table per member:

       card | Benny Sundin   GAMES  LAST
       card | MICO N/A       79     5 months ago

     MICO keeps its inline prefix. It sits under the name, so a caption
     above it would collide with the name itself. */
  .gdp-team .cell-profile{ grid-column: 1; grid-row: 1 / 3; }
  .gdp-team .col-name    { grid-column: 2; grid-row: 1; font-size: 14px; min-width: 0;
                           white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .gdp-team .cell-mico    { grid-column: 2; grid-row: 2; min-width: 0; }
  /* WRITTEN AGAINST THE BASELINE, not short.
     `.gdp-team .members-table tr.tablerow > td` sets display:block at
     0-3-2. A short `.gdp-team .cell-act` is 0-2-0 and loses to it, so
     display:flex never applied and the caption stayed inline in front of
     its value. Anything in this block that changes how a cell lays out
     has to clear 0-3-2. */
  .gdp-team .members-table tr.tablerow > td.cell-sessions,
  .gdp-team .members-table tr.tablerow > td.cell-act{
    grid-row: 1 / 3; display: flex; flex-direction: column;
    justify-content: center; align-items: flex-start; gap: 2px;
  }
  .gdp-team .cell-sessions{ grid-column: 3; }
  .gdp-team .cell-act     { grid-column: 4; }
  .gdp-team .cell-tools  { grid-column: 5; grid-row: 1 / 3; }

  /* The address card replaces the online dot here. It is the coach's way
     into the player info card, which is worth more on a phone than a
     green or grey dot. */
  .gdp-team .member-card-link{
    display: block; color: var(--sd-muted); font-size: 17px; line-height: 1;
  }
  .gdp-team .member-card-link:hover{ color: var(--sd-green); }

  /* The MICO cell wraps its figure in a positioned div, for the popup to
     anchor to. Left as a block it put the prefix on one line and the
     number on the next and doubled the height of every row. */
  .gdp-team .cell-mico > div{ display: inline-block; }

  .gdp-team .cell-mico{ font-size: 12px; color: var(--sd-muted); white-space: nowrap; }
  /* The values themselves read as data, so they take the text colour
     rather than the muted one their captions use. */
  .gdp-team .cell-sessions,
  .gdp-team .cell-act{ font-size: 13px; color: var(--sd-text); white-space: nowrap; }

  /* Bare numbers whose meaning changes with the range. A short prefix
     costs almost nothing and stops "14.92 31 2d" being a guess. */
  /* The caption line above each figure. Small, tracked and muted, so it
     is legible without competing with the number under it. */
  .gdp-team .cell-sessions::before,
  .gdp-team .cell-act::before{
    font-family: "Oswald", sans-serif;
    font-size: 9px; font-weight: 500; letter-spacing: .12em;
    text-transform: uppercase; color: var(--sd-muted); opacity: .8;
    line-height: 1;
  }
  .gdp-team .cell-sessions::before{ content: "Games"; }
  .gdp-team .cell-act::before{ content: "Last played"; }

  /* MICO stays inline: it sits beneath the name, and a caption there
     would run into it. */
  .gdp-team .cell-mico::before{ content: "MICO "; opacity: .7; }

  .gdp-team .btn-mico-popup{ padding: 0; font-size: 12px; display: inline; }

  .gdp-team .row-chev{
    display: block; color: var(--sd-muted); font-size: 18px; line-height: 1;
  }

  /* A non-premium member has one wide cell instead of the figures. */
  .gdp-team .members-table tr.tablerow > td[colspan]{ grid-column: 2 / 5; grid-row: 1; }

  .gdp-team .row-btn{ width: 32px; height: 32px; }
}

/* The played-games column used to carry hidden-xs hidden-sm. Those are
   display:none !important, so the phone layout had no way to bring the
   column back when it wanted it. The Bootstrap classes are gone and the
   widths are decided here instead: hidden on tablets, where the table is
   still eight columns and tight, shown on desktop and shown again on a
   phone, where the layout is a two-line grid with room for it. */
/* Tablets get the table but not all six figures: darts and active days
   come off first, since sessions and the last-played date already answer
   whether somebody has been throwing. */
@media (min-width: 768px) and (max-width: 991px){
  .gdp-team .cell-darts,  .gdp-team .cell-darts-hd,
  .gdp-team .cell-active, .gdp-team .cell-active-hd{ display: none; }
}

/* Desktop keeps the table exactly as it was: the chevron is a phone-only
   affordance and the row is not clickable up here, where five labelled
   controls fit comfortably. */
.gdp-team .row-chev{ display: none; }
.gdp-team .member-card-link{ color: var(--sd-muted); }
.gdp-team .member-card-link:hover{ color: var(--sd-green); }

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

   Twelve leaderboards, two per row. Was a #999 border round a #151515
   header with #ccc body text, none of which came from the palette.
   ------------------------------------------------------------------ */
.gdp-team .chal-card{
  background: var(--sd-surface);
  border: 1px solid var(--sd-line);
  border-radius: 14px;
  overflow: hidden;
  margin-bottom: 4px;
}
.gdp-team .chal-head{
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px;
  background: var(--sd-surface-2);
  border-bottom: 1px solid var(--sd-line);
}
.gdp-team .chal-title{
  font-family: "Oswald", sans-serif; font-size: 15px; font-weight: 500;
  color: var(--sd-text); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gdp-team .chal-play{
  flex: 0 0 auto;
  padding: 5px 13px; border-radius: 8px;
  border: 1px solid var(--sd-gold); color: var(--sd-gold);
  font-family: "Oswald", sans-serif; font-size: 11px; letter-spacing: .1em;
}
.gdp-team .chal-play:hover{ background: var(--sd-gold); color: var(--sd-bg); text-decoration: none; }

.gdp-team .chal-table{ margin: 0; }
.gdp-team .chal-table td{ padding: 7px 14px; }
.gdp-team .chal-cols td{
  font-family: "Oswald", sans-serif; font-size: 10px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--sd-muted);
  border-bottom: 1px solid var(--sd-line);
  /* The team colour used to be painted across this row as a background,
     which meant every team got a different and unpredictable header. */
  background: transparent;
}
.gdp-team .chal-rank { width: 44px; text-align: center; color: var(--sd-muted);
                       font-variant-numeric: tabular-nums; }
.gdp-team .chal-who  { max-width: 0; overflow: hidden; text-overflow: ellipsis;
                       white-space: nowrap; color: var(--sd-text); }
.gdp-team .chal-score{ width: 90px; text-align: right;
                       font-variant-numeric: tabular-nums; color: var(--sd-text); }

/* The top three, marked without a medal or a colour per place: the rank
   number is already there, and this only needs to say "these are the
   ones". */
.gdp-team .chal-table .is-podium .chal-rank{ color: var(--sd-gold); font-weight: 600; }
.gdp-team .chal-table .is-podium .chal-score{ font-weight: 600; }

/* The padding rows. Present so every card is the same height and the two
   columns stay level, and quiet enough not to be read as results. */
.gdp-team .chal-table .is-empty td{ color: var(--sd-line-2); }

@media (max-width: 560px){
  .gdp-team .chal-table td{ padding: 6px 11px; }
  .gdp-team .chal-score{ width: 74px; }
}

/* ---------------------------------------------------------------------
   GOALS — THE PLAYER'S BLOCK

   Deliberately not styled like the assignments above it. An assignment is
   a task list for this fortnight; a goal is months of work, and if the
   two looked alike a player would read the goal as another chore and
   forget it by March.
   ------------------------------------------------------------------ */
/* ---------------------------------------------------------------------
   TEAM NEWS: the banner, and the player's page
   ------------------------------------------------------------------ */

/* Only ever shown when there IS something unread, so it never becomes
   furniture a player learns to ignore. */
.gdp-team .np-banner{
  display:flex; align-items:center; gap:12px;
  padding:13px 16px; margin-bottom:16px;
  background:rgba(255,162,0,.10);
  border:1px solid rgba(255,162,0,.34);
  border-left:4px solid var(--sd-gold);
  border-radius:12px;
  color:var(--sd-text);
}
.gdp-team .np-banner:hover{ background:rgba(255,162,0,.16); text-decoration:none; color:var(--sd-text); }
.gdp-team .np-banner-i{ color:var(--sd-gold); font-size:17px; line-height:1; }
.gdp-team .np-banner-t{ flex:1; min-width:0; font-size:14px; }
.gdp-team .np-banner-go{
  flex:0 0 auto; font-family:"Oswald",sans-serif; font-size:11px;
  letter-spacing:.1em; text-transform:uppercase; color:var(--sd-gold);
}

/* HOW MANY PLAYERS HAVE READ A POST.

   Under each post in the coach's list. The bar is there because a coach
   scanning ten posts reads shapes faster than numbers, and the number is
   there because "most of them" is not good enough when deciding whether
   to repeat something at training. */
.gdp-team .post-read{ display:flex; align-items:center; gap:9px; margin-top:6px; }
.gdp-team .post-read-bar{
  flex:0 0 62px; height:4px; border-radius:99px;
  background:var(--sd-surface-2); overflow:hidden;
}
.gdp-team .post-read-bar span{
  display:block; height:100%; border-radius:99px; background:var(--sd-muted);
}
.gdp-team .post-read-t{ font-size:11px; color:var(--sd-muted); }

/* Read by everyone, or nearly. Worth seeing at a glance. */
.gdp-team .post-read.is-most .post-read-bar span{ background:var(--sd-green); }
.gdp-team .post-read.is-most .post-read-t{ color:var(--sd-green); }

/* Read by nobody. Not an error, but the one case a coach should notice:
   said plainly rather than as "0 of 24", which reads like a broken
   counter. */
.gdp-team .post-read.is-none .post-read-t{ color:var(--sd-gold); }

/* The count on the menu link, so the tab itself is the notice. */
.gdp-team .np-dot{
  display:inline-block; margin-left:6px; padding:1px 6px;
  border-radius:99px; background:var(--sd-gold); color:var(--sd-bg);
  font-family:"Oswald",sans-serif; font-size:10px; line-height:1.5;
  vertical-align:middle;
}

.gdp-team .np-new-count{
  font-family:"Oswald",sans-serif; font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--sd-gold);
}
.gdp-team .np-none{ color:var(--sd-muted); font-size:14px; margin:0; }

.gdp-team .np-list{ display:flex; flex-direction:column; }
.gdp-team .np-post{
  padding:16px 0; border-top:1px solid var(--sd-line);
}
.gdp-team .np-post:first-child{ border-top:0; padding-top:4px; }

.gdp-team .np-meta{ display:flex; align-items:center; gap:10px; margin-bottom:4px; }
.gdp-team .np-date{
  font-family:"Oswald",sans-serif; font-size:11px; letter-spacing:.08em;
  color:var(--sd-muted);
}
/* Marked from what was unread when the page opened, not from what is
   unread now: opening the page is what marks them read, so by the time
   this renders the answer would always be none. */
.gdp-team .np-flag{
  font-family:"Oswald",sans-serif; font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--sd-bg);
  background:var(--sd-gold); padding:2px 7px; border-radius:99px;
}
.gdp-team .np-title{
  font-family:"Oswald",sans-serif; font-size:19px; font-weight:500;
  color:var(--sd-text); margin:0 0 6px;
}
/* The coach writes these in a rich text editor, so the body carries their
   own markup and needs sane defaults rather than a fixed style. */
.gdp-team .np-body{ font-size:14px; line-height:1.65; color:var(--sd-text); }
.gdp-team .np-body p{ margin:0 0 10px; }
.gdp-team .np-body p:last-child{ margin-bottom:0; }
.gdp-team .np-body a{ color:var(--sd-gold); text-decoration:underline; }
.gdp-team .np-body ul, .gdp-team .np-body ol{ margin:0 0 10px 20px; }
.gdp-team .np-body img{ max-width:100%; height:auto; border-radius:8px; }

/* The block had no spacing of its own. It sits inside a .gdp-cell, and
   the page grid's gap separates CELLS, not two boxes sharing one. So it
   sat flush against the box above it. */
.gdp-team .gdp-goals-block{ margin-bottom: 16px; }
@media (max-width: 767px){
  .gdp-team .gdp-goals-block{ margin-bottom: 12px; }
}

.gdp-team .gb-tally{
  font-family:"Oswald",sans-serif; font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--sd-green);
}
.gdp-team .gb-none{ color:var(--sd-muted); font-size:14px; margin:0; line-height:1.6; }
.gdp-team .gb-list{ display:flex; flex-direction:column; gap:10px; }

.gdp-team .gb-goal{
  padding:13px 14px;
  background:rgba(173,194,224,.03);
  border:1px solid var(--sd-line);
  border-radius:12px;
}
.gdp-team .gb-goal.is-done{
  background:var(--sd-good-bg); border-color:var(--sd-good-border);
}

/* The header is the toggle, so it behaves like one. */
.gdp-team .gb-top{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  cursor:pointer; outline:none;
}
.gdp-team .gb-top:focus-visible{ outline:2px solid var(--sd-gold); outline-offset:3px; border-radius:8px; }

/* COLLAPSED. display:none rather than an animated height, for the reason
   the presets collapse uses it: a height animation on a card containing an
   SVG chart has to guess the height, and guesses wrong the first time. */
.gdp-team .gb-goal .gb-body{ display:block; }
.gdp-team .gb-goal.is-shut .gb-body{ display:none; }
.gdp-team .gb-goal.is-shut{ padding:11px 14px; }

/* What a shut card still says. */
.gdp-team .gb-sum{ margin-left:auto; font-size:12px; white-space:nowrap; }
.gdp-team .gb-sum-done{ color:var(--sd-green); }
.gdp-team .gb-goal:not(.is-shut) .gb-sum{ display:none; }

/* A chevron, rotated. Drawn from borders so it needs no font and no
   image. */
.gdp-team .gb-chev{
  flex:0 0 auto; width:8px; height:8px; margin-left:4px;
  border-right:2px solid var(--sd-muted);
  border-bottom:2px solid var(--sd-muted);
  transform:rotate(45deg); transition:transform .15s;
}
.gdp-team .gb-goal.is-shut .gb-chev{ transform:rotate(-45deg); }
.gdp-team .gb-top:hover .gb-chev{ border-color:var(--sd-text); }
.gdp-team .gb-what{ min-width:0; }
.gdp-team .gb-name{
  font-family:"Oswald",sans-serif; font-size:16px; font-weight:500; color:var(--sd-text);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.gdp-team .gb-target{ font-size:13px; color:var(--sd-muted); margin-top:2px; }
.gdp-team .gb-target strong{ color:var(--sd-text); font-weight:600; }

/* The only useful response to seeing a goal is to go and throw. */
.gdp-team .gb-play{
  flex:0 0 auto; padding:7px 16px; border-radius:9px;
  background:var(--sd-gold); color:var(--sd-bg);
  font-family:"Oswald",sans-serif; font-size:12px; letter-spacing:.08em;
  text-transform:uppercase;
}
.gdp-team .gb-play:hover{ background:var(--sd-gold-hi); text-decoration:none; color:var(--sd-bg); }
.gdp-team .gb-done-mark{ flex:0 0 auto; color:var(--sd-green); font-size:20px; line-height:1; }

/* THE PROGRESS METER.

   It was a bare green bar sitting flush above the chart, which read as a
   ceiling drawn across the plot rather than as progress from nothing to
   the goal. Three things fix that: a caption and a number so it is
   labelled, ends marked 0 and Goal so it is a scale, and real space
   between it and the chart so they are two separate objects. */
.gdp-team .gb-progress{ margin:12px 0 16px; }

.gdp-team .gb-progress-l{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:10px; margin-bottom:5px;
}
.gdp-team .gb-progress-cap{
  font-family:"Oswald",sans-serif; font-size:10px; font-weight:500;
  letter-spacing:.14em; text-transform:uppercase; color:var(--sd-muted);
}
.gdp-team .gb-progress-v{
  font-family:"Oswald",sans-serif; font-size:13px; color:var(--sd-text);
  font-variant-numeric:tabular-nums;
}
.gdp-team .gb-progress-v.is-done{ color:var(--sd-green); }

.gdp-team .gb-meter{
  position:relative; height:8px; border-radius:99px;
  background:var(--sd-surface-2);
  /* A visible right-hand end, so the track reads as a distance with a
     finish rather than as a line that happens to stop. */
  box-shadow:inset 0 0 0 1px var(--sd-line);
}
.gdp-team .gb-meter-fill{
  display:block; height:100%; border-radius:99px;
  background:var(--sd-muted); position:relative;
  transition:width .3s;
}
/* Where they are, as a point rather than an edge to judge. */
.gdp-team .gb-meter-knob{
  position:absolute; right:-1px; top:50%;
  width:12px; height:12px; margin-top:-6px;
  border-radius:99px; background:inherit;
  box-shadow:0 0 0 3px var(--sd-surface);
}

.gdp-team .gb-progress-scale{
  display:flex; justify-content:space-between;
  margin-top:5px; font-size:10px; color:var(--sd-muted); opacity:.75;
}
/* The colour follows the pace, not the fraction: the same 30% is ahead in
   month one and nearly lost in month five. The knob inherits it. */
.gdp-team .gb-goal.is-ahead .gb-meter-fill,
.gdp-team .gb-goal.is-on_track .gb-meter-fill,
.gdp-team .gb-goal.is-done .gb-meter-fill{ background:var(--sd-green); }
.gdp-team .gb-goal.is-behind .gb-meter-fill{ background:var(--sd-gold); }
.gdp-team .gb-goal.is-at_risk .gb-meter-fill{ background:var(--sd-red); }

/* Count, near miss and pace on one line. The count alone would say 30% in
   month one and month five alike; the state is what says whether 30% is
   good. */
.gdp-team .gb-line{
  display:flex; align-items:baseline; flex-wrap:wrap; gap:4px 12px;
  font-size:12px; color:var(--sd-muted);
}
.gdp-team .gb-count{
  font-family:"Oswald",sans-serif; font-size:14px; color:var(--sd-text);
  font-variant-numeric:tabular-nums;
}
.gdp-team .gb-best{ color:var(--sd-text); }
.gdp-team .gb-state{ letter-spacing:.04em; }
.gdp-team .gb-state--ahead,
.gdp-team .gb-state--on_track{ color:var(--sd-green); }
.gdp-team .gb-state--behind{ color:var(--sd-gold); }
.gdp-team .gb-state--at_risk{ color:var(--sd-red); }
.gdp-team .gb-left, .gdp-team .gb-pace{ margin-left:auto; }
.gdp-team .gb-pace{ margin-left:0; }

/* THE MOMENT.
   A six-month goal that completes silently teaches a player that
   finishing does not matter. Shown once. */
.gdp-team .gb-win{
  position:fixed; inset:0; z-index:12500;
  display:flex; align-items:center; justify-content:center; padding:20px;
  font-family:"Hanken Grotesk",system-ui,sans-serif;
}
.gdp-team .gb-win-bd{ position:absolute; inset:0; background:rgba(6,9,13,.82); }
.gdp-team .gb-win-box{
  position:relative; z-index:1; width:100%; max-width:400px; text-align:center;
  background:var(--sd-surface); border:1px solid var(--sd-good-border);
  border-radius:18px; padding:30px 26px; color:var(--sd-text);
  box-shadow:0 24px 60px rgba(0,0,0,.6);
}
.gdp-team .gb-win-mark{
  width:56px; height:56px; margin:0 auto 14px;
  display:flex; align-items:center; justify-content:center;
  border-radius:99px; background:var(--sd-good-bg);
  border:1px solid var(--sd-good-border);
  color:var(--sd-green); font-size:26px; line-height:1;
}
.gdp-team .gb-win-eyebrow{
  font-family:"Oswald",sans-serif; font-size:11px; font-weight:500;
  letter-spacing:.18em; text-transform:uppercase; color:var(--sd-green);
}
.gdp-team .gb-win-t{
  font-family:"Oswald",sans-serif; font-size:26px; font-weight:500; margin:6px 0 0;
}
.gdp-team .gb-win-lead{ margin:8px 0 0; font-size:14px; color:var(--sd-muted); line-height:1.5; }
.gdp-team .gb-win-tally{ margin:12px 0 0; font-size:13px; color:var(--sd-text); }
.gdp-team .gb-win-box .gdp-dlg-btn{ margin-top:20px; width:100%; }

@media (max-width:560px){
  .gdp-team .gb-left{ margin-left:0; }
  .gdp-team .gb-win{ padding:14px; }
}

/* ---------------------------------------------------------------------
   THE GOAL CHART

   Inline SVG, sized by its container. preserveAspectRatio="none" on a
   1000-unit viewBox means the chart stretches to whatever width it is
   given without the dots deforming, because they are drawn after the
   scaling is decided.
   ------------------------------------------------------------------ */
.gdp-team .gc-wrap{ margin:10px 0 4px; }
.gdp-team .gc-svg{ display:block; width:100%; height:auto; overflow:visible; }

/* Everything on the good side of the target. Shaded so the chart reads
   before any single dot is examined. */
.gdp-team .gc-band{ fill:rgba(39,210,163,.07); }

/* A rule, not data, so it is dashed. */
.gdp-team .gc-target{
  stroke:var(--sd-green); stroke-width:1.5; stroke-dasharray:5 4; opacity:.8;
}

/* The run of attempts. Faint while the dots carry the values, because it
   is only there to show direction. */
.gdp-team .gc-line{
  fill:none; stroke:var(--sd-line-2); stroke-width:1.5;
  stroke-linejoin:round; vector-effect:non-scaling-stroke;
}
/* Past sixty sessions the dots are gone and the line IS the data, so it
   takes the weight they were carrying. */
.gdp-team .gc-line.is-dense{ stroke:var(--sd-muted); stroke-width:1.8; }

.gdp-team .gc-dot{ fill:var(--sd-muted); }
.gdp-team .gc-dot:hover{ fill:var(--sd-text); }

/* A session that met the target. A star rather than a differently
   coloured dot: it is the moment the player did what was asked, and that
   is worth something that looks like a reward. */
.gdp-team .gc-star{ fill:var(--sd-green); }
.gdp-team .gc-star:hover{ fill:var(--sd-gold); }

.gdp-team .gc-legend{
  display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap;
  margin-top:4px; font-size:11px; color:var(--sd-muted);
}
/* The x axis is attempt order, which is not obvious from looking at it.
   Said once, quietly. */
.gdp-team .gc-legend-axis{ opacity:.75; }
.gdp-team .gc-legend-target{ color:var(--sd-green); }
.gdp-team .gc-none{ font-size:12px; color:var(--sd-muted); padding:8px 0; }

/* Past what the coach asked for, and still going. */
.gdp-team .gb-over,
.gdp-team .goal-over{ color:var(--sd-gold); }

/* ---------------------------------------------------------------------
   GOALS — the coach's page
   ------------------------------------------------------------------ */
.gdp-team .goal-bar{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; flex-wrap:wrap; margin-bottom:14px;
}
.gdp-team .goal-bar-note{ font-size:13px; color:var(--sd-muted); }
/* When these numbers were last counted. Quiet, but present: a figure that
   might be minutes old and does not say so reads as broken. */
.gdp-team .goal-bar-stamp{
  margin-left:10px; padding-left:10px; border-left:1px solid var(--sd-line);
  font-size:11px; color:var(--sd-muted); opacity:.8;
}
.gdp-team .goal-refresh{ color:var(--sd-gold); margin-left:4px; }
.gdp-team .goal-refresh:hover{ text-decoration:underline; color:var(--sd-gold); }
.gdp-team .goal-none{ color:var(--sd-muted); font-size:14px; margin:0; padding:4px 0 8px; line-height:1.6; }

/* ONE CARD PER PLAYER.

   All of a player's goals live inside their own box, so a coach with
   thirty players reads thirty blocks rather than one long list where the
   only thing separating people was a hairline.

   Kept tight on purpose. Thirty players at three goals each is ninety
   rows, and generous padding would turn that into a page nobody
   scrolls. */
.gdp-team .goal-player{
  position:relative;
  /* A STEP LIGHTER THAN THE PANEL IT SITS ON.

     This was var(--sd-surface), which is what .teambox around it already
     uses, so the cards were the same tone as their own background and
     only the border said where one player ended. --sd-surface-2 is the
     lighter of the two the theme already defines, so the cards lift off
     the panel without introducing a colour that exists nowhere else. */
  background:var(--sd-surface-2);
  border:1px solid var(--sd-line-2);
  border-left:3px solid var(--sd-line-2);
  border-radius:10px;
  padding:14px 16px 6px;
  /* SEPARATION OVER DENSITY, as asked. A coach picking one player out of
     thirty is helped more by the gap than by fitting two more rows on
     the screen. */
  margin-bottom:20px;
}
.gdp-team .goal-player:last-child{ margin-bottom:4px; }
.gdp-team .goal-player:first-of-type{ border-top:1px solid var(--sd-line-2); padding-top:14px; }

/* The dividers between goals have to lift too, or they disappear against
   the lighter card. */
.gdp-team .goal-player .goal-row{ border-bottom-color:rgba(255,255,255,.09); }

/* The name is the thing you look for, so it reads as a heading rather
   than as another line of content. It was 15px against 14px body text,
   which is why it did not. */
.gdp-team .goal-player-h{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:12px; margin-bottom:10px;
}
.gdp-team .goal-player-n{
  font-family:"Oswald",sans-serif; font-size:20px; font-weight:600;
  line-height:1.2; letter-spacing:.01em; margin:0; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* Quiet, because it is a fact rather than a heading. */
.gdp-team .goal-player-c{
  font-family:"JetBrains Mono",monospace; font-size:11px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--sd-muted); white-space:nowrap; flex:0 0 auto;
}

/* The last goal in a card has no divider: it would be a line against the
   card's own edge. */
.gdp-team .goal-player .goal-row:last-child{ border-bottom:0; }

/* TEN COLOURS, CYCLED.

   Only the card's left edge and the name are tinted. The progress bars
   stay status-coloured, because a coach reads red as "this goal is in
   trouble" and that has to keep meaning what it means.

   Chosen to be distinguishable side by side rather than to be a
   spectrum, and all light enough to read on the dark surface. */
.gdp-team .goal-player.is-c1 { border-left-color:#5fd39a; }
.gdp-team .goal-player.is-c1  .goal-player-n{ color:#5fd39a; }
.gdp-team .goal-player.is-c2 { border-left-color:#6fb3d2; }
.gdp-team .goal-player.is-c2  .goal-player-n{ color:#6fb3d2; }
.gdp-team .goal-player.is-c3 { border-left-color:#e0a33a; }
.gdp-team .goal-player.is-c3  .goal-player-n{ color:#e0a33a; }
.gdp-team .goal-player.is-c4 { border-left-color:#c58ce0; }
.gdp-team .goal-player.is-c4  .goal-player-n{ color:#c58ce0; }
.gdp-team .goal-player.is-c5 { border-left-color:#e8705f; }
.gdp-team .goal-player.is-c5  .goal-player-n{ color:#e8705f; }
.gdp-team .goal-player.is-c6 { border-left-color:#4fc7c7; }
.gdp-team .goal-player.is-c6  .goal-player-n{ color:#4fc7c7; }
.gdp-team .goal-player.is-c7 { border-left-color:#9db85c; }
.gdp-team .goal-player.is-c7  .goal-player-n{ color:#9db85c; }
.gdp-team .goal-player.is-c8 { border-left-color:#e58fb0; }
.gdp-team .goal-player.is-c8  .goal-player-n{ color:#e58fb0; }
.gdp-team .goal-player.is-c9 { border-left-color:#8fa6e8; }
.gdp-team .goal-player.is-c9  .goal-player-n{ color:#8fa6e8; }
.gdp-team .goal-player.is-c10{ border-left-color:#d9a066; }
.gdp-team .goal-player.is-c10 .goal-player-n{ color:#d9a066; }

@media (max-width:560px){
  .gdp-team .goal-player{ padding:12px 13px 5px; margin-bottom:16px; }
  .gdp-team .goal-player-n{ font-size:18px; }
}

/* One goal. The bar spans the full width under the text rather than
   sitting in a column, because progress is the thing being read and a
   narrow bar in a table cell is decoration. */
.gdp-team .goal-row{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto auto;
  grid-template-areas:"main num acts" "meter meter meter" "chart chart chart";
  align-items:center; gap:6px 14px;
  padding:10px 0;
  border-bottom:1px solid var(--sd-line-2);
}
.gdp-team .goal-main{ grid-area:main; min-width:0; }
.gdp-team .goal-num { grid-area:num; text-align:right; white-space:nowrap; }
.gdp-team .goal-acts{ grid-area:acts; display:flex; gap:10px; }
.gdp-team .goal-meter{ grid-area:meter; }
.gdp-team .goal-chart{ grid-area:chart; }

.gdp-team .goal-title{
  font-size:14px; color:var(--sd-text);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.gdp-team .goal-sub{ font-size:11px; color:var(--sd-muted); margin-top:2px; }

.gdp-team .goal-count{
  font-family:"Oswald",sans-serif; font-size:15px; color:var(--sd-text);
  font-variant-numeric:tabular-nums;
}
/* The near miss. A count alone never says "you are close". */
.gdp-team .goal-best{ display:block; font-size:11px; color:var(--sd-muted); }

/* Same shape as the player's meter, at the tighter scale a list needs. */
.gdp-team .goal-meter{
  position:relative; height:6px; border-radius:99px;
  background:var(--sd-surface-2);
  box-shadow:inset 0 0 0 1px var(--sd-line);
  margin:6px 0 2px;
}
.gdp-team .goal-meter-fill{
  display:block; height:100%; background:var(--sd-muted);
  border-radius:99px; position:relative;
}
.gdp-team .goal-meter-knob{
  position:absolute; right:-1px; top:50%;
  width:10px; height:10px; margin-top:-5px;
  border-radius:99px; background:inherit;
  box-shadow:0 0 0 3px var(--sd-surface);
}
.gdp-team .goal-meter-v{
  position:absolute; right:0; top:-16px;
  font-family:"Oswald",sans-serif; font-style:normal; font-size:10px;
  color:var(--sd-muted); font-variant-numeric:tabular-nums;
}

/* PACE, NOT JUST PROGRESS. The same 3-of-10 is ahead in month one and
   nearly lost in month five, so the colour follows the pace rather than
   the fraction. */
.gdp-team .goal-row.is-ahead    .goal-meter-fill,
.gdp-team .goal-row.is-on_track .goal-meter-fill{ background:var(--sd-green); }
.gdp-team .goal-row.is-behind   .goal-meter-fill{ background:var(--sd-gold); }
.gdp-team .goal-row.is-at_risk  .goal-meter-fill,
.gdp-team .goal-row.is-expired  .goal-meter-fill{ background:var(--sd-red); }
.gdp-team .goal-row.is-done     .goal-meter-fill{ background:var(--sd-green); }
.gdp-team .goal-row.is-done     .goal-count{ color:var(--sd-green); }
.gdp-team .goal-row.is-expired{ opacity:.7; }

.gdp-team .goal-flag{ font-size:10px; letter-spacing:.1em; text-transform:uppercase; }
.gdp-team .goal-flag--done{ color:var(--sd-green); }
.gdp-team .goal-flag--miss{ color:var(--sd-red); }

.gdp-team .goal-act{ font-size:12px; color:var(--sd-muted); cursor:pointer; white-space:nowrap; }
.gdp-team .goal-act:hover{ color:var(--sd-text); text-decoration:underline; }
.gdp-team .goal-act--x:hover{ color:var(--sd-red); }

/* The form. */
.gdp-team .goal-modal{
  position:fixed; inset:0; z-index:12000;
  display:flex; align-items:center; justify-content:center; padding:20px;
  font-family:"Hanken Grotesk",system-ui,sans-serif;
}
.gdp-team .goal-modal[hidden]{ display:none; }
.gdp-team .goal-modal-bd{ position:absolute; inset:0; background:rgba(6,9,13,.78); }
.gdp-team .goal-modal-box{
  position:relative; z-index:1; width:100%; max-width:480px;
  max-height:calc(100vh - 48px); overflow-y:auto;
  background:var(--sd-surface); border:1px solid var(--sd-line-2);
  border-radius:16px; padding:24px; color:var(--sd-text);
  box-shadow:0 22px 56px rgba(0,0,0,.6);
}
.gdp-team .goal-modal-t{
  font-family:"Oswald",sans-serif; font-size:22px; font-weight:500; margin:0 0 16px;
}
.gdp-team .goal-f{ display:block; margin-bottom:12px; }
.gdp-team .goal-f-l{
  display:block; font-family:"Oswald",sans-serif; font-size:10px; font-weight:500;
  letter-spacing:.12em; text-transform:uppercase; color:var(--sd-muted); margin-bottom:5px;
}
.gdp-team .goal-f select,
.gdp-team .goal-f input{
  width:100%; padding:10px 12px;
  background:var(--sd-bg); color:var(--sd-text);
  border:1px solid var(--sd-line-2); border-radius:9px;
  font-size:14px; font-family:inherit;
}
.gdp-team .goal-f select:focus,
.gdp-team .goal-f input:focus{ outline:none; border-color:var(--sd-gold); }
.gdp-team .goal-f-row{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }

/* TYPE-TO-FILTER FIELDS.

   The real <select> is still there and still what gets submitted; it is
   only hidden. So the form works without the script, and every handler
   that reads .js-goal-game or .js-goal-member is untouched. */
.gdp-team .gf-pick{ position:relative; }
/* THE SCROLLBAR ALONG THE BOTTOM OF THE GOAL DIALOG.

   This rule hides the real <select>, but it was losing to the field
   styling further up the file:

     .gdp-team .goal-f select   two classes AND an element  (0,2,1)
     .gdp-team .gf-pick-real    two classes                 (0,2,0)

   Higher specificity wins whatever the order, so width:100% beat
   width:1px and the select was laid out at full width, absolutely
   positioned at its static position after a block-level input. That put
   it a full field-width past the right edge of the dialog, and because
   .goal-modal-box sets overflow-y:auto (which makes the other axis auto
   too, by spec) it showed up as a scrollbar under an empty form.

   Matching that specificity with .goal-f is the fix. The select stays
   present and submittable, which is the point of hiding it this way
   rather than with display:none. */
.gdp-team .goal-f.gf-pick .gf-pick-real,
.gdp-team .gf-pick-real{
  position:absolute; top:0; left:0;
  width:1px; height:1px; margin:-1px; padding:0; border:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%);
  appearance:none;
}

/* Grid items default to min-width:auto, so a date field's intrinsic
   width can stop 1fr behaving like a half. Cheap insurance on a row
   that holds two of them. */
.gdp-team .goal-f-row > *{ min-width:0; }
.gdp-team .goal-f input,
.gdp-team .goal-f select{ max-width:100%; box-sizing:border-box; }

/* If a future field ever does overflow, it should not put a scrollbar
   under the whole dialog. */
.gdp-team .goal-modal-box{ overflow-x:hidden; }

/* The vertical scrollbar is still wanted for a long options list, but
   thin and in the team palette, matching .gf-pick-list below. */
.gdp-team .goal-modal-box{ scrollbar-width:thin; scrollbar-color:var(--sd-line-2) transparent; }
.gdp-team .goal-modal-box::-webkit-scrollbar{ width:6px; height:6px; }
.gdp-team .goal-modal-box::-webkit-scrollbar-track{ background:transparent; }
.gdp-team .goal-modal-box::-webkit-scrollbar-thumb{ background:var(--sd-line-2); border-radius:99px; }
.gdp-team .gf-pick-in{
  width:100%; padding:10px 12px;
  background:var(--sd-bg); color:var(--sd-text);
  border:1px solid var(--sd-line-2); border-radius:9px;
  font-size:14px; font-family:inherit;
}
.gdp-team .gf-pick-in:focus{ outline:none; border-color:var(--sd-gold); }

.gdp-team .gf-pick-list{
  position:absolute; z-index:30; left:0; right:0; top:100%;
  margin-top:4px; max-height:230px; overflow-y:auto;
  background:var(--sd-surface-2);
  border:1px solid var(--sd-line-2); border-radius:10px;
  box-shadow:0 14px 34px rgba(0,0,0,.5);
  scrollbar-width:thin; scrollbar-color:var(--sd-line-2) transparent;
}
.gdp-team .gf-pick-list::-webkit-scrollbar{ width:6px; }
.gdp-team .gf-pick-list::-webkit-scrollbar-thumb{ background:var(--sd-line-2); border-radius:99px; }

.gdp-team .gf-pick-opt{
  padding:9px 12px; font-size:14px; color:var(--sd-text); cursor:pointer;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.gdp-team .gf-pick-opt:hover,
.gdp-team .gf-pick-opt.is-cursor{ background:rgba(173,194,224,.08); }
/* The current choice, so a coach reopening the list sees where they are. */
.gdp-team .gf-pick-opt.is-on{ color:var(--sd-gold); }
.gdp-team .gf-pick-none{ padding:11px 12px; font-size:13px; color:var(--sd-muted); }
.gdp-team .goal-opt-none{ font-size:12px; color:var(--sd-red); margin-bottom:10px; }

/* The goal as the player will read it, before it is saved. This is where
   a coach notices they picked a lower-is-better game. */
.gdp-team .goal-preview{
  margin:4px 0 0; padding:11px 13px;
  background:var(--sd-surface-2); border-radius:9px;
  font-size:13px; color:var(--sd-text); min-height:14px;
}
.gdp-team .goal-preview:empty{ display:none; }

.gdp-team .goal-modal-foot{ display:flex; gap:8px; margin-top:18px; }
.gdp-team .goal-modal-foot .gdp-dlg-btn{ flex:1 1 0; }

@media (max-width:560px){
  .gdp-team .goal-row{
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"main num" "acts acts" "meter meter" "chart chart";
  }
  .gdp-team .goal-f-row{ grid-template-columns:1fr; }
  .gdp-team .goal-modal{ padding:12px; align-items:flex-end; }
  .gdp-team .goal-modal-box{ padding:20px; }
}

/* INSIDE THE TEAM AREA, the information page sits in a container that
   already has padding and a width. The hero would otherwise try to run
   full-bleed inside a 1170px column and look cropped rather than
   cinematic, so it is toned down to a panel there.

   The public page has no such wrapper and keeps the full-bleed hero. */
.gdp-team .gdpt-hero{ min-height:300px; border-radius:12px; overflow:hidden; }
.gdp-team .gdpt-inner{ padding-left:clamp(18px,4vw,40px); padding-right:clamp(18px,4vw,40px); }
.gdp-team .gdpt-sec{ padding:clamp(30px,4vw,52px) 0; }
.gdp-team .gdpt{ background:transparent; }

/* The .ti-* rules that were here are gone. The information page was
   rebuilt on the premium page's design and carries its own styles inline,
   so ninety lines of unused CSS were left behind. Removed rather than
   kept "just in case": dead rules are how a stylesheet becomes something
   nobody dares change. */

/* ---------------------------------------------------------------------
   THE LICENCE PAGE
   ------------------------------------------------------------------ */
.gdp-team .lic-box{ text-align:center; padding:32px 26px; }
.gdp-team .lic-eyebrow{
  font-family:"Oswald",sans-serif; font-size:11px; font-weight:500;
  letter-spacing:.18em; text-transform:uppercase; color:var(--sd-gold);
}
.gdp-team .lic-price{ margin:10px 0 0; display:flex; align-items:baseline; justify-content:center; gap:8px; }
.gdp-team .lic-amount{
  font-family:"Oswald",sans-serif; font-size:52px; font-weight:500;
  line-height:1; color:var(--sd-text);
}
.gdp-team .lic-per{ font-size:15px; color:var(--sd-muted); }

/* The arithmetic. It is the most persuasive thing on the page, so it is
   the first thing under the price rather than a footnote. */
.gdp-team .lic-lead{
  margin:14px auto 0; max-width:460px;
  font-size:15px; line-height:1.6; color:var(--sd-muted);
}
.gdp-team .lic-lead strong{ color:var(--sd-text); }

.gdp-team .lic-list{
  list-style:none; margin:20px auto 0; padding:20px 0 0; max-width:400px;
  border-top:1px solid var(--sd-line); text-align:left;
}
.gdp-team .lic-list li{
  position:relative; padding:7px 0 7px 26px; font-size:14px; color:var(--sd-text);
}
.gdp-team .lic-list li::before{
  content:"\2713"; position:absolute; left:0; top:7px; color:var(--sd-green);
}

.gdp-team .lic-cta{
  display:inline-block; margin-top:24px; padding:15px 34px;
  background:var(--sd-gold); color:var(--sd-bg); border:0; border-radius:11px;
  font-family:"Oswald",sans-serif; font-size:16px; font-weight:500;
  letter-spacing:.06em; text-transform:uppercase; cursor:pointer;
  box-shadow:0 3px 14px rgba(255,162,0,.26);
}
.gdp-team .lic-cta:hover{ background:var(--sd-gold-hi); text-decoration:none; color:var(--sd-bg); }
.gdp-team .lic-cta[disabled]{ opacity:.6; cursor:default; }

.gdp-team .lic-sub{ margin:10px 0 0; font-size:12px; color:var(--sd-muted); }

/* The already-have-Premium warning. Before the button, because after it
   would be after they paid. */
.gdp-team .lic-note{
  margin:18px auto 0; max-width:440px; padding:11px 14px;
  background:var(--sd-surface-2); border-radius:10px;
  font-size:12.5px; line-height:1.55; color:var(--sd-muted);
}
.gdp-team .lic-note a{ color:var(--sd-gold); }

.gdp-team .lic-alt{ margin-top:16px; }
.gdp-team .lic-alt-t{
  font-family:"Oswald",sans-serif; font-size:17px; font-weight:500;
  margin:0 0 8px; color:var(--sd-text);
}
.gdp-team .lic-alt p{ margin:0 0 8px; font-size:14px; line-height:1.6; color:var(--sd-muted); }
.gdp-team .lic-alt a{ color:var(--sd-gold); }

.gdp-team .lic-error{
  margin-bottom:14px; padding:13px 16px;
  background:rgba(239,77,99,.12); border:1px solid rgba(239,77,99,.34);
  border-radius:10px; font-size:14px; color:var(--sd-text);
}

@media (max-width:560px){
  .gdp-team .lic-box{ padding:26px 18px; }
  .gdp-team .lic-amount{ font-size:44px; }
  .gdp-team .lic-cta{ display:block; width:100%; }
}

/* ---------------------------------------------------------------------
   AN EXPIRED LICENCE

   Frosted rather than hidden: the coach should see that their team is
   still there and intact, which is the difference between "renew this"
   and "you have lost your data". The blur is what makes that argument
   without a paragraph explaining it.
   ------------------------------------------------------------------ */
.gdp-team.gdp-lock{
  position:fixed; inset:0; z-index:13000;
  display:flex; align-items:center; justify-content:center; padding:20px;
  background:rgba(8,11,16,.62);
  backdrop-filter:blur(7px); -webkit-backdrop-filter:blur(7px);
  font-family:"Hanken Grotesk",system-ui,sans-serif;
}
/* A coach who chose "manage members" gets out of the way, but the page
   stays visibly restricted. */
.gdp-team.gdp-lock.is-aside{ display:none; }

.gdp-team .gdp-lock-box{
  width:100%; max-width:440px; text-align:center;
  background:var(--sd-surface); border:1px solid var(--sd-line-2);
  border-radius:18px; padding:30px 26px; color:var(--sd-text);
  box-shadow:0 24px 60px rgba(0,0,0,.6);
}
.gdp-team .gdp-lock-eyebrow{
  font-family:"Oswald",sans-serif; font-size:11px; font-weight:500;
  letter-spacing:.18em; text-transform:uppercase; color:var(--sd-gold);
}
.gdp-team .gdp-lock-t{
  font-family:"Oswald",sans-serif; font-size:26px; font-weight:500; margin:6px 0 0;
}
.gdp-team .gdp-lock-lead{ margin:10px 0 0; font-size:15px; line-height:1.55; }
.gdp-team .gdp-lock-sub{ margin:10px 0 0; font-size:13px; line-height:1.6; color:var(--sd-muted); }
.gdp-team .gdp-lock-foot{ display:flex; gap:8px; margin-top:22px; }
.gdp-team .gdp-lock-foot .gdp-dlg-btn{ flex:1 1 0; text-align:center; }

@media (max-width:480px){
  .gdp-team.gdp-lock{ padding:14px; align-items:flex-end; }
  .gdp-team .gdp-lock-box{ padding:22px 20px; }
  .gdp-team .gdp-lock-foot{ flex-direction:column-reverse; }
}

/* THE COACH'S DECLINE DIALOG.
   Reuses .gdp-dlg-btn from team-dialog.php for the buttons, so the two
   dialogs in the team area cannot drift apart. */
.gdp-decline{
  position: fixed; inset: 0; z-index: 12000;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  font-family: "Hanken Grotesk", system-ui, sans-serif;
}
.gdp-decline-bd{ position: absolute; inset: 0; background: rgba(6,9,13,.78); }
.gdp-decline-box{
  position: relative; z-index: 1; width: 100%; max-width: 440px;
  background: var(--sd-surface); border: 1px solid var(--sd-line-2);
  border-radius: 16px; padding: 24px;
  box-shadow: 0 22px 56px rgba(0,0,0,.6); color: var(--sd-text);
}
.gdp-decline-eyebrow{
  font-family: "Oswald", sans-serif; font-size: 11px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--sd-muted);
}
.gdp-decline-t{
  font-family: "Oswald", sans-serif; font-size: 24px; font-weight: 500;
  margin: 6px 0 0; color: var(--sd-text);
}
.gdp-decline-lead{
  margin: 10px 0 0; font-size: 14px; line-height: 1.55; color: var(--sd-muted);
}
.gdp-decline-foot{ display: flex; gap: 8px; margin-top: 20px; }
.gdp-decline-foot .gdp-dlg-btn{ flex: 1 1 0; }
.gdp-decline-foot .gdp-dlg-btn--go{ flex: 1.4 1 0; }

@media (max-width: 480px){
  .gdp-decline{ padding: 12px; align-items: flex-end; }
  .gdp-decline-box{ padding: 20px; }
  .gdp-decline-foot{ flex-direction: column-reverse; }
  .gdp-decline-foot .gdp-dlg-btn{ flex: none; width: 100%; }
}

/* AN INVITED PLAYER, NOT YET A MEMBER.
   Dimmed and italic so the row reads as provisional at a glance: their
   stats columns are empty and will stay empty until they accept. */
.gdp-team .tablerow.is-invited{ opacity: .62; font-style: italic; }
.gdp-team .tablerow.is-invited:hover{ opacity: .78; }

.gdp-team .col-pending{
  display: inline-block; margin-left: 10px;
  font-size: 11px; font-style: normal; letter-spacing: .04em;
  color: var(--sd-muted); white-space: nowrap;
}
.gdp-team .col-pending-x{
  margin-left: 8px; padding-left: 8px;
  border-left: 1px solid var(--sd-line-2);
  color: var(--sd-red); cursor: pointer;
}
.gdp-team .col-pending-x:hover{ color: var(--sd-red); text-decoration: underline; }

@media (max-width: 767px){
  /* On the two-line phone row the label goes under the name rather than
     pushing it out of the way. */
  .gdp-team .col-pending{ display: block; margin: 3px 0 0; }
}

/* A confirmation after saving a team message. Green because it reports a
   completed action, which is what green means in this palette. */
.gdp-team .news-saved{
  display: flex; align-items: center; gap: 9px;
  margin-bottom: 14px; padding: 11px 14px;
  background: var(--sd-good-bg);
  border: 1px solid var(--sd-good-border);
  border-radius: 10px;
  color: var(--sd-green); font-size: 14px;
}
.gdp-team .news-saved::before{ content: "\2713"; font-size: 14px; }

/* ---------------------------------------------------------------------
   Challenge editor
   ------------------------------------------------------------------ */
.gdp-team .chal-editbar{
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 4px 0 0;
}
.gdp-team .chal-editbar-note{ font-size: 12px; color: var(--sd-muted); }

.gdp-team .chal-editor{
  position: fixed; inset: 0; z-index: 11000;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  font-family: "Hanken Grotesk", system-ui, sans-serif;
}
.gdp-team .chal-editor[hidden]{ display: none; }
.gdp-team .chal-editor-bd{ position: absolute; inset: 0; background: rgba(6,9,13,.72); }
.gdp-team .chal-editor-box{
  position: relative; z-index: 1; width: 100%; max-width: 460px;
  max-height: min(640px, calc(100vh - 48px));
  display: flex; flex-direction: column;
  background: var(--sd-surface); border: 1px solid var(--sd-line-2);
  border-radius: 16px; padding: 22px; color: var(--sd-text);
  box-shadow: 0 20px 50px rgba(0,0,0,.55);
}
.gdp-team .chal-editor-t{
  font-family: "Oswald", sans-serif; font-size: 20px; font-weight: 500; margin: 0;
}
.gdp-team .chal-editor-lead{
  margin: 8px 0 14px; font-size: 13px; line-height: 1.5; color: var(--sd-muted);
}

.gdp-team .chal-list{
  list-style: none; margin: 0; padding: 0;
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
}
.gdp-team .chal-item{
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: 9px;
  border: 1px solid transparent;
  /* The row is a toggle; only the grip is a handle. cursor:grab across
     the whole row promised dragging everywhere, which is exactly what it
     used to do — including over the checkbox, where it swallowed the
     click. */
  cursor: pointer;
}
.gdp-team .chal-item:hover{ background: rgba(173,194,224,.06); }
.gdp-team .chal-item.is-dragging{ opacity: .4; border-color: var(--sd-gold); }
/* The locked one does not pretend to be draggable. */
.gdp-team .chal-item.is-locked{ cursor: default; }
.gdp-team .chal-item.is-locked:hover{ background: transparent; }

.gdp-team .chal-grip{
  width: 12px; flex: 0 0 auto;
  color: var(--sd-muted); font-size: 13px; line-height: 1; letter-spacing: -2px;
  cursor: grab; padding: 4px 2px; margin: -4px 0;
}
.gdp-team .chal-grip:active{ cursor: grabbing; }
.gdp-team .chal-item.is-locked .chal-grip{ cursor: default; }
.gdp-team .chal-item-l{
  display: flex; align-items: center; gap: 9px; margin: 0;
  font-weight: 400; cursor: pointer; flex: 1 1 auto; min-width: 0;
}
/* THE BOX IS A SPAN, DRAWN HERE.

   Two earlier attempts styled the <input> itself — first with
   accent-color, then with appearance:none — and neither produced a
   visible box. The theme's own stylesheet, which this package does not
   contain, hides native checkboxes; a common pattern, and invisible to me
   from here.

   So the input keeps the state and the keyboard behaviour, and a sibling
   span is what gets drawn. No rule aimed at inputs can reach a span.

   The input is moved out of sight rather than display:none'd, because
   display:none removes it from the tab order and from the accessibility
   tree — it would stop being a checkbox in every sense except that it
   still held a value. */
.gdp-team .chal-input{
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; white-space: nowrap;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}

.gdp-team .chal-box{
  flex: 0 0 auto;
  width: 20px; height: 20px;
  border: 2px solid var(--sd-muted);
  border-radius: 6px;
  background: var(--sd-bg);
  position: relative;
  transition: background .12s, border-color .12s;
}
.gdp-team .chal-item:hover .chal-box{ border-color: var(--sd-text); }

/* Filled and ticked when on. The tick is a rotated border rather than a
   glyph, so it does not depend on a font having loaded. */
.gdp-team .chal-input:checked ~ .chal-box{
  background: var(--sd-gold); border-color: var(--sd-gold);
}
.gdp-team .chal-input:checked ~ .chal-box::after{
  content: ""; position: absolute;
  left: 5px; top: 1px; width: 4px; height: 9px;
  border: solid var(--sd-bg); border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg);
}

/* The input is out of sight, so the focus ring has to be drawn on the box
   or a keyboard user cannot see where they are. */
.gdp-team .chal-input:focus-visible ~ .chal-box{
  outline: 2px solid var(--sd-gold); outline-offset: 2px;
}

/* Always shown: filled, but plainly not yours to change. */
.gdp-team .chal-input[disabled] ~ .chal-box{
  background: var(--sd-muted); border-color: var(--sd-muted); opacity: .5;
}
.gdp-team .chal-item.is-locked .chal-item-l{ cursor: default; }

.gdp-team .chal-t{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The row states, so twelve of them can be read at a glance rather than
   one box at a time. */
.gdp-team .chal-input:not(:checked) ~ .chal-t{ color: var(--sd-muted); }
.gdp-team .chal-item{ background: rgba(173,194,224,.04); margin-bottom: 4px; }
.gdp-team .chal-item.is-off{ background: transparent; opacity: .62; }
.gdp-team .chal-item-l span{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gdp-team .chal-item input[disabled] + span{ color: var(--sd-muted); }
.gdp-team .chal-locked-note{
  flex: 0 0 auto; font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--sd-muted);
}

.gdp-team .chal-editor-foot{ display: flex; gap: 8px; margin-top: 18px; }
.gdp-team .chal-editor-foot .gdp-dlg-btn{ flex: 1 1 0; }

@media (max-width: 480px){
  .gdp-team .chal-editor{ padding: 12px; align-items: flex-end; }
  .gdp-team .chal-editor-box{ padding: 18px; max-height: calc(100vh - 24px); }
}

/* ---------------------------------------------------------------------
   Latest team activities

   The date was on a fixed width='70' and wrapped onto two lines, doubling
   the height of every row, while the game column took whatever was left
   for names that are mostly short. The proportions are the other way
   round now: the date gets what it needs, the game gives back what it
   does not.
   ------------------------------------------------------------------ */
.gdp-team .act-date{
  /* Sized to the widest this format produces — "1108 05:22PM" — so it
     never wraps. nowrap as well, because a date broken across two lines
     is the thing that made these rows tall. */
  width: 104px; white-space: nowrap;
  color: var(--sd-muted); font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.gdp-team .act-who{
  width: 96px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gdp-team .act-game{
  max-width: 0;          /* lets a table cell actually truncate */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gdp-team .act-res{
  width: 72px; text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.gdp-team .act-head td{ color: var(--sd-muted); }

/* How many times that game was played that day. Quiet, because the game
   name is the thing being read. */
.gdp-team .act-count{
  margin-left: 6px; font-size: 11px; color: var(--sd-muted);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 560px){
  /* The player column goes first: on a phone this list is mostly one
     person's own activity anyway, and the game name needs the room. */
  .gdp-team .act-who{ display: none; }
  .gdp-team .act-date{ width: 92px; font-size: 11px; }
  .gdp-team .act-res{ width: 62px; }
}

/* =====================================================================
   PAGE LAYOUT

   The start pages no longer use Bootstrap rows and columns. Every attempt
   to space them through that system fought three things at once:

     .row          margin 0 -15px, which a flex or grid parent does not
                   cancel the way a float parent does
     .col-*        padding 0 15px, applied at two nesting levels
     the theme's own .mobile-padding-content-s, .tm-s-20, .mb-1,
                   .nospace, .col-screen-m-* — defined in a stylesheet
                   this package does not contain, differing per column

   .gdp-page owns its layout instead: a grid, one gap, no negative
   margins, no inherited utilities. Nothing outside this file decides
   where these boxes sit.
   ================================================================== */

.gdp-page{
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin: 16px 0 0;
}
/* THE SAME GAP AT THE BOTTOM AS AT THE TOP.

   The last box ran into the footer. One of the two .gdp-team branches
   carried an inline padding-bottom:40px and the other carried nothing, so
   the gap was either wrong or absent depending on which branch rendered.

   Set here instead, matching the 16px the first grid takes from the
   sub-menu, so the page is evenly framed and both branches agree. */
.gdp-team .gdp-page:last-of-type{ margin-bottom: 16px; }
.gdp-team{ padding-bottom: 16px; }
/* Two grids in sequence — the boxes above and the assignments below live
   in separate PHP branches, so they cannot share one grid — and the
   margin-top above is deliberately the same value as the gap. That makes
   the join between two grids indistinguishable from a gap inside one:

     sub-menu -> box 1   16px  (margin-top of grid 1)
     box 1    -> box 2   16px  (gap inside grid 1)
     box 2    -> box 3   16px  (margin-top of grid 2)

   One number, three different structural situations. */
.gdp-page > .gdp-cell{ min-width: 0; }

/* A bar of controls rather than content columns: two cells side by side
   at every width, since "Play game" and "Select game" are short and
   stacking them wastes a row. */
.gdp-page--bar{ grid-template-columns: auto auto; justify-content: space-between; align-items: center; }

/* The leaderboard panel keeps two Bootstrap rows inside it. They are not
   page-level, so they do not shift the page, but they carry the same
   -15px margins — which inside a panel that already has padding pulls the
   table out to the panel's edges. Neutralised here rather than left as a
   trap for whoever edits this next. */
.gdp-team .golden-gradient > .row,
.gdp-team .js-leaderboard-wrapper,
.gdp-team .js-all-stats-wrapper{ margin-left: 0; margin-right: 0; }
.gdp-team .js-leaderboard-wrapper > [class*="col-"],
.gdp-team .js-all-stats-wrapper > [class*="col-"]{ padding-left: 0; padding-right: 0; }
.gdp-page--bar .gdp-cell--full{ grid-column: 1 / -1; }

@media (min-width: 768px){
  /* 7/5 on the start pages, matching the columns they replace.
     NOT on a bar: .gdp-page--bar sets its own columns above, and this
     rule is later in the file at equal specificity, so it was silently
     winning and giving the league's toolbar a 7/5 split. */
  .gdp-page:not(.gdp-page--bar){ grid-template-columns: 7fr 5fr; }
  .gdp-page > .gdp-cell--full,
  .gdp-page > .gdp-cell--main:only-child{ grid-column: 1 / -1; }
}

/* THE OUTER COLUMN'S PADDING, REMOVED.
   template-team.php wraps the page in .container > .row > .col-xs-12, so
   the content sat 15px inside a container that already had 15px. The
   container keeps its padding; the row and column inside it do not add
   more. */
.gdp-team > .container > .row,
.gdp-team .container > .row{ margin-left: 0; margin-right: 0; }
.gdp-team .container > .row > [class*="col-"]{ padding-left: 0; padding-right: 0; }

@media (max-width: 767px){
  /* Tighter on a phone, where the screen is worth using. */
  .gdp-team .container{ padding-left: 10px; padding-right: 10px; }
  .gdp-page{ gap: 12px; margin-top: 12px; }
  .gdp-team .teambox{ padding: 14px; }
  .gdp-team .teambox-heading{ padding-bottom: 10px; margin-bottom: 12px; }
}

/* ---------------------------------------------------------------------
   Active assignments

   A four-column grid rather than a table, so the columns line up down the
   whole list and each game can carry sub-rows for its players without a
   second table nested inside the first.
   ------------------------------------------------------------------ */
/* NO PADDING OF ITS OWN. .teambox already pads 18px, so this was adding a
   second inset and the assignments sat further in than the activity list
   beside them. The block fills its box like every other one. */
.gdp-team .assign-block{ padding: 0; }
.gdp-team .assign-none{ color: var(--sd-muted); font-size: 14px; margin: 0; }

/* THE MEMBERS LIST CARRIES NO INSET OF ITS OWN.

   The theme's own stylesheet sets `.members-list { padding: 0 0 0 15px }`,
   which this package does not contain and I cannot read. That 15px is
   what pushed this box out of line with the assignments box beside it.

   Zeroed here at 0-2-0, which beats the theme's 0-1-0, and stated OUTSIDE
   any media query — my first attempt zeroed it only under 767px, so the
   phone was correct and every desktop still had the 15px. The symptom was
   invisible on the device I was reasoning about.

   The shorthand is written in full rather than as padding-left, so a
   shorthand in the theme cannot reintroduce the other three sides. */
.gdp-team .members-list{ padding: 0; }

/* ONE CARD PER PERIOD.
   They used to run together in a single flow separated by a margin, so
   two periods' games read as one list. A recessed surface with its own
   header makes the boundary structural rather than something the reader
   has to infer from a date. */
.gdp-team .assign-period-box{
  background: rgba(173,194,224,.03);
  border: 1px solid var(--sd-line);
  border-radius: 12px;
  padding: 0 14px 6px;
  margin-bottom: 16px;
}
.gdp-team .assign-period-box:last-child{ margin-bottom: 0; }

.gdp-team .assign-period{
  font-family: "Oswald", sans-serif; font-size: 13px; font-weight: 500;
  letter-spacing: .06em; color: var(--sd-text);
  /* Full width of the card, so the date reads as its title rather than as
     a line floating above the first game. */
  margin: 0 -14px 0;
  padding: 11px 14px;
  background: var(--sd-surface-2);
  border-bottom: 1px solid var(--sd-line);
  border-radius: 11px 11px 0 0;
}

/* The last game in a card should not draw a rule against the card edge. */
.gdp-team .assign-period-box .assign-game:last-child,
.gdp-team .assign-period-box .assign-player:last-child{ border-bottom: 0; }

.gdp-team .assign-head,
.gdp-team .assign-game,
.gdp-team .assign-player{
  display: grid;
  grid-template-columns: minmax(0,1fr) 76px minmax(0,150px) 76px;
  align-items: center; gap: 10px;
}
.gdp-team .assign-head{
  font-family: "Oswald", sans-serif; font-size: 10px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--sd-muted);
  padding-bottom: 8px; border-bottom: 1px solid var(--sd-line);
}
.gdp-team .assign-c-qty,
.gdp-team .assign-c-done{ text-align: center; }

.gdp-team .assign-game{
  padding: 10px 0;
  border-bottom: 1px solid var(--sd-line-2);
}
.gdp-team .assign-game .assign-c-game{
  display: flex; align-items: center; gap: 10px; min-width: 0;
}
/* Small enough not to dominate a list, large enough to recognise. The
   artwork is part of the link, so the target is the picture and the name
   together rather than a small underlined word beside a picture. */
.gdp-team .assign-thumb{ flex: 0 0 auto; line-height: 0; }
.gdp-team .assign-thumb img{
  width: 40px; height: 40px; object-fit: cover; border-radius: 8px;
  display: block; border: 1px solid var(--sd-line);
}
.gdp-team .assign-thumb:hover img{ border-color: var(--sd-gold); }
.gdp-team .assign-name{
  font-family: "Oswald", sans-serif; font-size: 15px; font-weight: 500;
  color: var(--sd-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gdp-team .assign-name:hover{ color: var(--sd-gold); text-decoration: none; }

.gdp-team .assign-player{
  padding: 7px 0 7px 50px;   /* aligned under the game name, past the thumb */
  /* No left inset on a phone: 50px of a 340px row is a sixth of the width
     spent on indentation. */
  font-size: 14px; color: var(--sd-muted);
  border-bottom: 1px solid var(--sd-line-2);
}
.gdp-team .assign-player.is-me{ color: var(--sd-text); }

/* NOT RED AT ZERO. A routine assigned this morning is at zero for
   everybody, and red there says "you have failed" about something nobody
   has had a chance to do yet. Quiet until it is finished, then green. */
.gdp-team .assign-c-done.is-none{ color: var(--sd-muted); }
.gdp-team .assign-c-done.is-part{ color: var(--sd-text); }
.gdp-team .assign-c-done.is-done{ color: var(--sd-green); font-weight: 600; }

@media (max-width: 640px){
  .gdp-team .assign-block{ padding: 0; }
  /* The goal column goes first: it is the longest and the least scanned.
     It reappears under the game name instead. */
  .gdp-team .assign-head,
  .gdp-team .assign-game,
  .gdp-team .assign-player{ grid-template-columns: minmax(0,1fr) 54px 54px; }
  .gdp-team .assign-c-goal{ display: none; }
  .gdp-team .assign-player{ padding-left: 50px; }
  .gdp-team .assign-name{ font-size: 14px; }
}

/* ---------------------------------------------------------------------
   Game picker

   One grid, filtered. Categories narrow it rather than hide it, search
   narrows the same grid, and the two combine. Every game is rendered once
   and filtering toggles the hidden attribute, so nothing waits on a round
   trip while a coach is deciding.
   ------------------------------------------------------------------ */
/* Search and filters stay put while the grid moves under them. The fade
   below the chips stops tiles appearing to slice through the controls as
   they scroll past. */
.gdp-team .gp-head{
  position: sticky; top: 0; z-index: 3;
  background: var(--sd-surface);
  padding-bottom: 12px;
}
.gdp-team .gp-head::after{
  content: ""; position: absolute; left: 0; right: 0; bottom: -12px; height: 12px;
  background: linear-gradient(to bottom, var(--sd-surface), transparent);
  pointer-events: none;
}
/* A search field with the glass on it, so it reads as search rather than
   as a text input that happens to say "Search". */
.gdp-team .gp-search{
  width: 100%; padding: 11px 14px 11px 38px;
  background-repeat: no-repeat; background-position: 13px center; background-size: 15px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2393a1b5' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E");
  background: var(--sd-surface-2); border: 1px solid var(--sd-line-2);
  border-radius: 9px; color: var(--sd-text);
  font-family: "Hanken Grotesk", sans-serif; font-size: 14px;
}
.gdp-team .gp-search:focus{ outline: none; border-color: var(--sd-green); }

.gdp-team .gp-chips{ display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.gdp-team .gp-chip{
  padding: 6px 12px; border-radius: 99px;
  border: 1px solid var(--sd-line-2); background: transparent; color: var(--sd-muted);
  font-family: "Hanken Grotesk", sans-serif; font-size: 11px; font-weight: 600;
  letter-spacing: .04em; cursor: pointer; white-space: nowrap;
  transition: color .15s, border-color .15s, background .15s;
}
.gdp-team .gp-chip:hover{ color: var(--sd-text); }
.gdp-team .gp-chip.is-on{
  background: var(--sd-good-bg); border-color: var(--sd-good-border); color: var(--sd-green);
}

.gdp-team .gp-grid{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  /* No max-height here now. The modal caps its own height and its
     wrapper scrolls, so a second scrolling box inside it just made two
     scrollbars fight over the same gesture. */
  gap: 8px; padding: 2px;
}
/* THE NAME SITS ON THE ART, not in a bar under it.
   The bar added a fixed strip to every tile whether the name needed one
   line or two, so the grid was mostly chrome. Over a scrim the name costs
   nothing, the artwork gets the whole tile, and the row is shorter. */
.gdp-team .gp-tile{
  position: relative; cursor: pointer;
  border-radius: 10px; overflow: hidden;
  background: var(--sd-surface-2);
  aspect-ratio: 1 / 1;
  box-shadow: 0 0 0 1px var(--sd-line) inset;
  transition: box-shadow .14s, transform .14s;
}
.gdp-team .gp-tile:hover{
  box-shadow: 0 0 0 1px var(--sd-line-2) inset;
  transform: translateY(-2px);
}
.gdp-team .gp-art{
  display: block; width: 100%; height: 100%; object-fit: cover;
}
.gdp-team .gp-name{
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 18px 8px 7px;
  font-family: "Oswald", sans-serif; font-size: 11px; font-weight: 400;
  line-height: 1.15; color: #fff;
  text-shadow: 0 1px 6px rgba(0,0,0,.9);
  background: linear-gradient(to top, rgba(6,9,13,.92) 0%, rgba(6,9,13,.72) 45%, rgba(6,9,13,0) 100%);
}
.gdp-team .gp-tick,
.gdp-team .gp-have{ display: none; }

/* The coach's own favourites, marked on the tile as well as filterable.
   Top LEFT, because the selection tick and the "in preset" label both
   take the top right and a heart competing for that corner would be lost
   the moment a game was chosen. */
.gdp-team .gp-fav{
  position: absolute; top: 6px; left: 6px;
  font-size: 10px; color: var(--sd-red);
  background: rgba(9,10,12,.72); border-radius: 99px;
  width: 18px; height: 18px;
  display: flex; align-items: center; justify-content: center;
}
.gdp-team .gp-chip--fav.is-on{
  background: rgba(239,77,99,.12); border-color: rgba(239,77,99,.35); color: var(--sd-red);
}
.gdp-team .gp-chip--fav i{ font-size: 10px; margin-right: 3px; }

/* Selected: a ring plus a dark wash, so a chosen tile reads at a glance
   in a grid of bright artwork where a border alone gets lost. */
.gdp-team .gp-tile.is-on{
  box-shadow: 0 0 0 2px var(--sd-green) inset;
  transform: translateY(-2px);
}
.gdp-team .gp-tile.is-on .gp-art{ opacity: .55; }
.gdp-team .gp-tile.is-on .gp-tick{
  display: flex; align-items: center; justify-content: center;
  position: absolute; top: 7px; right: 7px; width: 22px; height: 22px;
  border-radius: 99px; background: var(--sd-green); color: #04231a;
  font-size: 12px; box-shadow: 0 2px 8px rgba(0,0,0,.5);
}

/* Already in the preset: shown, not hidden. Hiding it would leave a coach
   hunting for a game that is already there. */
.gdp-team .gp-tile.is-have{ opacity: .38; cursor: default; }
.gdp-team .gp-tile.is-have .gp-have{
  display: block; position: absolute; top: 6px; right: 6px;
  background: rgba(9,10,12,.85); color: var(--sd-muted);
  font-size: 9px; padding: 2px 6px; border-radius: 5px;
}
.gdp-team .gp-empty{ grid-column: 1 / -1; padding: 18px 2px; color: var(--sd-muted); font-size: 13px; }

/* The tray is the running record of the decision, so a coach can see what
   they have built without scrolling back up through the grid. */
/* The tray floats over the last row rather than sitting after it, with a
   fade above so the grid appears to run underneath. */
.gdp-team .gp-tray{
  position: sticky; bottom: 0; z-index: 3;
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--sd-line);
  background: var(--sd-surface);
}
.gdp-team .gp-tray::before{
  content: ""; position: absolute; left: 0; right: 0; top: -18px; height: 18px;
  background: linear-gradient(to top, var(--sd-surface), transparent);
  pointer-events: none;
}
.gdp-team .gp-tray-items{ display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.gdp-team .gp-pick{
  display: inline-flex; align-items: center; gap: 2px;
  border: 1px solid var(--sd-good-border); background: var(--sd-good-bg);
  border-radius: 8px; padding: 3px 4px 3px 9px;
  font-size: 11px; color: var(--sd-text);
}
.gdp-team .gp-pick-n{ margin-right: 4px; }
.gdp-team .gp-qty{ min-width: 16px; text-align: center; font-family: "Oswald", sans-serif; }
.gdp-team .gp-step{
  border: 0; background: transparent; color: var(--sd-muted);
  font-size: 13px; line-height: 1; padding: 3px 5px; cursor: pointer;
}
.gdp-team .gp-step:hover{ color: var(--sd-text); background: transparent; border: 0; }

.gdp-team .gp-tray-foot{ display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.gdp-team .gp-tray-count{ font-size: 12px; color: var(--sd-muted); }
.gdp-team .gp-tray-add{
  padding: 10px 18px; border-radius: 9px; border: 1px solid var(--sd-gold);
  background: var(--sd-gold); color: #1a1000;
  font-family: "Oswald", sans-serif; font-size: 13px; font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; cursor: pointer;
}
.gdp-team .gp-tray-add:hover{ background: var(--sd-gold-hi); border-color: var(--sd-gold-hi); color: #1a1000; }
.gdp-team .gp-tray-add[disabled]{
  opacity: .4; cursor: not-allowed; background: transparent;
  border-color: var(--sd-line); color: var(--sd-muted);
}

@media (max-width: 560px){
  .gdp-team .gp-grid{ grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); }
  .gdp-team .gp-tray-foot{ flex-direction: column; align-items: stretch; }
  .gdp-team .gp-tray-add{ width: 100%; }
  .gdp-team .gp-tray-count{ text-align: center; }
}

/* ---------------------------------------------------------------------
   Dialogs

   Replaces prompt() and confirm(). Declares its own tokens rather than
   inheriting: the markup is included at the end of the template and may
   sit outside .gdp-team, where a var(--sd-*) would resolve to nothing and
   the box would render as transparent text on a transparent background.
   ------------------------------------------------------------------ */
.gdp-dlg{
  --sd-surface:#181f29; --sd-surface-2:#212a36;
  --sd-line:rgba(173,194,224,.10); --sd-line-2:rgba(173,194,224,.18);
  --sd-text:#e9eef5; --sd-muted:#93a1b5;
  --sd-green:#27d2a3; --sd-gold:#ffa200; --sd-gold-hi:#ffc04d; --sd-red:#ef4d63;
  position: fixed; inset: 0; z-index: 11000;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  font-family: "Hanken Grotesk", system-ui, sans-serif;
}
.gdp-dlg[hidden]{ display: none; }
.gdp-dlg-bd{ position: absolute; inset: 0; background: rgba(6,9,13,.72); }
.gdp-dlg-box{
  position: relative; z-index: 1;
  width: 100%; max-width: 420px;
  background: var(--sd-surface);
  border: 1px solid var(--sd-line-2);
  border-radius: 16px;
  padding: 22px;
  box-shadow: 0 20px 50px rgba(0,0,0,.55);
  color: var(--sd-text);
}
.gdp-dlg-title{
  font-family: "Oswald", sans-serif; font-size: 20px; font-weight: 500;
  margin: 0; color: var(--sd-text);
}
.gdp-dlg-lead{ margin: 8px 0 0; font-size: 13px; line-height: 1.5; color: var(--sd-muted); }
.gdp-dlg-label{
  display: block; margin: 16px 0 6px;
  font-family: "Oswald", sans-serif; font-size: 11px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--sd-muted);
}
.gdp-dlg-input{
  width: 100%; padding: 11px 13px;
  background: var(--sd-surface-2); border: 1px solid var(--sd-line-2);
  border-radius: 9px; color: var(--sd-text);
  font-family: "Hanken Grotesk", sans-serif; font-size: 15px;
}
.gdp-dlg-input:focus{ outline: none; border-color: var(--sd-gold); }
.gdp-dlg-err{ margin-top: 7px; font-size: 12px; color: var(--sd-red); }

.gdp-dlg-foot{ display: flex; gap: 8px; margin-top: 20px; }
.gdp-dlg-btn{
  flex: 1 1 0; padding: 11px 14px; border-radius: 9px;
  border: 1px solid var(--sd-line-2); background: transparent; color: var(--sd-text);
  font-family: "Oswald", sans-serif; font-size: 13px; font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; cursor: pointer;
}
.gdp-dlg-btn:hover{ border-color: var(--sd-gold); color: var(--sd-gold); }
/* The action is the filled one; the way out stays quiet. */
.gdp-dlg-btn--go{
  flex: 1.4 1 0;
  background: var(--sd-gold); border-color: var(--sd-gold); color: #1a1000;
}
.gdp-dlg-btn--go:hover{ background: var(--sd-gold-hi); border-color: var(--sd-gold-hi); color: #1a1000; }
/* A destructive action is outlined, not filled. Nobody should confirm a
   deletion by reaching for the loudest button on the screen. */
.gdp-dlg-btn--danger{
  background: transparent; border-color: rgba(239,77,99,.55); color: var(--sd-red);
}
.gdp-dlg-btn--danger:hover{
  background: rgba(239,77,99,.12); border-color: var(--sd-red); color: #f4b3bd;
}

@media (max-width: 480px){
  .gdp-dlg{ padding: 14px; align-items: flex-end; }
  .gdp-dlg-box{ padding: 18px; border-radius: 16px; }
  .gdp-dlg-foot{ flex-direction: column-reverse; }
  .gdp-dlg-btn{ flex: none; width: 100%; }
}

/* ---------------------------------------------------------------------
   Player snapshot popup

   Opened from a member row. Facts only: colour carries scale, never
   judgement. A busier day is a brighter square and that is all it means.
   ------------------------------------------------------------------ */

/* The overlay no longer places the panel. It was a flex container with
   align-items:flex-start, which pinned the panel to the top of the
   viewport whichever row had been clicked. The panel now positions itself
   against its trigger; see positionSnap() in team-player-snapshot.php.

   Still scrollable, for the case where the panel is taller than the
   viewport and has to start at the top. */
.snap-overlay{
  position: fixed; inset: 0; z-index: 10500;
  background: rgba(6, 9, 13, .78);
  overflow-y: auto;
  font-family: "Hanken Grotesk", system-ui, sans-serif;
}
.snap-panel{
  --sd-bg:#0e131a; --sd-surface:#181f29; --sd-surface-2:#212a36;
  --sd-line:rgba(173,194,224,.10); --sd-line-2:rgba(173,194,224,.18);
  --sd-text:#e9eef5; --sd-muted:#93a1b5;
  --sd-green:#27d2a3; --sd-gold:#ffa200; --sd-gold-hi:#ffc04d; --sd-red:#ef4d63;
  --sd-good-bg:rgba(39,210,163,.12); --sd-good-border:rgba(39,210,163,.30);
  position: absolute;
  left: 50%; transform: translateX(-50%);
  top: 40px;                 /* replaced on open by positionSnap() */
  width: calc(100% - 32px); max-width: 620px;
  background: var(--sd-surface);
  border: 1px solid var(--sd-line-2);
  border-radius: 16px;
  padding: 20px;
  color: var(--sd-text);
  box-shadow: 0 18px 48px rgba(0,0,0,.55);

  /* A CEILING, so the panel can never be taller than the screen.
     There was none, which is how it grew past the display: every section
     added its height and nothing stopped it. The content is shorter now,
     but a player with a long list of games should not be able to bring
     the problem back. */
  max-height: calc(100vh - 80px);
  overflow-y: auto;
}
.snap-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-bottom:16px; }
.snap-eyebrow{ color: var(--sd-muted); }
.snap-name{ font-family:"Oswald",sans-serif; font-size:22px; font-weight:500; }
.snap-loading{ color: var(--sd-muted); padding: 24px 0; }
.snap-none{ color: var(--sd-muted); font-size:13px; }

.snap-kpis{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; margin-bottom:20px; }
/* The way out of this panel, at the top where it can be seen. */
/* The tiles were already tight; I briefly added a second, looser pair of
   rules above these and they simply lost to them. Removed rather than
   left as two declarations of the same thing. */
.snap-kpi{ background: var(--sd-surface-2); border-radius:10px; padding:10px 12px; }
.snap-kpi-v{ font-family:"Oswald",sans-serif; font-size:22px; font-weight:500; line-height:1.1; }
.snap-kpi-l{ font-family:"Oswald",sans-serif; font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--sd-muted); margin-top:2px; }
.snap-kpi-d{ font-size:11px; color:var(--sd-muted); margin-top:3px; min-height:14px; }

.snap-section{ margin-bottom:20px; }
.snap-section .app-header-s{ display:block; margin-bottom:10px; }

.snap-cols{ display:flex; gap:4px; }
/* flex:1 1 0 made every week stretch to fill the panel, which is what
   made the squares large. A week is as wide as its days. */
.snap-col{ display:flex; flex-direction:column; gap:4px; }
/* SIZED, NOT STRETCHED.

   width:100% with aspect-ratio meant each square grew to fill its column,
   so on a wide panel thirteen weeks of days filled half the height. A day
   is a fixed 11px now; the grid takes the width it needs and no more.

   No background here: .snap-l0 to .snap-l4 below own the colour, and a
   background on this rule would override all five and turn the whole
   grid grey. */
.snap-sq{
  /* 15px rather than 11. At 11 a day was legible but not readable — you
     could see there was a pattern without being able to see what it was.
     The scrolling games list below pays for the extra height. */
  display:block; width:15px; height:15px; border-radius:3px;
}
/* Five steps of the same hue. One ramp, so the eye reads "more" or
   "less" and nothing else. */
.snap-l0{ background:#212a36; }
.snap-l1{ background:rgba(39,210,163,.28); }
.snap-l2{ background:rgba(39,210,163,.48); }
.snap-l3{ background:rgba(39,210,163,.70); }
.snap-l4{ background:rgba(39,210,163,.95); }
.snap-future{ opacity:.25; }

.snap-legend{ display:flex; align-items:center; gap:5px; margin-top:8px; font-size:11px; color:var(--sd-muted); }
.snap-legend .snap-sq{ width:11px; height:11px; aspect-ratio:auto; }
.snap-legend-note{ margin-left:auto; }

/* MOST PLAYED — A LIST, NOT A GALLERY.

   This was a three-column grid with `width:100%` on the artwork, so on a
   wide screen each cover was over 200px tall and six of them pushed the
   panel past the height of the display. The cover is there to make the
   game recognisable, which a thumbnail does as well as a poster.

   One per row now, artwork at a fixed 44px, so six games cost about 300px
   instead of 900. */
/* TWO PER ROW, TWO ROWS DEEP, then it scrolls.

   A player with fifteen games would otherwise make this panel as tall as
   their history. Four games is enough to see what somebody has been
   working on; the rest is a short scroll rather than a taller page. */
.snap-games{ display:grid; grid-template-columns:repeat(2,1fr); gap:2px 18px; }
.snap-games-scroll{
  max-height:124px;      /* two rows of 56px, plus the gap */
  overflow-y:auto;
  /* Room for the scrollbar so it does not sit on top of the figures. */
  padding-right:6px;
}

/* A thin bar rather than the browser's default, which on a dark panel is
   a bright slab. */
.snap-games-scroll{ scrollbar-width:thin; scrollbar-color:var(--sd-line-2) transparent; }
.snap-games-scroll::-webkit-scrollbar{ width:6px; }
.snap-games-scroll::-webkit-scrollbar-track{ background:transparent; }
.snap-games-scroll::-webkit-scrollbar-thumb{
  background:var(--sd-line-2); border-radius:99px;
}
.snap-games-scroll::-webkit-scrollbar-thumb:hover{ background:var(--sd-muted); }
.snap-game{
  display:grid;
  grid-template-columns:44px 1fr auto;
  align-items:center; gap:11px;
  padding:6px 0;
}
.snap-game img{
  width:44px; height:44px; object-fit:cover;
  border-radius:8px; display:block;
  border:1px solid var(--sd-line);
}
.snap-game-n{
  font-family:"Oswald",sans-serif; font-size:14px; color:var(--sd-text);
  min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* The figures sit at the end of the row rather than under the name, so
   the eye runs down one column of numbers. */
.snap-game-s{
  font-size:12px; color:var(--sd-muted); white-space:nowrap;
  font-variant-numeric:tabular-nums; text-align:right;
}

/* The row's actions, labelled. Hidden on desktop, where the five buttons
   are still on the row itself and repeating them here would be two ways
   to do the same thing on one screen. */
.snap-actions{ display:none; gap:6px; flex-wrap:wrap; margin-bottom:14px; }
.snap-act{
  display:inline-flex; align-items:center;
  border:1px solid var(--sd-line-2); border-radius:8px;
  padding:8px 12px; font-size:12px; color:var(--sd-text);
  cursor:pointer; text-decoration:none;
}
.snap-act:hover,.snap-act:focus{ border-color:var(--sd-good-border); color:var(--sd-green); text-decoration:none; }
@media (max-width:767px){ .snap-actions{ display:flex; } }

/* It sat at the foot of the panel as a full-width button. It is now
   under the name, where it can be seen without scrolling, so it is an
   inline control rather than a bar. */
.snap-pc{ display:inline-block; width:auto; margin-bottom:14px; }
@media (max-width:560px){
  /* Full width on a phone, where a lone inline button looks stranded. */
  .snap-pc{ display:block; width:100%; text-align:center; }
}

@media (max-width: 560px){
  /* 247px of grid fits a 320px phone by 13px, which is not a margin worth
     relying on. 12px squares give 195px and the same 13 weeks. */
  .snap-sq{ width:12px; height:12px; }
  .snap-cols, .snap-col{ gap:3px; }
  /* One game per row, still scrolling at two rows' worth. */
  .snap-games{ grid-template-columns:1fr; }
  .snap-games-scroll{ max-height:116px; }

  .snap-panel{ width: calc(100% - 20px); }
  .snap-kpis{ grid-template-columns:repeat(2,1fr); }
  /* Already one per row; nothing to change on a phone. */
  .snap-legend-note{ display:none; }
}

/* ---------------------------------------------------------------------
   Mobile

   Players are overwhelmingly on phones and coaches on desktop, so the
   phone layout is the one that has to be right rather than merely
   survivable.
   ------------------------------------------------------------------ */

@media (max-width: 767px){
  .gdp-team .teambox{ padding: 14px; border-radius: 12px; }
  .gdp-team .period-head{ padding: 12px 14px; }
  .gdp-team .player-row{ padding: 12px 14px; }
  .gdp-team .period-dates{ font-size: 18px; }
  .gdp-team .app-header-l{ font-size: 19px; }
  .gdp-team .teamHeader .app-header-l{ font-size: 21px; }
  .gdp-team .team-submenu a{ padding: 12px 10px; font-size: 15px; }
}

@media (prefers-reduced-motion: reduce){
  .gdp-team *{ transition: none !important; animation: none !important; }
}
