/* Orthanc DICOM Explorer — app-specific styling layered on top of
   skeleton.css (vendored from fhir_server — see that file's own header for
   why). Defines this explorer's own accent palette, plus the Orthanc-
   specific search filter row and study-list polish. Linked after
   skeleton.css — see index.html. */

:root {
  --accent: #2C5F8A;
  --accent-dark: #1D3F5C;
  --accent-tint: #E4EEF5;
}

/* ---- ID search field (primary row) ----
   Reuses skeleton.css's `.search__field` positioning/input styling — this
   modifier just gives it a narrower fixed width (unlike the name field's
   flex: 1) so the row reads name → ID → search → clear, same as Erebor.
   180px so the placeholder — "ID, e.g. OR-60394" — isn't cut off
   (Erebor's is 190px for its longer "ID, e.g. EB40271853"). */

.search__field--id {
  flex: 0 0 180px;
}

/* The name field is the only field on this row meant to give up space
   when it's tight (flex: 1 on .search__field already lets it shrink) —
   pin the search button so it's never the one that shrinks instead.
   (.clear-btn already has its own flex: none, in skeleton.css.) */
#search-btn {
  flex-shrink: 0;
}

@media (max-width: 900px) {
  /* Same cascade-order issue Erebor's own copy of this rule documents:
     skeleton.css's mobile rule sends the generic `.search__field` full
     width, but this file loads after it, so the unconditional rule above
     would otherwise win at this width despite not being the one that
     should apply here. Restate the override in the file that's
     cascade-last. */
  .search__field--id {
    flex: 1 1 100%;
  }
}

/* ---- advanced filters (second row) ----
   Modality + study date range + sex + age range, alongside the shared name
   search box from skeleton.css. Desktop keeps the original layout exactly
   as it was before pairing existed: six independent fields on one flex-wrap
   row (no fixed breakpoint), each with its own flex-basis below. The DOM is
   already grouped into three .filter-group pairs (modality+sex,
   date-from+date-to, min+max age), but .filter-group is display: contents
   up here — it contributes no box of its own, so its children are direct
   flex items of .filters and behave exactly as if the wrapper weren't
   there. Below the mobile breakpoint that flips (see media query): that's
   where individual fields were wrapping apart incoherently (e.g. min age
   landing on a different line than max age), so there each group becomes a
   real nowrap flex row instead, and a pair can no longer split. */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.filter-group {
  display: contents;
}

.filters__field {
  position: relative;
  flex: 1 1 110px;
}

.filters__field--date {
  flex: 1 1 150px;
}

.filters__field--age {
  flex: 1 1 90px;
}

/* Same fixed width as Erebor's own sex field (no grow/shrink, unlike every
   other filter field here). On desktop it also sits last in visual order —
   `order: 1` (every other field defaults to order: 0) pushes it after all
   of them regardless of where it falls in DOM source order, which is fixed
   by the modality+sex pairing the mobile layout needs (see .filter-group
   and the media query below, where this is reset to sit naturally beside
   modality instead). */
.filters__field--sex {
  flex: 0 0 130px;
  order: 1;
}

/* Only reachable on mobile, where the two study-date fields are swapped to
   <input type="text"> and so can hold something unparseable (see app.js).
   The native date picker desktop keeps can't produce an invalid value. */
.filters input.is-invalid {
  border-color: var(--down);
}

@media (max-width: 900px) {
  .filter-group {
    display: flex;
    flex-wrap: nowrap;
    gap: 8px;
    min-width: 0;
  }

  .filter-group--modality-sex {
    flex: 1 1 248px;   /* same 110+130+gap reference width as desktop; the two fields split it evenly here (see below) rather than 110/130 */
  }

  /* Same basis as the age pair below, not desktop's wider 150px-per-field
     one — the two pairs sit next to each other here and reading as
     different sizes was the visual inconsistency. Their fields split the
     pair evenly (see below), so a date field and an age field come out the
     same width. The dotted "dd.mm.yyyy" text input this width now has to
     hold is narrower than the native picker desktop keeps, so it fits. */
  .filter-group--date {
    flex: 1 1 188px;
  }

  .filter-group--age {
    flex: 1 1 188px;   /* two 90px age fields + gap */
  }

  .filter-group > .filters__field {
    min-width: 0;
  }

  /* Even split within the date pair, overriding desktop's 150px basis the
     same way the modality+sex rule below overrides its own — without it
     the fields would shrink in proportion to a basis the pair no longer
     has room for. */
  .filter-group--date > .filters__field {
    flex: 1 1 0%;
  }

  /* Modality and sex split their pair's width evenly here — desktop's
     mismatched 110px/130px-fixed split (still in effect via the
     unconditional .filters__field / .filters__field--sex rules above)
     doesn't apply at this width. Wins over .filters__field--sex's own
     flex on specificity (two classes vs. one), regardless of source order. */
  .filter-group--modality-sex > .filters__field {
    flex: 1 1 0%;
  }

  /* Undo the desktop-only reorder — here sex belongs right next to
     modality, its actual DOM position, as the pair's second field. */
  .filters__field--sex {
    order: 0;
  }
}

/* Same look as skeleton.css's `.search input` — duplicated here rather
   than shared across a class boundary since this row is this explorer's
   own addition, not part of the shared skeleton. */
.filters input,
.filters select {
  width: 100%;
  font-family: var(--mono);
  font-size: 14px;
  padding: 10px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 3px;
  background: var(--panel);
  color: var(--ink);
}

.filters input:focus,
.filters select:focus {
  outline: none;
  border-color: var(--accent);
}

