/* ===========================================================================
   dashboard.css — the staff home.
   Composition only. Every colour, size and radius comes from design-system.css.

   THREE RULES THIS FILE IS BUILT AGAINST, all from DESIGN.md:

   The Tenant Accent Rule — the handoff spec draws this screen in literal reds
   (#e84545, rgba(232,69,69,.34), #fdeaec, #c93636). None of them appear here.
   Every accent surface is mixed from --accent / --accent-btn / --brand-navy, so
   the hero, the chips and the form tiles are correct for a club whose colour is
   navy, green or gold. The first club is a customer, not the specification.

   The No-Half-Step Rule — the spec asks for 32/30/22/16/12.5/11.5/10.5/9.5px.
   The ramp is 46/34/30/26/21/17/15/13/11 and nothing else. Where the spec
   wanted a size between two steps, this uses a step and changes weight or
   colour instead.

   The Minmax-Zero Rule — every track below is minmax(0, 1fr). A club name or a
   Portuguese surname that cannot break will otherwise widen its own track and
   push the page sideways on a phone.
   =========================================================================== */

/* ---------- the greeting row ---------------------------------------------- */
.dash-greet {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 20px;
}
.dash-greet .when {
  font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: var(--text-tertiary); margin-bottom: 4px;
}
.dash-greet-meta { display: flex; align-items: center; gap: 8px; }
.season-pill {
  height: 34px; display: inline-flex; align-items: center; padding: 0 14px;
  border-radius: var(--r-full); border: 1px solid var(--border-default);
  background: var(--bg-card); color: var(--text-secondary);
  font-size: var(--fs-label); font-weight: var(--w-title);
  font-variant-numeric: tabular-nums lining-nums;
}

/* ---------- the fixture hero ---------------------------------------------- */
/* The club's own two colours, not a fixed charcoal: the base is the secondary
   colour deepened to ink, and the warm corner is the accent. A blue club gets a
   blue corner, which is the whole point. */
.fixture-hero {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg); padding: 24px 26px;
  color: #fff;
  background:
    radial-gradient(120% 130% at 100% 0%,
      color-mix(in srgb, var(--accent) 38%, transparent), transparent 62%),
    linear-gradient(150deg,
      var(--brand-navy) 0%,
      var(--ink-shade) 54%,
      color-mix(in srgb, var(--accent) 24%, var(--ink-shade)) 100%);
  box-shadow: var(--shadow-md);
}
.fixture-hero .eyebrow {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 16px;
}
.fixture-hero .eyebrow .lbl,
.fixture-hero .when-pill {
  font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide); text-transform: uppercase;
}
/* Secondary text on a coloured surface is tinted from the surface's own
   foreground, never grey — grey on this ground reads as disabled. */
.fixture-hero .eyebrow .lbl { color: rgba(255, 255, 255, 0.62); }
.fixture-hero .when-pill {
  flex: none; padding: 5px 11px; border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.14); color: #fff;
}
.fixture-hero-body {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center; gap: 16px;
}
.fixture-hero-body .crest {
  width: 56px; height: 56px; border-radius: var(--r-md); flex: none;
  background: rgba(255, 255, 255, 0.12);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-size: var(--fs-title);
  font-weight: var(--w-display); color: #fff; overflow: hidden;
}
.fixture-hero-body .crest img { width: 100%; height: 100%; object-fit: cover; }
.fixture-hero .who {
  font-family: var(--font-display); font-size: var(--fs-page);
  font-weight: var(--w-display); letter-spacing: var(--track-tighter);
  line-height: var(--lh-tight);
  overflow-wrap: anywhere;
}
.fixture-hero .sub,
.fixture-hero .venue { font-size: var(--fs-label); color: rgba(255, 255, 255, 0.66); }
.fixture-hero .kickoff {
  text-align: right; flex: none;
  font-family: var(--font-display); font-size: var(--fs-page);
  font-weight: var(--w-display); letter-spacing: var(--track-tighter);
  font-variant-numeric: tabular-nums lining-nums;
}

/* Squad readiness. The design's version counts availability replies; RUCK does
   not collect those, so this counts the thing it does know — how much of the
   squad is picked, and whether it has been released. */
.squad-meter { margin-top: 18px; }
.squad-meter .caption {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 7px;
  font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}
