/* Injuries (ADR-0172): the floor plan and body figure (pick, single point, heat map), the
 * Injuries page's tiles, bars and list rows, and the injury detail view.
 * The list row is shared by the page, the account's Injuries tab and Staff
 * Notes' call-backs, so it is styled once here, unscoped. */

/* ============================================================================
 * Floor plan
 * ========================================================================== */

.injury-plan {
  position: relative;
  width: 100%;
  /* Its height comes from aspect-ratio; overflow:hidden would otherwise let a
     flex column shrink it to nothing. */
  flex-shrink: 0;
  /* The plan is a black line drawing on white; it keeps its paper in dark mode. */
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  user-select: none;
}

.injury-plan-frame { display: contents; }   /* a phone turns the plan inside it (mobile.css); the desk lays out the plan alone */

.injury-plan-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
}

.injury-heat-layer,
.injury-plan-points {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.injury-heat-layer {
  pointer-events: none;
  mix-blend-mode: multiply;
}

.injury-plan-pick {
  cursor: crosshair;
}

.injury-plan-pick:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* A marker on the map: a filled dot, coloured by severity, ringed in white so
   it reads over any line of the drawing. */
.injury-dot {
  position: absolute;
  width: 14px;
  height: 14px;
  padding: 0;
  border: 2px solid #fff;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: var(--color-text-muted);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
}

.injury-dot.moderate { background: var(--color-paused); }
.injury-dot.serious { background: var(--color-expired); }

button.injury-dot {
  cursor: pointer;
}

button.injury-dot:hover,
button.injury-dot:focus-visible {
  width: 18px;
  height: 18px;
  outline: none;
  box-shadow: 0 0 0 2px var(--color-accent);
}

.injury-plan-pick .injury-dot {
  width: 18px;
  height: 18px;
}

/* The body figure (ADR-0172): front and back, drawn from the same shapes a tap
   is tested against. Like the plan it is a drawing on paper, so it keeps its
   own light greys in dark mode; every part's outline shows, so the parts a tap
   can land on read on the drawing. */
.injury-map-body {
  --body-fill: #eceef1;
  --body-line: #8a929c;
  --body-label: #5b636d;
  --body-count: #1f2328;
  max-width: 360px;
}

.injury-body-shapes {
  fill: var(--body-fill);
  stroke: var(--body-line);
  stroke-width: 1.2;
}

.injury-body-labels {
  fill: var(--body-label);
  font-size: 14px;
  font-weight: 600;
}

/* By body part (the Injuries page): a heat map. A counted part is tinted in the accent, darker for more reports
   (the opacity is set per part), and filters the page when tapped. The part the page is filtered to, and the one
   the keyboard is on, is outlined. */
.injury-body-shapes .has-count {
  fill: var(--color-accent);
  pointer-events: auto;
  cursor: pointer;
}

.injury-body-shapes .has-count.is-on,
.injury-body-shapes .has-count:focus-visible {
  outline: none;
  stroke: var(--body-count);
  stroke-width: 3;
}

/* Each counted part's number, in plain type on the part: dark digits with a paper-coloured edge so they read on any
   tint, and no box over the drawing. A tap goes through it to the part. */
.injury-body-numbers {
  fill: var(--body-count);
  stroke: var(--body-fill);
  stroke-width: 4px;
  stroke-linejoin: round;
  paint-order: stroke;
  font-size: 22px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

/* A view's points layer lies over the picture and lets a tap through to the tinted parts. */
.injury-plan-view .injury-plan-points { pointer-events: none; }

/* A report's floor plan opens close up on its spot (ADR-0263, ADR-0264, ADR-0265). The picture and its dot share
   one stage (`--stage-*`), sized and slid inside the plan's box so the dot keeps its size. On the desk the box keeps
   the plan's shape and the close-up is --focus-zoom times the plan, its corner at --focus-x, --focus-y
   (injury-map.js); a tap swaps to the whole gym and back, animated. The phone's square is in mobile.css. */
.injury-plan.is-zoomable { --stage-w: 100%; --stage-h: 100%; --stage-x: 0%; --stage-y: 0%; cursor: zoom-in; }
.injury-plan.is-zoomable.is-zoomed {
  --stage-w: calc(var(--focus-zoom) * 100%); --stage-h: calc(var(--focus-zoom) * 100%);
  --stage-x: calc(var(--focus-x) * var(--focus-zoom) * -100%); --stage-y: calc(var(--focus-y) * var(--focus-zoom) * -100%);
  cursor: zoom-out;
}
.injury-plan.is-zoomable > .injury-plan-img,
.injury-plan.is-zoomable > .injury-plan-points {
  position: absolute; left: var(--stage-x); top: var(--stage-y); width: var(--stage-w); height: var(--stage-h);
}
/* Only a tap animates; the report opens already close up (injury-map.js adds is-toggled on the first tap). */
.injury-plan.is-zoomable.is-toggled > .injury-plan-img,
.injury-plan.is-zoomable.is-toggled > .injury-plan-points {
  transition: left var(--anim-slide-duration) ease, top var(--anim-slide-duration) ease,
    width var(--anim-slide-duration) ease, height var(--anim-slide-duration) ease;
}
.injury-plan.is-zoomable:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* Its corner says what a tap does: show the whole gym, or close up again. */
.injury-plan-zoom {
  position: absolute; top: var(--space-1); right: var(--space-1);
  display: grid; place-items: center; width: 28px; height: 28px;
  background: var(--color-bg-elevated); border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  color: var(--color-text-muted); pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .injury-plan.is-zoomable.is-toggled > .injury-plan-img,
  .injury-plan.is-zoomable.is-toggled > .injury-plan-points { transition: none; }
}

/* Under the figure: what was recorded once a spot is marked, and Not one spot.
   Nothing until then; the field's title says what to do (owner 2026-10-16). */
.injury-body-readout {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.injury-body-readout strong { color: var(--color-text); }

/* The report, in bands (owner 2026-10-16), in the form and the report window
   alike (owner 2026-10-17): the two maps side by side, the same height, then
   the facts in two columns. A band spaces itself the way a modal's
   .form-group does (its bottom margin, none when last). */
.injury-band-maps {
  display: grid;
  /* --maps-cols is each drawing's width per unit of height, set by the form,
     (injury-map.js `mapsColumns`), so the plan and the figure stand the same height. */
  grid-template-columns: var(--maps-cols, 3fr 1fr);
  gap: var(--space-4);
  align-items: start;
}

.injury-band-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--space-5);
  align-items: start;
}

.injury-band-maps,
.injury-band-cols { margin-bottom: var(--space-3); }

.injury-band-maps:last-child,
.injury-band-cols:last-child { margin-bottom: 0; }

.injury-band-col { min-width: 0; }

/* Type of injury: one or more, a chip each. */
.injury-type-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* ============================================================================
 * Injuries page
 * ========================================================================== */

.injuries-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  /* The band above is flush with the page's edges; the content starts one body inset below it,
     as a page without a band starts below its header. */
  padding-top: var(--page-body-pad);
}