/* ---- exam list (patient detail view) ----
   One row per exam (a study and/or its RIS report) on one fixed grid:
   date | type | content | actions. Every column but content has a fixed
   width and the actions column is kept even when a row has one button, so
   rows line up whatever they hold. More than ten exams group into
   skeleton.css's year drawers (newest open); fewer stay a flat list with
   full dates. */

.detail__group-count {
  font-weight: 400;
  color: var(--ink-soft);
}

.xrow {
  --xrow-date: 56px;
  display: grid;
  grid-template-columns: var(--xrow-date) 76px minmax(0, 1fr) 128px;
  grid-template-areas: "date type content actions";
  align-items: start;
  column-gap: 14px;
  padding: 9px 4px;
  border-bottom: 1px dashed var(--border);
}

.xrow:last-child {
  border-bottom: 0;
}

.xlist--full-dates .xrow {
  --xrow-date: 96px;
}

.xrow__date {
  grid-area: date;
  padding-top: 3px;
  font-family: var(--mono);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* Modality as a bracket tag filling its column — the same width for every
   row whatever the modality. */
.xrow__type {
  grid-area: type;
  min-width: 0;
}

.xrow__type .tag {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
  white-space: nowrap;
}

.xrow__content {
  grid-area: content;
  min-width: 0;
  max-width: 70ch;
}

.xrow__title,
.xrow__detail {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.xrow__title {
  font-size: 14px;
  line-height: 1.4;
}

.xrow__detail {
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--ink-soft);
}

/* Two fixed slots, "read" then "view", so each button sits in the same
   place on every row — a lone "read" lines up under the other "read"s. */
.xrow__actions {
  grid-area: actions;
  display: grid;
  grid-template-columns: 58px 58px;
  justify-content: end;
  gap: 6px;
}

.xrow__btn--read { grid-column: 1; }
.xrow__btn--view { grid-column: 2; }

/* Same look as skeleton.css's .detail__back — secondary actions in this
   same detail view, one size for every button. "view" opens the DICOM
   viewer in its own popup window (see viewStudy() in app.js). */
.xrow__btn {
  width: 58px;
  font-family: var(--mono);
  font-size: 12px;
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: 2px;
  padding: 4px 0;
  cursor: pointer;
  color: var(--accent-dark);
}

.xrow__btn:hover {
  background: var(--accent-tint);
  border-color: var(--accent);
}

/* ---- report reader ----
   An overlay in the explorer's terminal style: skeleton.css's .terminal
   window and path bar (no window-control dots), the report below. */

body.reader-open {
  overflow: hidden;
}

.reader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(20, 24, 28, 0.55);
}

.reader__window {
  display: flex;
  flex-direction: column;
  width: min(760px, 100%);
  max-height: 100%;
  overflow: hidden;
  background: var(--panel);
}

.reader__bar {
  justify-content: space-between;
}

.reader__close {
  font-family: var(--mono);
  font-size: 12px;
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: 2px;
  padding: 3px 10px;
  cursor: pointer;
  color: var(--accent-dark);
}

.reader__close:hover {
  background: var(--panel);
  border-color: var(--accent);
}

.reader__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 12px;
  padding: 16px 20px 12px;
  border-bottom: 1px solid var(--border);
}

.reader__title {
  margin: 0;
  font-family: var(--mono);
  font-size: 17px;
  font-weight: 600;
}

.reader__meta {
  grid-column: 1;
  font-size: 13px;
  color: var(--ink-soft);
}

.reader__actions {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
}

.reader__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-anchor: none;
  padding: 14px 20px 20px;
}

/* The rendered report: sanitized to plain structural tags on the gateway,
   so only those need styling. */
.reader__doc {
  max-width: 68ch;
  font-size: 14.5px;
  line-height: 1.55;
}

.reader__doc > :first-child { margin-top: 0; }
.reader__doc h1, .reader__doc h2, .reader__doc h3, .reader__doc h4 { margin: 1.2em 0 0.4em; line-height: 1.3; }
.reader__doc h1 { font-size: 18px; }
.reader__doc h2 { font-size: 15.5px; }
.reader__doc h3, .reader__doc h4 { font-size: 14.5px; }
.reader__doc p, .reader__doc ul, .reader__doc ol { margin: 0.6em 0; }
.reader__doc ul, .reader__doc ol { padding-left: 1.4em; }
.reader__doc hr { margin: 1em 0; border: 0; border-top: 1px solid var(--border); }

/* Matches skeleton.css's stack breakpoint. Rows stack: date and type on one
   line, the content below, the actions under that; the reader fills the
   screen. */
@media (max-width: 700px) {
  .xrow {
    grid-template-columns: var(--xrow-date) 76px minmax(0, 1fr);
    grid-template-areas:
      "date type ."
      "content content content"
      "actions actions actions";
    row-gap: 6px;
  }

  .xrow__actions {
    justify-content: start;
  }

  .reader {
    padding: 0;
  }

  .reader__window {
    width: 100%;
    height: 100%;
    border-radius: 0;
  }
}

/* Second line under the patient count: "43 studies" (same as Erebor's). */
.stat__sub {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-soft);
}

/* ---- footer link + imaging credits page (/credits) ----
   The credits page is generated by curated_patients/scripts/imaging_credits.py;
   it reuses the terminal panel on its own, one column wide. */

.footer a {
  color: inherit;
}

.credits {
  max-width: 860px;
  margin: 0 auto;
}

.credits__head {
  margin: 26px 0 10px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

.credits__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.credit {
  padding: 12px 0;
  border-bottom: 1px dashed var(--border);
}

.credit:last-child {
  border-bottom: 0;
}

.credit__title {
  font-weight: 600;
  font-size: 14.5px;
}

.credit__meta {
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--ink-soft);
}

.credit__cite {
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.credits__back {
  margin-top: 22px;
  font-family: var(--mono);
  font-size: 12.5px;
}