.squad-meter .caption .state { color: #fff; }
.squad-meter .rail {
  height: 8px; border-radius: var(--r-full); overflow: hidden;
  background: rgba(255, 255, 255, 0.14);
}
/* Clipped, not sized: a width transition on a rail that re-splits on every
   realtime update runs a layout pass per frame. */
.squad-meter .fill {
  height: 100%; width: 100%; border-radius: inherit;
  background: var(--warning);
  clip-path: inset(0 calc(100% - var(--pct, 0%)) 0 0);
  transition: clip-path var(--t-slow) var(--ease), background var(--t-med) var(--ease);
}
/* Three states, because a bar that is green at 13% is worse than no bar.
   Filling is the default and is amber: work in progress, nothing wrong.
   Short is a squad that will not field itself with kickoff inside three days.
   Ready is a full 23, or a squad already released. The caption says the same
   thing in words — "faltam 20 jogadores" — so this never rests on colour. */
.squad-meter.is-short .fill { background: var(--danger); }
.squad-meter.is-ready .fill { background: var(--success); }

.hero-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.hero-actions .btn { min-height: 44px; }
/* On the hero these sit on the club's own ground, so they cannot use the
   page-level button colours. */
.hero-actions .btn-hero {
  background: rgba(255, 255, 255, 0.14); color: #fff; border: 0;
}
.hero-actions .btn-hero:hover { background: rgba(255, 255, 255, 0.24); }

/* ---------- the week rail -------------------------------------------------- */
.week-rail .row {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
  padding: 9px 8px; border-radius: var(--r-sm);
  color: inherit; text-decoration: none;
  transition: background var(--t-fast) var(--ease);
}
.week-rail .row:hover { background: var(--bg-sunken); }
.week-rail .date-tile {
  width: 44px; height: 44px; border-radius: var(--r-sm);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--tone) 12%, transparent);
  /* The lettering used to be var(--tone) at full strength on a 12% tint of
     that same hue — a training tile measured 2.92:1 and a match tile 3.32:1,
     both well under AA, at 11px, on the screen this system says it optimised
     for a coach in direct sunlight. The eight event hues are a CATEGORICAL
     scale: they exist to be told apart at four pixels across, not to be read
     as text. So the tint keeps carrying the category and the ink goes back to
     the one colour that is legible on every one of the eight. */
  color: var(--text-primary);
}
.week-rail .date-tile .dow {
  font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide); text-transform: uppercase; line-height: 1;
}
.week-rail .date-tile .dom {
  font-family: var(--font-display); font-size: var(--fs-title);
  font-weight: var(--w-display); line-height: 1.1;
  font-variant-numeric: tabular-nums lining-nums;
}
.week-rail .what { min-width: 0; }
.week-rail .what .t {
  font-size: var(--fs-body); font-weight: var(--w-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.week-rail .what .s { font-size: var(--fs-label); color: var(--text-tertiary); }
.week-rail .kind {
  flex: none; font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide); text-transform: uppercase;
  padding: 4px 9px; border-radius: var(--r-full);
  background: color-mix(in srgb, var(--tone) 12%, transparent); color: var(--text-primary);
}

/* ---------- club figures --------------------------------------------------- */
.kpi-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.kpi-card {
  display: block; color: inherit; text-decoration: none;
  background: var(--bg-card); border: 1px solid var(--border-subtle);
  border-radius: var(--r-md); padding: 16px;
  transition: box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.kpi-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.kpi-card .head {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
}
/* Two lines, not an ellipsis. At 2-up on a 390px phone the label and its
   delta chip share one line, and nowrap turned "Quotas por cobrar" into
   "QUOTAS …" — a label that has stopped naming anything. */
.kpi-card .lbl {
  font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: var(--text-tertiary); margin-bottom: 8px;
}
/* Rendered only when a real previous-period value exists. Three of the four
   figures have one; `injured` has no history anywhere in the schema, so its
   card carries no chip rather than an invented one. */
.kpi-card .delta {
  flex: none; font-size: var(--fs-micro); font-weight: var(--w-title);
  padding: 3px 7px; border-radius: var(--r-full);
  font-variant-numeric: tabular-nums lining-nums;
  /* --tone-bg, not a 14% mix of --tone. The -text half of every semantic pair
     is solved to read on the matching -bg; mixing the foreground into the card
     to invent a ground produced 4.25:1 and 4.28:1 — near misses that the
     solved token clears at 4.6:1 in both themes. */
  background: var(--tone-bg); color: var(--tone);
}
.kpi-card .val {
  font-family: var(--font-display); font-size: var(--fs-figure);
  font-weight: var(--w-display); letter-spacing: var(--track-tighter);
  line-height: var(--lh-tight);
  font-variant-numeric: tabular-nums lining-nums;
  overflow-wrap: anywhere;
}
.kpi-card .sub { font-size: var(--fs-label); color: var(--text-tertiary); margin-top: 3px; }

/* A figure that is not merely true but WRONG — money owed, players out.
   These used to be restated as alert rows below the row, the same number in
   the same colour six inches apart; the alarm belongs on the figure the
   reader is already looking at. A tinted border and a tinted value, no
   coloured left-bar: the border is the structure this system already uses. */
.kpi-card.needs-danger { border-color: color-mix(in srgb, var(--danger) 38%, var(--border-subtle)); }
.kpi-card.needs-danger .val { color: var(--danger-text); }
.kpi-card.needs-warning { border-color: color-mix(in srgb, var(--warning) 42%, var(--border-subtle)); }
.kpi-card.needs-warning .val { color: var(--warning-text); }

/* The euro sign was breaking onto its own line at 320px — `overflow-wrap:
   anywhere` on a figure whose whole job is to be read at a glance. A money
   total is one token; it may shrink, but it may not come apart. */
.kpi-card .val { overflow-wrap: normal; word-break: keep-all; }
@media (max-width: 380px) {
  .kpi-card { padding: 14px 12px; }
  .kpi-card .val { font-size: var(--fs-stat); }
}

/* ---------- squad health ---------------------------------------------------
   The staff home's figures used to be four identical bordered tiles — the
   exact shape of every B2B dashboard, carrying no rugby in it whatsoever, and
   occupying the second-largest block on a screen a coach opens a hundred times
   a season. This is the same data asking a selection question instead: how
   many can I pick from, and who is out. The people are named, because a coach
   reading "4" wants to know which four. */
.squad-health {
  display: block; color: inherit; text-decoration: none;
  background: var(--bg-card); border: 1px solid var(--border-subtle);
  border-radius: var(--r-md); padding: 18px; margin-bottom: 12px;
  transition: box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.squad-health:hover { box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.sh-main { display: flex; align-items: center; gap: 16px; }
.sh-figure { display: flex; align-items: baseline; gap: 8px; flex: none; }
.sh-n {
  font-family: var(--font-display); font-size: var(--fs-match);
  font-weight: var(--w-display); letter-spacing: var(--track-tighter);
  line-height: 1; font-variant-numeric: tabular-nums lining-nums;
  color: var(--text-primary);
}
.sh-delta {
  font-size: var(--fs-micro); font-weight: var(--w-title);
  padding: 3px 7px; border-radius: var(--r-full);
  font-variant-numeric: tabular-nums lining-nums;
  /* The solved ground, not a mix of the foreground — same rule as .delta. */
  background: var(--success-bg); color: var(--success-text);
}
.sh-say { min-width: 0; }
.sh-lbl {
  display: block; font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide); text-transform: uppercase; color: var(--text-tertiary);
}
.sh-sub { display: block; font-size: var(--fs-label); color: var(--text-secondary); margin-top: 2px; }

.sh-out {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border-subtle);
}
/* On a wide card the two facts share one line instead of stacking.
   .sh-figure is flex:none and .sh-say is the only thing that grows, so the
   content hugged the left and roughly two thirds of a 1150px card was empty —
   the same "the eye reads that gap as missing content" defect the badge shelf
   was rebuilt for. Who is out belongs beside how many are available; it is the
   second half of the same sentence, not a footnote to it. Below 720px it
   stacks exactly as before, where the width genuinely is not there. */
@media (min-width: 720px) {
  .squad-health { display: flex; align-items: center; gap: 24px; }
  .sh-main { flex: 1 1 auto; min-width: 0; }
  .sh-out {
    flex: none; margin-top: 0; padding-top: 0; padding-left: 24px;
    border-top: 0; border-left: 1px solid var(--border-subtle);
    align-self: stretch;
  }
}
.sh-out-n {
  font-size: var(--fs-label); font-weight: 650; color: var(--warning-text);
  font-variant-numeric: tabular-nums lining-nums;
}
.sh-out.is-clear .sh-out-n { color: var(--success-text); }
.sh-faces { display: flex; align-items: center; }   /* overlap comes from the margin below */
.sh-face {
  margin-right: -6px; border: 2px solid var(--bg-card);
  background: var(--warning-bg); color: var(--warning-text); font-weight: 700;
}
.sh-more {
  margin-left: 12px; font-size: var(--fs-label); color: var(--text-tertiary);
  font-variant-numeric: tabular-nums lining-nums;
}
/* Two figures, not four: attendance and money are the club's business, and
   they belong beside the squad rather than competing with it. */
.kpi-row-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* A coach is shown no money, so the pair below the squad block becomes a
   single figure. .kpi-row is a four-column grid, so dropping the modifier
   alone left the survivor a quarter wide with three columns of nothing beside
   it. One card takes the whole row.
   Written as two classes deliberately: the responsive rules further down
   re-state .kpi-row at 980px and 720px, and a single-class modifier declared
   above them loses to every one of those. This held on a desktop and broke on
   a laptop, which is exactly the width a coach opens the app on. */
.kpi-row.kpi-row-1 { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 420px) {
  .squad-health { padding: 14px 12px; }
  .sh-main { gap: 12px; }
}

/* ---------- team form ------------------------------------------------------ */
.form-guide { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.form-guide .g { text-align: center; min-width: 0; }
.form-guide .mark {
  height: 38px; border-radius: var(--r-sm);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-size: var(--fs-title);
  font-weight: var(--w-display);
  background: var(--tone-bg); color: var(--tone);
}
.form-guide .score {
  font-size: var(--fs-label); color: var(--text-secondary); margin-top: 5px;
  font-variant-numeric: tabular-nums lining-nums;
}
.form-guide .opp {
  font-size: var(--fs-micro); color: var(--text-tertiary);
  letter-spacing: normal; text-transform: none; font-weight: var(--w-body);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.form-totals {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border-subtle);
}
.form-totals .n {
  font-family: var(--font-display); font-size: var(--fs-stat);
  font-weight: var(--w-display); letter-spacing: var(--track-tight);
  font-variant-numeric: tabular-nums lining-nums;
}
.form-totals .c {
  font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: var(--text-tertiary); margin-top: 2px;
}

/* ---------- team cards ----------------------------------------------------- */
.team-tile {
  display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 12px;
  align-items: center;
  background: var(--bg-card); border: 1px solid var(--border-subtle);
  border-radius: var(--r-md); padding: 16px;
  color: inherit; text-decoration: none;
  transition: box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.team-tile:hover { box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.team-tile .name {
  font-size: var(--fs-body); font-weight: var(--w-display);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.team-tile .cat { font-size: var(--fs-label); color: var(--text-tertiary); }
.team-tile .foot {
  grid-column: 1 / -1; display: flex; align-items: center;
  justify-content: space-between; gap: 8px;
  margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--border-subtle);
  font-size: var(--fs-label); color: var(--text-secondary);
}
.team-tile .form-pill {
  flex: none; font-size: var(--fs-micro); font-weight: var(--w-title);
  letter-spacing: var(--track-wide);
  padding: 3px 9px; border-radius: var(--r-full);
  background: var(--bg-sunken); color: var(--text-secondary);
  font-variant-numeric: tabular-nums lining-nums;
}

/* ---------- responsive ------------------------------------------------------ */
@media (max-width: 980px) {
  .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .fixture-hero { padding: 18px; border-radius: var(--r-md); }
  .fixture-hero-body { grid-template-columns: 44px minmax(0, 1fr); }
  .fixture-hero-body .crest { width: 44px; height: 44px; }
  .fixture-hero .who { font-size: var(--fs-stat); }
  /* The kick-off drops under the fixture rather than fighting it for width. */
  .fixture-hero .kickoff {
    grid-column: 2; text-align: left; font-size: var(--fs-title);
  }
  .hero-actions .btn { width: 100%; }
  .form-guide { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 4px; }
  .form-guide .mark { height: 34px; font-size: var(--fs-body); }
  /* This was `display: none`, which is content LOSS rather than a layout
     adaptation: a desktop reader at 200% zoom crosses this breakpoint, so the
     act of zooming in to read deleted the five opponent names (WCAG 1.4.10).
     The names stay; they simply get less room. */
  .form-guide .opp {
    font-size: var(--fs-micro); max-width: 7ch;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
}

/* The hero pair: the fixture console takes the room, the week rail is a fixed
   companion. Both tracks are minmax(0, …) so a long opponent name or venue
   cannot widen the grid instead of wrapping inside it. */
.grid-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: 16px;
  align-items: start;
}
@media (max-width: 980px) {
  .grid-hero { grid-template-columns: minmax(0, 1fr); }
}

/* The Resumo page's season heading, and the count a filter chip carries. Both
   live here rather than in a <style> block inside a template string, which is
   where this page's one-off rules used to accumulate. */
.season-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.chip .chip-n {
  font-weight: 800; font-variant-numeric: tabular-nums lining-nums;
  opacity: 0.75; margin-left: 2px;
}

/* maintainAspectRatio is off so the chart fills a frame the layout controls
   rather than one Chart.js derives from the canvas width — an eleven-column
   season otherwise grew absurdly tall on a wide screen. */
.chart-frame { position: relative; height: 300px; }
@media (max-width: 720px) { .chart-frame { height: 260px; } }