/* The two maps side by side (the report's own maps band); the page's gap spaces it. */
.injuries-page > .injury-band-maps { margin-bottom: 0; }

/* Side by side, the grid's gap spaces the two maps' sections (stacked on a phone too): the stacking margin
   `.titled-section + .titled-section` adds (v3.css) would drop the body figure below the floor plan. */
.injury-band-maps > .titled-section:not(.hidden) + .titled-section:not(.hidden) { margin-top: 0; }

/* ============================================================================
 * List row (page, account tab, Staff Notes call-backs)
 * ========================================================================== */

.injury-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.injury-row {
  display: grid;
  grid-template-columns: 170px 1fr auto;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.injury-row:hover { background: var(--hover-row); }

.injury-row-when {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
}

.injury-row-due {
  display: block;
  font-weight: var(--font-medium);
}

.injury-row-due.is-due { color: var(--color-paused); }

.injury-row-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.injury-row-who { font-weight: var(--font-semibold); }

.injury-row-what {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.injury-row-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: flex-end;
}

/* The lock note, when there is one, spaced like the bands under it. */
.injury-locked { margin: 0 0 var(--space-3); }


/* ============================================================================
 * Detail and form
 * ========================================================================== */

.injury-text { white-space: pre-wrap; }

.injury-media-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.injury-media-player video,
.injury-media-player img {
  display: block;
  max-width: 100%;
  max-height: 60vh;
  margin-top: var(--space-2);
  border-radius: var(--radius-sm);
}

/* The report window's cards are flex columns (.record-card): its buttons keep
   their own width. */
.injury-add-media,
.injury-record-call { align-self: flex-start; }

.injury-media-list + .injury-add-media { margin-top: var(--space-2); }

.injury-file-list {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-4);
  font-size: var(--text-sm);
}

.injury-file-list:empty { display: none; }

/* How serious is a row of `.choice` radio cards (design-system/choice.js). The "what happens" lines are always there,
   so choosing never moves a thing. */

/* A level's points: short, so the three cards stay a glance (owner 2026-10-16). */
.injury-severity-points {
  margin: 0;
  padding-left: 1.1em;
  font-size: var(--text-sm);
  line-height: 1.35;
  color: var(--color-text-secondary);
}

/* ============================================================================
 * Phone
 * ========================================================================== */

@media (max-width: 767px) {
  /* The applied filters drop under their title rather than crowding it. */
  .injuries-page .section-legend { flex-wrap: wrap; }

  .injury-row {
    grid-template-columns: 1fr;
    gap: var(--space-1);
  }

  .injury-row-chips { justify-content: flex-start; }

  .injury-dot { width: 12px; height: 12px; }

  .injury-band-maps,
  .injury-band-cols { grid-template-columns: minmax(0, 1fr); }
}
