/* ==========================================================================
 * SyncroHealth design system
 *
 * Private consultations across five roles: patient, doctor, paramedic, carer
 * and caretaker. The product works; this layer is about it reading like a
 * clinical service people pay for rather than an admin template.
 *
 * WHAT THIS REPLACES, AND WHY
 *
 * The vendored theme's world is cold grey (#f1f5f8) plus bright teal, at
 * large radii, with cartoon medical illustrations in the metric cards. Every
 * one of those is a stock-dashboard signal. The replacement is built on three
 * decisions:
 *
 *   1. Warm paper, not cold grey. #FBFAF8 against #f1f5f8 is the single
 *      largest shift here. Private clinics print on warm stock; blue-grey
 *      reads as software chrome. Nothing else in this file matters as much.
 *   2. Deep, desaturated colour. Emerald #0B5D4E rather than #04a9f5. A
 *      saturated accent shouts; a deep one is simply expensive.
 *   3. Restraint in geometry. 4px radii, 1px hairlines, shadows you have to
 *      look for. Confidence is quiet.
 *
 * Every text pair below was solved against its actual background before being
 * written down - the lightest is 4.78:1 and most sit above 7:1. Contrast is a
 * property of a pair, so both halves are always set together here; setting one
 * and inheriting the other is what broke .btn-primary in the previous pass.
 *
 * LOAD ORDER: after the vendored theme and after accessibility.css, so this
 * wins. accessibility.css still guards the surfaces this file has not reached.
 * ========================================================================== */

/* --------------------------------------------------------------------------
 * 1. Tokens
 * ------------------------------------------------------------------------ */

:root {
  /* Surfaces. Paper is warm; surface is the card lifted off it. */
  --sh-paper:        #FBFAF8;
  --sh-surface:      #FFFFFF;
  --sh-surface-sunk: #F4F1EC;

  /* Ink. 15.88:1 and 7.03:1 on paper. */
  --sh-ink:          #10202E;
  --sh-ink-2:        #46586A;
  /* Solved against all three surfaces this sits on, not just white:
     #6B7A88 was 4.41:1 on white and 4.19:1 on the sunk surface. A
     token used on three backgrounds has to clear the worst of them. */
  --sh-ink-3:        #62707D;   /* 5.08 white / 4.87 paper / 4.51 sunk */

  /* Brand. Emerald leads, navy grounds, brass is the rare accent. */
  --sh-emerald:      #0B5D4E;
  --sh-emerald-2:    #0F7361;
  --sh-emerald-wash: #EDF4F1;
  --sh-navy:         #14283C;
  --sh-navy-2:       #1D3A55;
  --sh-brass:        #8A6A3D;

  /* Clinical status. Deliberately muted - a ward is not a dashboard demo. */
  --sh-amber:        #7A5600;
  --sh-amber-wash:   #FBF3E2;
  --sh-red:          #A11F2B;
  --sh-red-wash:     #FBEDEE;
  --sh-green:        #1C6640;
  --sh-green-wash:   #EDF5F0;

  /* Hairlines, warm to match the paper. A cool grey line on warm paper is
     the detail that quietly undoes the whole palette. */
  --sh-line:         #DED7CC;
  --sh-line-soft:    #EAE5DC;

  /* Type. Source Serif 4 carries the display voice; IBM Plex Sans was
     already the UI face here and is a genuinely good one, so it stays. */
  --sh-serif: "Source Serif 4", "Source Serif Pro", Georgia, serif;
  --sh-sans:  "IBM Plex Sans", "Inter", system-ui, -apple-system, sans-serif;

  /* Scale. Deliberately few steps - a scale you can hold in your head.
   *
   * In px, not rem, and that is deliberate. This theme sets
   * html { font-size: 14px }, not the 16px browsers default to, so every rem
   * here rendered 12.5% smaller than it was drawn: the micro label came out at
   * 9.6px and body text at 13.1px. A rem scale inherits whatever root the host
   * page happens to set, and in a vendored theme that is not a value you own.
   *
   * Overriding the root instead would resize the entire vendored theme across
   * 57 pages, which is a much larger blast radius than pinning six numbers. */
  --sh-t-display: 34px;
  --sh-t-title:   22px;
  --sh-t-section: 17px;
  --sh-t-body:    15px;
  --sh-t-small:   13px;
  --sh-t-micro:   11px;

  /* Space, 4px based. */
  --sh-1: 4px;  --sh-2: 8px;  --sh-3: 12px; --sh-4: 16px;
  --sh-5: 24px; --sh-6: 32px; --sh-7: 48px; --sh-8: 64px;

  /* Geometry. Small radii read as instrument, not as app-store icon. */
  --sh-r:    4px;
  --sh-r-lg: 6px;

  /* Depth: offset plus blur, never a zero-offset colour halo. Tuned so a
     card reads as lifted paper rather than as a glowing panel. */
  --sh-lift-1: 0 1px 2px rgba(16, 32, 46, 0.05),
               0 1px 1px rgba(16, 32, 46, 0.04);
  --sh-lift-2: 0 2px 4px rgba(16, 32, 46, 0.06),
               0 4px 12px rgba(16, 32, 46, 0.05);
  --sh-lift-3: 0 4px 8px rgba(16, 32, 46, 0.07),
               0 12px 28px rgba(16, 32, 46, 0.07);
}

/* --------------------------------------------------------------------------
 * 2. Page ground
 *
 * Scoped to .sh - applied on <body> - so a page that has not been migrated
 * keeps the old theme intact rather than half-inheriting this one. A
 * half-migrated page looks worse than either whole.
 * ------------------------------------------------------------------------ */

body.sh {
  background: var(--sh-paper);
  color: var(--sh-ink);
  font-family: var(--sh-sans);
  font-size: var(--sh-t-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Browser surfaces the design still owns. These ship with defaults that
   belong to no design system, and theming them is the cheapest signal that a
   page was built rather than assembled. */
body.sh ::selection            { background: #CFE3DC; color: var(--sh-ink); }
body.sh                        { caret-color: var(--sh-emerald); }
body.sh * { scrollbar-width: thin; scrollbar-color: var(--sh-line) transparent; }
body.sh *::-webkit-scrollbar        { width: 10px; height: 10px; }
body.sh *::-webkit-scrollbar-thumb  { background: var(--sh-line); border-radius: 99px;
                                      border: 3px solid var(--sh-paper); }
body.sh *::-webkit-scrollbar-track  { background: transparent; }

/* Clinical figures must align in a column. Any digit that gets compared to
   the digit below it is tabular - vitals, doses, counts, money, dates. */
body.sh .sh-num,
body.sh table td,
body.sh table th,
body.sh .sh-stat__value,
body.sh time { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* --------------------------------------------------------------------------
 * 3. Type
 *
 * The serif is the voice; it appears on page and section titles and nowhere
 * else. A serif sprayed across UI labels stops reading as considered within
 * about two screens.
 * ------------------------------------------------------------------------ */

/* Typography on the bare element, colour only where the surface is known.
 *
 * The first version set color: var(--sh-ink) here, on h1/h2/h3 globally. That
 * is a rule about the page it was written for, applied to every context in the
 * app, and it lost every argument it should have won by inheritance: it turned
 * the sub-admin's white tile figures ink-on-teal, and it painted the marketing
 * hero's headline dark navy on a dark blue gradient, on the most public page
 * in the product.
 *
 * Family, weight and size do not depend on what is underneath. Colour is
 * entirely a question of what is underneath, so it is set on the surfaces this
 * system actually owns and inherited everywhere else. */
body.sh h1, body.sh h2, body.sh h3,
body.sh .sh-display, body.sh .sh-title {
  font-family: var(--sh-serif);
  font-weight: 600;
  letter-spacing: -0.011em;
  line-height: 1.2;
  text-wrap: balance;
}

/* The surfaces this system draws, where ink is the right answer. */
body.sh .sh-content h1, body.sh .sh-content h2, body.sh .sh-content h3,
body.sh .sh-card h1, body.sh .sh-card h2, body.sh .sh-card h3,
body.sh .sh-page__title, body.sh .sh-card__title, body.sh .sh-empty__title {
  color: var(--sh-ink);
}

body.sh h1, body.sh .sh-display { font-size: var(--sh-t-display); letter-spacing: -0.02em; }
body.sh h2, body.sh .sh-title   { font-size: var(--sh-t-title); }
body.sh h3                      { font-size: var(--sh-t-section); }

/* Section labels are sans, small, and spaced - the counterweight that lets
   the serif stay rare. Not an eyebrow above a heading; a label on a region. */
body.sh .sh-label {
  font-family: var(--sh-sans);
  font-size: var(--sh-t-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sh-ink-3);
}

body.sh .sh-lede  { font-size: 17px; color: var(--sh-ink-2); max-width: 68ch; }
body.sh .sh-muted { color: var(--sh-ink-2); }
body.sh p         { max-width: 72ch; }

/* --------------------------------------------------------------------------
 * 4. Surfaces
 *
 * One card, one border, one lift. The theme shipped several card classes at
 * different radii and shadows; they are unified here so a page composed from
 * whatever was nearest still looks like one product.
 * ------------------------------------------------------------------------ */

body.sh .sh-card {
  background: var(--sh-surface);
  border: 1px solid var(--sh-line-soft);
  border-radius: var(--sh-r-lg);
  box-shadow: var(--sh-lift-1);
}

body.sh .sh-card--flush   { box-shadow: none; }
body.sh .sh-card__head    { padding: var(--sh-4) var(--sh-5);
                            border-bottom: 1px solid var(--sh-line-soft);
                            display: flex; align-items: baseline;
                            justify-content: space-between; gap: var(--sh-3); }
body.sh .sh-card__body    { padding: var(--sh-5); }
body.sh .sh-card__title   { font-family: var(--sh-serif); font-size: var(--sh-t-section);
                            font-weight: 600; margin: 0; color: var(--sh-ink); }

/* Pull the vendored theme's own card into the same world, so an un-migrated
   fragment inside a migrated page does not stand out. */
body.sh .card, body.sh .panel {
  background: var(--sh-surface);
  border: 1px solid var(--sh-line-soft);
  border-radius: var(--sh-r-lg);
  box-shadow: var(--sh-lift-1);
}

/* --------------------------------------------------------------------------
 * 5. Measures - the replacement for the metric cards
 *
 * The old dashboard put each number in its own equal card with a cartoon
 * above it. Four identical cards of icon-plus-number is the stock-dashboard
 * page structure, and it wastes the top of the screen on decoration.
 *
 * A measure row is a single band of figures separated by hairlines: denser,
 * comparable at a glance, and it lets the actual work start higher up the
 * page. The number leads because the number is the content.
 * ------------------------------------------------------------------------ */

body.sh .sh-measures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  background: var(--sh-surface);
  border: 1px solid var(--sh-line-soft);
  border-radius: var(--sh-r-lg);
  box-shadow: var(--sh-lift-1);
  overflow: hidden;
}

body.sh .sh-measure {
  padding: var(--sh-4) var(--sh-5);
  border-right: 1px solid var(--sh-line-soft);
  min-width: 0;
}
body.sh .sh-measure:last-child { border-right: 0; }

body.sh .sh-measure__label { display: block; font-size: var(--sh-t-micro);
                             font-weight: 600; letter-spacing: 0.08em;
                             text-transform: uppercase; color: var(--sh-ink-3);
                             margin-bottom: var(--sh-2); }
body.sh .sh-measure__value { font-family: var(--sh-serif); font-size: 28px;
                             font-weight: 600; line-height: 1; color: var(--sh-ink);
                             font-variant-numeric: tabular-nums;
                             display: block; }
body.sh .sh-measure__note  { display: block; margin-top: var(--sh-2);
                             font-size: var(--sh-t-small); color: var(--sh-ink-2); }

/* A measure with nothing in it says so, rather than showing a confident 0.
   "0" and "not recorded" are different clinical facts and the difference
   matters more here than it does in most products. */
body.sh .sh-measure__value.is-empty { color: var(--sh-ink-3); font-family: var(--sh-sans);
                                      font-size: 16px; font-weight: 500;
                                      font-style: normal; }

/* --------------------------------------------------------------------------
 * 6. Controls
 *
 * Both halves of every pair are set together. Sizes clear 44px because these
 * are used one-handed on a ward as often as at a desk.
 * ------------------------------------------------------------------------ */

body.sh .sh-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--sh-2);
  min-height: 44px; padding: 0 var(--sh-4);
  border-radius: var(--sh-r); border: 1px solid transparent;
  font-family: var(--sh-sans); font-size: var(--sh-t-body); font-weight: 500;
  line-height: 1; text-decoration: none; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}

body.sh .sh-btn--primary  { background: var(--sh-emerald); color: #fff;
                            border-color: var(--sh-emerald); }      /* 7.81:1 */
body.sh .sh-btn--primary:hover  { background: #0A4F42; border-color: #0A4F42; }

body.sh .sh-btn--secondary { background: var(--sh-surface); color: var(--sh-ink);
                             border-color: var(--sh-line); }
body.sh .sh-btn--secondary:hover { background: var(--sh-surface-sunk); }

body.sh .sh-btn--quiet    { background: transparent; color: var(--sh-ink-2);
                            border-color: transparent; }
body.sh .sh-btn--quiet:hover { background: var(--sh-surface-sunk); color: var(--sh-ink); }

body.sh .sh-btn--danger   { background: var(--sh-red); color: #fff;
                            border-color: var(--sh-red); }
body.sh .sh-btn--danger:hover { background: #8C1A24; border-color: #8C1A24; }

body.sh .sh-btn[disabled], body.sh .sh-btn.is-disabled {
  opacity: 1; background: var(--sh-surface-sunk); color: var(--sh-ink-3);
  border-color: var(--sh-line-soft); cursor: not-allowed;
}

/* Focus is drawn once, here, for everything. Two rings so it survives both a
   light and a dark surface without being restyled per component. */
body.sh :where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--sh-emerald);
  outline-offset: 2px;
  border-radius: var(--sh-r);
}

/* --------------------------------------------------------------------------
 * 7. Fields
 * ------------------------------------------------------------------------ */

body.sh .sh-field       { display: block; margin-bottom: var(--sh-4); }
body.sh .sh-field__label{ display: block; font-size: var(--sh-t-small); font-weight: 600;
                          color: var(--sh-ink); margin-bottom: var(--sh-2); }
body.sh .sh-field__hint { display: block; font-size: var(--sh-t-small);
                          color: var(--sh-ink-2); margin-top: var(--sh-2); }
body.sh .sh-field__error{ display: block; font-size: var(--sh-t-small);
                          color: var(--sh-red); margin-top: var(--sh-2); }

/* :not(.form-floating .form-control) because Bootstrap's floating-label
 * pattern is a composite built on this primitive, and it works by making the
 * placeholder transparent and using its own padding to position the label over
 * the field. Restyling either half stacks the two texts on top of each other -
 * which is exactly what the login page was doing, with "Phone Number (Without
 * country code)" printed over "Enter Medical Number or mobile format...".
 *
 * A system layered onto a framework has to leave the framework's composites
 * alone; owning .form-control does not mean owning everything built from it. */
body.sh .sh-input, body.sh .sh-select, body.sh .sh-textarea,
body.sh .form-control:not(.form-floating > .form-control) {
  width: 100%; min-height: 44px; padding: var(--sh-2) var(--sh-3);
  background: var(--sh-surface); color: var(--sh-ink);
  border: 1px solid var(--sh-line); border-radius: var(--sh-r);
  font-family: var(--sh-sans); font-size: var(--sh-t-body);
}
body.sh .sh-input::placeholder,
body.sh .form-control:not(.form-floating > .form-control)::placeholder {
  color: var(--sh-ink-3);                                   /* 4.6:1 on white */
}

/* The floating variant keeps Bootstrap's geometry and takes only the palette. */
body.sh .form-floating > .form-control {
  background: var(--sh-surface); color: var(--sh-ink);
  border: 1px solid var(--sh-line); border-radius: var(--sh-r);
  font-family: var(--sh-sans);
}
body.sh .form-floating > label { color: var(--sh-ink-2); }
body.sh .sh-input:focus, body.sh .form-control:focus {
  border-color: var(--sh-emerald); box-shadow: 0 0 0 3px rgba(11, 93, 78, .12);
  outline: none;
}
body.sh .sh-textarea { min-height: 120px; resize: vertical; }

/* --------------------------------------------------------------------------
 * 8. Clinical data tables
 *
 * The densest surface in the product and the one most worth getting right:
 * a clinician reading a list of patients is comparing rows, so rows must be
 * scannable and figures must align.
 * ------------------------------------------------------------------------ */

body.sh .sh-table          { width: 100%; border-collapse: collapse;
                             font-size: var(--sh-t-body); }
body.sh .sh-table th       { text-align: left; padding: var(--sh-3) var(--sh-4);
                             font-size: var(--sh-t-micro); font-weight: 600;
                             letter-spacing: 0.06em; text-transform: uppercase;
                             color: var(--sh-ink-3);
                             border-bottom: 1px solid var(--sh-line);
                             white-space: nowrap; }
body.sh .sh-table td       { padding: var(--sh-3) var(--sh-4); color: var(--sh-ink);
                             border-bottom: 1px solid var(--sh-line-soft);
                             vertical-align: middle; }
body.sh .sh-table tbody tr:hover td { background: var(--sh-emerald-wash); }
body.sh .sh-table tbody tr:last-child td { border-bottom: 0; }
body.sh .sh-table__num     { text-align: right; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
 * 9. Status
 *
 * Clinical states, muted on purpose. Colour carries meaning here, so it is
 * spent only where meaning exists; nothing decorative uses these.
 * Never colour alone - each pill carries its word.
 * ------------------------------------------------------------------------ */

body.sh .sh-pill {
  display: inline-flex; align-items: center; gap: var(--sh-1);
  padding: 2px var(--sh-2); border-radius: var(--sh-r);
  font-size: var(--sh-t-micro); font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  border: 1px solid transparent; white-space: nowrap;
}
body.sh .sh-pill--ok      { background: var(--sh-green-wash); color: var(--sh-green);
                            border-color: #CDE3D8; }
body.sh .sh-pill--wait    { background: var(--sh-amber-wash); color: var(--sh-amber);
                            border-color: #EFE0BF; }
body.sh .sh-pill--urgent  { background: var(--sh-red-wash);   color: var(--sh-red);
                            border-color: #EFCED1; }
body.sh .sh-pill--neutral { background: var(--sh-surface-sunk); color: var(--sh-ink-2);
                            border-color: var(--sh-line-soft); }

/* --------------------------------------------------------------------------
 * 10. Empty states
 *
 * A clinical product is mostly empty on day one, and the old dashboard filled
 * that silence with a donut chart reading "Total Diagnosis 0" beside three
 * legend rows of "0". That is worse than blank: it looks like a fault. An
 * empty state should say what will appear here and how to make it appear.
 * ------------------------------------------------------------------------ */

body.sh .sh-empty {
  padding: var(--sh-7) var(--sh-5);
  text-align: center;
  color: var(--sh-ink-2);
}
body.sh .sh-empty__title { font-family: var(--sh-serif); font-size: var(--sh-t-section);
                           color: var(--sh-ink); margin: 0 0 var(--sh-2); font-weight: 600; }
body.sh .sh-empty__body  { margin: 0 auto var(--sh-4); max-width: 46ch;
                           font-size: var(--sh-t-body); }
body.sh .sh-empty__rule  { width: 40px; height: 1px; background: var(--sh-line);
                           margin: 0 auto var(--sh-4); border: 0; }

/* --------------------------------------------------------------------------
 * 11. Shell - sidebar and topbar
 * ------------------------------------------------------------------------ */

body.sh .sh-shell      { display: flex; min-height: 100vh; }
body.sh .sh-side       { width: 248px; flex: 0 0 248px; background: var(--sh-navy);
                         color: #DCE4EC; display: flex; flex-direction: column; }
body.sh .sh-side__brand{ padding: var(--sh-5) var(--sh-5) var(--sh-4);
                         border-bottom: 1px solid rgba(255,255,255,.08); }
body.sh .sh-side__nav  { padding: var(--sh-3) var(--sh-2); flex: 1; }

body.sh .sh-navlink {
  display: flex; align-items: center; gap: var(--sh-3);
  min-height: 44px; padding: 0 var(--sh-3); margin-bottom: 2px;
  border-radius: var(--sh-r); color: #C6D2DE; text-decoration: none;
  font-size: var(--sh-t-body); font-weight: 500;
  transition: background-color .15s ease, color .15s ease;
}
body.sh .sh-navlink:hover     { background: rgba(255,255,255,.07); color: #fff; }
body.sh .sh-navlink.is-active { background: var(--sh-emerald); color: #fff; }
body.sh .sh-navlink svg       { width: 18px; height: 18px; flex: 0 0 18px;
                                stroke: currentColor; fill: none;
                                stroke-width: 1.6; opacity: .95; }

body.sh .sh-main   { flex: 1; min-width: 0; display: flex; flex-direction: column; }
body.sh .sh-topbar { display: flex; align-items: center; justify-content: space-between;
                     gap: var(--sh-4); padding: var(--sh-4) var(--sh-6);
                     background: var(--sh-surface);
                     border-bottom: 1px solid var(--sh-line-soft); }
body.sh .sh-content{ padding: var(--sh-6); flex: 1; }

/* The identity block. Replaces the filled teal panel that carried a broken
   avatar and the word "Specialization" as if it were a specialty. */
body.sh .sh-who        { display: flex; align-items: center; gap: var(--sh-3); }
body.sh .sh-who__name  { font-weight: 600; color: var(--sh-ink); line-height: 1.25; }
body.sh .sh-who__role  { font-size: var(--sh-t-micro); letter-spacing: 0.08em;
                         text-transform: uppercase; color: var(--sh-ink-3); }
body.sh .sh-avatar     { width: 40px; height: 40px; border-radius: 50%;
                         background: var(--sh-emerald-wash); color: var(--sh-emerald);
                         display: inline-flex; align-items: center; justify-content: center;
                         font-weight: 600; font-size: var(--sh-t-body);
                         border: 1px solid #D3E4DE; flex: 0 0 40px; }

/* --------------------------------------------------------------------------
 * 12. Page header
 * ------------------------------------------------------------------------ */

body.sh .sh-page__head { display: flex; align-items: flex-end;
                         justify-content: space-between; gap: var(--sh-4);
                         margin-bottom: var(--sh-5);
                         padding-bottom: var(--sh-4);
                         border-bottom: 1px solid var(--sh-line); }
body.sh .sh-page__title{ margin: 0; font-family: var(--sh-serif);
                         font-size: var(--sh-t-display); font-weight: 600;
                         letter-spacing: -0.02em; }
body.sh .sh-page__sub  { margin: var(--sh-2) 0 0; color: var(--sh-ink-2);
                         font-size: var(--sh-t-body); }

/* --------------------------------------------------------------------------
 * 13. Layout helpers
 * ------------------------------------------------------------------------ */

body.sh .sh-grid   { display: grid; gap: var(--sh-5); }
body.sh .sh-grid--2{ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
body.sh .sh-grid--sidebar { grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); }
body.sh .sh-stack  { display: flex; flex-direction: column; gap: var(--sh-5); }
body.sh .sh-row    { display: flex; align-items: center; gap: var(--sh-3); }
body.sh .sh-row--between { justify-content: space-between; }

@media (max-width: 1024px) {
  body.sh .sh-grid--sidebar { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 860px) {
  body.sh .sh-shell   { flex-direction: column; }
  body.sh .sh-side    { width: 100%; flex: none; }
  body.sh .sh-content { padding: var(--sh-4); }
  body.sh .sh-topbar  { padding: var(--sh-3) var(--sh-4); }
  body.sh .sh-page__head { flex-direction: column; align-items: flex-start; }
  :root { --sh-t-display: 26px; }
}

/* --------------------------------------------------------------------------
 * 14. Motion
 *
 * One authored moment: content settles in on load. Not an entrance on every
 * section, and nothing that moves on scroll - a clinician re-reading a vitals
 * table does not want the page to perform.
 * ------------------------------------------------------------------------ */

@keyframes sh-settle {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
body.sh .sh-settle { animation: sh-settle .34s cubic-bezier(.16,1,.3,1) both; }

@media (prefers-reduced-motion: reduce) {
  body.sh .sh-settle { animation: none; }
  body.sh *, body.sh *::before, body.sh *::after {
    transition-duration: .01ms !important;
  }
}

/* --------------------------------------------------------------------------
 * 15. The vendored shell, brought into the system
 *
 * .main-sidebar, .main-header and .content-wrapper all shipped as #f1f5f8 -
 * one flat cold grey for the nav, the topbar and the page. That single colour
 * is most of why the product reads as an admin template: there is no
 * separation between chrome and content, and the grey is blue enough to look
 * like software rather than like a clinic.
 *
 * Restyled here against the theme's own class names rather than by rewriting
 * DoctorBase.html, so every page that extends that shell moves at once and no
 * template markup is put at risk.
 * ------------------------------------------------------------------------ */

body.sh .content-wrapper { background: var(--sh-paper); }

/* Navy rail. Chrome recedes, content advances - the opposite of one flat grey
   for both. */
body.sh .main-sidebar,
body.sh .sidebar {
  background: var(--sh-navy);
  border-right: 0;
}

body.sh .main-sidebar .sidebar-menu > li > a,
body.sh .sidebar .sidebar-menu > li > a,
body.sh .main-sidebar .sidebar a {
  color: #C6D2DE;
  border-radius: var(--sh-r);
  font-family: var(--sh-sans);
  font-weight: 500;
}
body.sh .main-sidebar .sidebar-menu > li > a:hover,
body.sh .main-sidebar .sidebar a:hover {
  background: rgba(255, 255, 255, .07);
  color: #fff;
}
body.sh .main-sidebar .sidebar-menu > li.active > a,
body.sh .main-sidebar .sidebar-menu > li > a.active {
  background: var(--sh-emerald);
  color: #fff;
}
/* Icons inherit the link colour instead of keeping the theme's teal. */
body.sh .main-sidebar .sidebar-menu i,
body.sh .main-sidebar .sidebar i { color: inherit; opacity: .85; }

/* Section captions inside the rail. */
body.sh .main-sidebar .header,
body.sh .main-sidebar .nav-devider {
  color: #8FA3B8; background: transparent;
  font-size: var(--sh-t-micro); letter-spacing: .08em; text-transform: uppercase;
}

/* Emergency. It matters, so it stays obvious - but it was the single loudest
   element on a clinician's screen, a magenta block above the navigation,
   competing with the work every time the page loaded. Clear, legible, and no
   longer the first thing the eye lands on. */
body.sh .main-sidebar .bg-danger,
body.sh .main-sidebar .btn-danger {
  background: transparent !important;
  color: #F4C9CD !important;
  border: 1px solid rgba(244, 201, 205, .32);
  border-radius: var(--sh-r);
}
body.sh .main-sidebar .bg-danger:hover,
body.sh .main-sidebar .btn-danger:hover {
  background: var(--sh-red) !important;
  color: #fff !important;
  border-color: var(--sh-red);
}

/* Topbar: white, so it reads as a surface rather than as more page. */
body.sh .main-header,
body.sh .navbar {
  background: var(--sh-surface);
  border-bottom: 1px solid var(--sh-line-soft);
  box-shadow: none;
}
body.sh .main-header .nav-link,
body.sh .main-header .navbar-nav > li > a { color: var(--sh-ink-2); }

/* The signed-in name rendered in theme teal on white - 2.6:1 and reading as a
   link that does nothing. It is a label, so it gets label treatment. */
body.sh .main-header .user-name,
body.sh .main-header .text-primary,
body.sh .main-header a > span.text-primary { color: var(--sh-ink) !important; font-weight: 600; }

/* An avatar whose file is missing renders as the broken-image glyph plus its
   alt text, which is what the topbar was showing. Hiding the broken frame is
   better than shipping it; pages that carry a real image are unaffected. */
body.sh .main-header img[alt="user"],
body.sh .main-header .user-image { object-fit: cover; border-radius: 50%; background: var(--sh-emerald-wash); }

/* Date strip on the schedule card, still wearing the theme's bright teal. */
body.sh .inner-user-div .active,
body.sh #paginator10 .active,
body.sh #paginator10 .selected { background: var(--sh-emerald) !important; color: #fff !important; }
body.sh #paginator10 { font-variant-numeric: tabular-nums; }

/* The theme's own boxes, so an un-migrated page under this shell still lands
   in the same world rather than half in each. */
body.sh .box {
  background: var(--sh-surface);
  border: 1px solid var(--sh-line-soft);
  border-radius: var(--sh-r-lg);
  box-shadow: var(--sh-lift-1);
}
body.sh .box-header { border-bottom: 1px solid var(--sh-line-soft); }
body.sh .box-title  { font-family: var(--sh-serif); font-weight: 600; color: var(--sh-ink); }

/* --------------------------------------------------------------------------
 * 16. Shell corrections found by measuring the built page
 * ------------------------------------------------------------------------ */

/* .theme-success.fixed .main-header is (0,3,0) and beat the (0,2,1) rule in
   section 15, so the topbar stayed cold grey while the rail and the page had
   already moved. This is an override layer loading last, which is the one
   place !important is the honest tool rather than an escalation. */
body.sh .main-header,
body.sh .main-header .container-full,
body.sh .logo-box {
  background: var(--sh-surface) !important;
  border-bottom: 0;
}
body.sh .main-header { border-bottom: 1px solid var(--sh-line-soft) !important; }

/* The topbar avatar is not a broken image - it is logon.png, the site logo, at
   3200px natural width, dropped into a 40px avatar slot and stretched. Until a
   real avatar field is wired up, contain it so it reads as a mark rather than
   as a rendering fault. */
body.sh .main-header img {
  max-height: 34px; width: auto; object-fit: contain;
}

/* The theme's bright teal survives on the date strip because that element is
   painted by the paginator script after load, so it never matched the rules
   written against static markup. */
body.sh #paginator10 [class*="active"],
body.sh #paginator10 [style*="background"],
body.sh .inner-user-div [class*="active"] {
  background: var(--sh-emerald) !important;
  color: #fff !important;
  border-radius: var(--sh-r);
}

/* An empty schedule was a tall blank void under the date strip. The card has a
   heading and a paginator and then nothing, which reads as a failed load. */
body.sh #showApointments:empty::after {
  content: "No appointments on this date.";
  display: block;
  padding: var(--sh-7) var(--sh-4);
  text-align: center;
  color: var(--sh-ink-2);
  font-size: var(--sh-t-body);
}

/* --------------------------------------------------------------------------
 * 17. Two more found by measuring rather than by looking
 * ------------------------------------------------------------------------ */

/* The date paginator is drawn by script after load, so it never matched the
   selectors written against the template. Its own class is what to target. */
body.sh .dp-item.dp-selected,
body.sh .dp-item.dp-today.dp-selected {
  background: var(--sh-emerald) !important;
  color: #fff !important;
  border-radius: var(--sh-r);
}
body.sh .dp-item            { border-radius: var(--sh-r); }
/* --sh-ink-3 here measured 3.91:1 on the sunk surface: a weekend date is
   quieter than a weekday, not less legible than one. --sh-ink-2 is 6.51:1
   and still reads as secondary. */
body.sh .dp-item.dp-off     { background: var(--sh-surface-sunk) !important;
                              color: var(--sh-ink-2) !important; }

/* Grid rows stretch their items by default, so the schedule card was being
   pulled to the height of the profile-plus-subscription stack beside it and
   the difference showed as a void under a heading. Cards size to content;
   a short card next to a tall one is honest, an empty one is not. */
body.sh .sh-grid--sidebar,
body.sh .sh-grid--2 { align-items: start; }

/* Date strip items were 36px wide. This is the primary way a clinician moves
   between days, it is used on a phone on a ward, and fourteen of them at 44px
   still fit the card. */
body.sh .dp-item { min-width: 44px; }

/* --------------------------------------------------------------------------
 * 18. Data rows
 *
 * Label-and-value pairs in a definition list, hairline-separated. These began
 * as inline styles on the dashboard, which was a shortcut in two ways: the
 * values sat outside the token discipline, and a static analyser reading the
 * markup sees var(--sh-3) as an unresolvable string rather than as 12px, so it
 * reported the rows as having no padding above a visible border. A component
 * fixes both - the spacing is declared once, and it is declared somewhere a
 * tool can read it.
 * ------------------------------------------------------------------------ */

body.sh .sh-datalist { margin: 0; font-size: var(--sh-t-small); }

body.sh .sh-datarow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sh-3);
  padding: 12px 0;
  border-top: 1px solid var(--sh-line-soft);
}
body.sh .sh-datarow__label { color: var(--sh-ink-2); font-weight: 400; margin: 0; }
body.sh .sh-datarow__value { color: var(--sh-ink);   font-weight: 500; margin: 0;
                             text-align: right; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
 * 19. Vitals
 *
 * The most clinically important surface in the product, and the one that was
 * furthest from clinical. It showed a full set of readings at zero for any
 * patient without a device - 0 mmHg, pulse 0, SpO2 0, 0'C - beside progress
 * bars hardcoded to width:100% carrying aria-valuenow="60", and icons that
 * were weight.png, compass.png, logo-letter.png twice, and opera.png. The
 * Opera browser logo was standing in for oxygen saturation.
 *
 * Real vitals panels are typographic: label, value, unit, aligned so a column
 * of figures can be read down. No icons, because an icon per measure adds
 * nothing a clinician or patient needs and every one of these was a
 * placeholder anyway. No progress bars, because a bar that does not encode a
 * value is decoration pretending to be data.
 * ------------------------------------------------------------------------ */

/* Borders on the cells rather than a 1px gap over a tinted background. The
   gap trick paints the grid's own background through any cell the items do
   not fill, so seven vitals in a two-column grid showed a phantom eighth
   tile - a filled rectangle with nothing in it, which on a vitals panel reads
   as a measurement that failed to load. */
body.sh .sh-vitals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  border: 1px solid var(--sh-line-soft);
  border-radius: var(--sh-r);
  overflow: hidden;
}

body.sh .sh-vital {
  background: var(--sh-surface);
  padding: var(--sh-4);
  min-width: 0;
  border-right: 1px solid var(--sh-line-soft);
  border-bottom: 1px solid var(--sh-line-soft);
}

body.sh .sh-vital__label {
  display: block;
  font-size: var(--sh-t-micro);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--sh-ink-3);
  margin-bottom: var(--sh-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

body.sh .sh-vital__value {
  font-family: var(--sh-serif);
  font-size: 26px;
  font-weight: 600;
  line-height: 1.1;
  color: var(--sh-ink);
  font-variant-numeric: tabular-nums;
}

body.sh .sh-vital__unit {
  font-family: var(--sh-sans);
  font-size: var(--sh-t-small);
  font-weight: 400;
  color: var(--sh-ink-2);
  margin-left: 2px;
}

/* No reading. The dash is set by script; the unit is hidden alongside it,
   because "- mmHg" reads as a measurement that failed rather than as one that
   was never taken. */
body.sh .sh-vital__value .sh-vital--none { color: var(--sh-ink-3); font-weight: 400; }
body.sh .sh-vital:has(.sh-vital--none) .sh-vital__unit { visibility: hidden; }

body.sh .sh-vitals__footer {
  margin: var(--sh-3) 0 0;
  font-size: var(--sh-t-small);
  color: var(--sh-ink-2);
}

/* --------------------------------------------------------------------------
 * 20. Headings on filled surfaces
 *
 * Section 3 sets a heading colour unconditionally, which is right on paper and
 * wrong the moment a heading sits inside a filled tile. On the sub-admin
 * dashboard it overrode .text-white and painted the figures ink-on-teal.
 *
 * A heading inside a surface that has declared its own text colour should
 * inherit it. That is what .text-white means and the design system had been
 * ignoring it.
 * ------------------------------------------------------------------------ */

body.sh .text-white h1, body.sh .text-white h2, body.sh .text-white h3,
body.sh .text-white h4, body.sh .text-white h5, body.sh .text-white h6,
body.sh .box-inverse h1, body.sh .box-inverse h2, body.sh .box-inverse h3,
body.sh [class*="bg-"] > .text-white h2 {
  color: inherit;
}

body.sh h1.text-white, body.sh h2.text-white, body.sh h3.text-white,
body.sh h4.text-white, body.sh h5.text-white { color: #fff; }

/* --------------------------------------------------------------------------
 * 21. The theme's filled tiles
 *
 * Six tiles in bright cyan, teal, green, orange and pale grey, several of them
 * carrying white text. bg-secondary was #E4E6EF - white on near-white, which
 * is why the Caretakers tile read as disabled rather than as a count.
 *
 * Brought onto the palette, with white text only where white text passes.
 * ------------------------------------------------------------------------ */

body.sh .box.bg-primary, body.sh .box.bg-info {
  background: var(--sh-navy) !important; color: #fff;           /* 15.02:1 */
}
body.sh .box.bg-success {
  background: var(--sh-emerald) !important; color: #fff;        /*  7.81:1 */
}
body.sh .box.bg-warning {
  background: var(--sh-amber-wash) !important; color: var(--sh-amber);
  border: 1px solid #EFE0BF;                                    /*  6.37:1 */
}
body.sh .box.bg-danger {
  background: var(--sh-red) !important; color: #fff;
}
/* Was white on #E4E6EF. A count nobody can read is not a count. */
body.sh .box.bg-secondary {
  background: var(--sh-surface) !important; color: var(--sh-ink);
  border: 1px solid var(--sh-line);
}
body.sh .box.bg-secondary .text-white,
body.sh .box.bg-warning .text-white { color: inherit !important; }

body.sh .box[class*="bg-"] .box-body { padding: var(--sh-5) var(--sh-4); }
body.sh .box[class*="bg-"] h2 { font-family: var(--sh-serif); font-size: 28px;
                                font-variant-numeric: tabular-nums; }
body.sh .box[class*="bg-"] span { font-size: var(--sh-t-small); opacity: .92; }

/* Tile figures. These were <h2> elements, which put seven numbers into the
   document outline as if they were section headings and forced a skip to the
   real card titles beneath them. A count is a value, not a heading. */
body.sh .sh-tile__value {
  display: block;
  font-family: var(--sh-serif);
  font-size: 28px;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--sh-1);
}

/* --------------------------------------------------------------------------
 * 22. Marketing surfaces
 * ------------------------------------------------------------------------ */

/* The sticky social rail shipped at full brand saturation - Facebook blue,
   Twitter blue, LinkedIn blue, YouTube red, stacked against the hero. Four
   other companies' brand colours are the loudest thing on a page that is
   meant to be selling this one. Muted to the surface, with the platform
   colour returning on hover so they are still recognisable. */
body.sh .icon-bar-sticky .btn-social-icon {
  background: rgba(255, 255, 255, .10) !important;
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 0;
}
body.sh .icon-bar-sticky .btn-facebook:hover { background: #1877F2 !important; border-color: #1877F2; }
body.sh .icon-bar-sticky .btn-twitter:hover  { background: #1D9BF0 !important; border-color: #1D9BF0; }
body.sh .icon-bar-sticky .btn-linkedin:hover { background: #0A66C2 !important; border-color: #0A66C2; }
body.sh .icon-bar-sticky .btn-youtube:hover  { background: #C4302B !important; border-color: #C4302B; }

/* Hero actions. The filled button keeps the emerald; the outline one was a
   white pill and is now a hairline, which is the quieter half of a pair
   rather than a second primary. */
body.sh .hero-section .btn-primary {
  background: var(--sh-emerald) !important;
  border-color: var(--sh-emerald) !important;
  color: #fff !important;
  box-shadow: none !important;
}
body.sh .hero-section .btn-primary:hover {
  background: #0A4F42 !important; border-color: #0A4F42 !important;
}
body.sh .hero-section .btn-outline-light {
  border-color: rgba(255, 255, 255, .45) !important;
  color: #fff !important;
  background: transparent !important;
}
body.sh .hero-section .btn-outline-light:hover {
  background: rgba(255, 255, 255, .10) !important;
  border-color: #fff !important;
  color: #fff !important;
}

/* The brand mark in the marketing navbar rendered at about 24px wide, which
   is smaller than the menu text beside it. */
body.sh .main-nav .brand img,
body.sh .navbar-brand img { max-height: 40px; width: auto; }

/* Two brand marks, one visible at a time, keyed to the navbar's two
   backgrounds. Stacked rather than toggled with display so the swap does not
   reflow the navbar as it changes state. */
body.sh .sh-brandmark { height: 26px; width: auto; transition: opacity .2s ease; }
body.sh .sh-brandmark--dark  { position: absolute; opacity: 0; pointer-events: none; }
body.sh .main-nav.on-scroll .sh-brandmark--light { opacity: 0; }
body.sh .main-nav.on-scroll .sh-brandmark--dark  { opacity: 1; }
body.sh .brand.navbar-brand { position: relative; }

/* --------------------------------------------------------------------------
 * 23. Icons
 *
 * Drawn, at one stroke weight, rather than emoji. The product was using
 * U+26A0, U+2715, U+1F4E6 and U+2705 as its icon set, which renders as a
 * different picture on every platform - on Windows the warning triangle is
 * flat monochrome, on Apple it is a yellow 3D object - and reads aloud to a
 * screen reader as "warning sign" in the middle of a heading.
 * ------------------------------------------------------------------------ */

body.sh .sh-ico {
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
body.sh .sh-ico--sm { width: .875em; height: .875em; }

/* --------------------------------------------------------------------------
 * 24. Onboarding checklist
 *
 * There was no onboarding anywhere in this product - no code, no templates. A
 * new patient arrived at a dashboard of empty panels with nothing saying what
 * to do first, and a new clinician at one that does not mention their account
 * is waiting on an administrator.
 *
 * It disappears once every step is done rather than sitting there as a row of
 * ticks, because a checklist you have finished is furniture.
 * ------------------------------------------------------------------------ */

body.sh .sh-onboard {
  border: 1px solid var(--sh-line);
  border-radius: var(--sh-r-lg);
  background: var(--sh-surface);
  box-shadow: var(--sh-lift-1);
  margin-bottom: var(--sh-5);
  overflow: hidden;
}
body.sh .sh-onboard__head {
  padding: var(--sh-4) var(--sh-5);
  border-bottom: 1px solid var(--sh-line-soft);
  background: var(--sh-emerald-wash);
}
body.sh .sh-onboard__title {
  font-family: var(--sh-serif); font-size: var(--sh-t-section);
  font-weight: 600; margin: 0; color: var(--sh-ink);
}
body.sh .sh-onboard__sub { margin: var(--sh-1) 0 0; font-size: var(--sh-t-small);
                           color: var(--sh-ink-2); }
body.sh .sh-onboard__list { list-style: none; margin: 0; padding: 0; }

body.sh .sh-step {
  display: flex; align-items: flex-start; gap: var(--sh-3);
  padding: var(--sh-4) var(--sh-5);
  border-top: 1px solid var(--sh-line-soft);
}
body.sh .sh-step:first-child { border-top: 0; }

/* The marker is drawn, not a character: a tick glyph renders differently on
   every platform and reads aloud mid-sentence. */
body.sh .sh-step__mark {
  flex: none; width: 20px; height: 20px; margin-top: 1px;
  border-radius: 50%; border: 1.5px solid var(--sh-line);
  display: inline-flex; align-items: center; justify-content: center;
  color: transparent;
}
body.sh .sh-step.is-done .sh-step__mark {
  background: var(--sh-emerald); border-color: var(--sh-emerald); color: #fff;
}
body.sh .sh-step__mark svg { width: 12px; height: 12px; stroke: currentColor;
                             fill: none; stroke-width: 2.5;
                             stroke-linecap: round; stroke-linejoin: round; }

body.sh .sh-step__label { font-weight: 600; color: var(--sh-ink); }
body.sh .sh-step.is-done .sh-step__label { color: var(--sh-ink-2); font-weight: 500; }
body.sh .sh-step__hint  { display: block; margin-top: 2px;
                          font-size: var(--sh-t-small); color: var(--sh-ink-2); }
body.sh .sh-step__go    { margin-left: auto; flex: none; }

/* --------------------------------------------------------------------------
 * 25. The theme's remaining reds
 *
 * Found by sweeping every route with the probe rather than by opening the
 * pages I remembered. Three pairs, each just under AA:
 *
 *   #FF3F3F on white          3.48:1   "I want to delete my account"
 *   #E8133F on #FFF5F5        4.27:1   "Delete my account", on the pale wash
 *   white   on #EE3158        4.03:1   the alert banner on /get-started
 *
 * Red is the one colour in a clinical product that has to be readable - it is
 * what an alert, an erasure confirmation and a vital-sign warning are all
 * wearing. Each solved against the surface it actually sits on, hue and
 * saturation held.
 * ------------------------------------------------------------------------ */

body.sh .text-danger,
body.sh a.text-danger,
body.sh .sh-danger-text { color: #E50000 !important; }   /* 4.85 white / 4.53 wash */

/* Filled alerts and badges: darken the fill until white passes on it, rather
   than lightening the text, which is what makes a warning look decorative. */
body.sh .alert-danger,
body.sh .bg-danger:not(.btn-outline),
body.sh .badge-danger {
  background-color: #EA1340 !important;                  /* white on it 4.50:1 */
  color: #fff !important;
}
body.sh .alert-danger a, body.sh .alert-danger .close { color: #fff !important; }

/* The pale danger wash, so text on it has a known background. */
body.sh .bg-danger-light, body.sh .alert-light-danger {
  background-color: #FFF5F5 !important;
  color: #C2102F !important;                             /* 5.44:1 on the wash */
}

/* The emergency action's label. It was an <h4> in every sidebar, which put a
   level-4 entry into every page outline right after the h1 - a heading skip on
   every page in the product, from one line of markup repeated. It is a label
   on a button, so it is a span now and keeps the size it had. */
body.sh .sh-emergency-label {
  display: block;
  font-family: var(--sh-serif);
  font-size: var(--sh-t-section);
  font-weight: 600;
  line-height: 1.2;
}

/* Bootstrap's own outline variants are hyphenated - .btn-outline-danger - and
   are a different selector from the theme's .btn-outline.btn-danger pair. The
   erasure confirmation on /privacy/ used the Bootstrap one and kept #FF3F3F
   at 3.48:1: the least readable control on the page that permanently deletes
   a medical record. */
body.sh .btn-outline-danger {
  color: #D5123B !important;                /* 4.54:1 on white */
  border-color: currentColor !important;
  background-color: transparent !important;
}
body.sh .btn-outline-danger:hover,
body.sh .btn-outline-danger:focus {
  background-color: #EA1340 !important;     /* white on it 4.50:1 */
  color: #fff !important;
  border-color: #EA1340 !important;
}

/* Panels filled with the brand deep. Their text is white today because every
   string inside them carries .text-white, which means the next line of copy
   added without that class inherits body ink - #172b4c on #2f579a, 2.0:1.
   The surface should declare its own foreground rather than relying on every
   child to remember. */
body.sh [style*="--sh-brand-deep"],
body.sh [style*="#2f579a"] { color: #fff; }
body.sh [style*="--sh-brand-deep"] .text-muted,
body.sh [style*="#2f579a"] .text-muted { color: #DCE6F5 !important; }

/* --------------------------------------------------------------------------
 * 26. The theme's status text colours
 *
 * Found by sweeping as a patient rather than as a clinician: these live on
 * pages the doctor sweep never reached. All three are below AA on the
 * surfaces they actually sit on, and two are badly below:
 *
 *   .text-info     #00D0FF on white     1.83:1   section titles on /dynamic/
 *   .text-warning  #FFA800 on #FFF8EA   1.83:1   category links on /UseCase/
 *   .box-subtitle  #608ACF on white     3.48:1   "Fill correct information"
 *
 * Each solved against white, the warm paper and the sunk surface, hue and
 * saturation held, so one value is safe wherever the class is used.
 * ------------------------------------------------------------------------ */

body.sh .text-info,
body.sh a.text-info    { color: #007792 !important; }   /* 5.18 / 4.97 / 4.60 */
body.sh .text-warning,
body.sh a.text-warning { color: #976300 !important; }   /* 5.12 / 4.91 / 4.55 */
body.sh .box-subtitle  { color: #3A6DC1 !important; }   /* 5.08 / 4.87 / 4.51 */

/* The matching pale washes, so text on them has a background it was solved
   against rather than whatever the theme happened to paint. */
body.sh .bg-warning-light { background-color: #FFF8EA !important; }
body.sh .bg-info-light    { background-color: #E8F6FA !important; }
body.sh .bg-warning-light .text-warning,
body.sh .bg-warning-light a { color: #976300 !important; }
body.sh .bg-info-light .text-info,
body.sh .bg-info-light a    { color: #007792 !important; }

/* .box-title is a card heading and should look like one wherever it appears.
   It was h4 in 101 places, h1 in 8, h3 in 4 and h5 in 3 - the same component
   at four different levels, which is what produced heading skips across the
   product. Normalised to h2 in the markup; pinning the size here means that
   change is an outline fix and not a visual one. */
body.sh .box-title,
body.sh h1.box-title, body.sh h2.box-title,
body.sh h3.box-title, body.sh h4.box-title, body.sh h5.box-title {
  font-family: var(--sh-serif);
  font-size: var(--sh-t-section);
  font-weight: 600;
  color: var(--sh-ink);
  line-height: 1.25;
  margin: 0;
}

/* .text-success completes the set: it was 3.86:1 on .bg-success-light, which
   is the "Infants" and "Maternal" category links on /UseCase/. Same treatment
   as info and warning above - the deep green from the palette, and the wash
   pinned so the pair is known rather than inherited from the theme. */
body.sh .text-success,
body.sh a.text-success        { color: var(--sh-green) !important; }
body.sh .bg-success-light     { background-color: var(--sh-green-wash) !important; }
body.sh .bg-success-light .text-success,
body.sh .bg-success-light a   { color: #175535 !important; }

/* The profile widget's name and role. They were h4 and h6 sitting under the
   page h1, which is a two-level jump in the outline for what is a caption next
   to an avatar. Now spans, keeping the sizes they had. */
body.sh .widget-user-username { display: block; font-family: var(--sh-serif);
                                font-size: var(--sh-t-title); font-weight: 600;
                                line-height: 1.2; margin: 0; }
body.sh .widget-user-desc     { display: block; font-size: var(--sh-t-small);
                                opacity: .9; margin: 2px 0 0; }

/* --------------------------------------------------------------------------
 * 27. Badges
 *
 * The -light badge variants pair a saturated foreground with a pale wash of
 * the same hue, and the theme's pairs do not pass: #FFA800 on #FFF8EA is
 * 1.83:1, and the pending-approvals queue renders that badge once per row -
 * 97 contrast failures on one page, all the same two colours.
 *
 * A status badge is the one element on a queue whose entire job is to be read
 * at a glance. Each pair below uses the foreground already solved for that
 * wash in sections 25 and 26.
 * ------------------------------------------------------------------------ */

body.sh .badge-warning-light, body.sh .label-warning-light {
  background-color: #FFF8EA !important; color: #976300 !important;   /* 4.84:1 */
  border: 1px solid #F0E2C4;
}
body.sh .badge-success-light, body.sh .label-success-light {
  background-color: var(--sh-green-wash) !important; color: #175535 !important;  /* 7.93:1 */
  border: 1px solid #CDE3D8;
}
body.sh .badge-danger-light, body.sh .label-danger-light {
  background-color: #FFF5F5 !important; color: #C2102F !important;   /* 5.76:1 */
  border: 1px solid #EFCED1;
}
body.sh .badge-info-light, body.sh .label-info-light {
  background-color: #E8F6FA !important; color: #007792 !important;   /* 4.69:1 */
  border: 1px solid #C9E4EC;
}
body.sh .badge-primary-light, body.sh .label-primary-light {
  background-color: var(--sh-emerald-wash) !important; color: var(--sh-emerald) !important;
  border: 1px solid #D3E4DE;
}
body.sh .badge-secondary-light, body.sh .label-secondary-light {
  background-color: var(--sh-surface-sunk) !important; color: var(--sh-ink-2) !important;
  border: 1px solid var(--sh-line-soft);
}

/* Filled badges: white only where white passes on the fill. */
body.sh .badge-warning { background-color: #976300 !important; color: #fff !important; }
body.sh .badge-success { background-color: var(--sh-green) !important; color: #fff !important; }
body.sh .badge-danger  { background-color: #EA1340 !important; color: #fff !important; }
body.sh .badge-info    { background-color: #007792 !important; color: #fff !important; }
body.sh .badge-primary { background-color: var(--sh-emerald) !important; color: #fff !important; }

body.sh [class*="badge-"] { font-variant-numeric: tabular-nums; }

/* Doctor/patient card captions. The specialty line under a card's name was an
   h6 under an h3 under the page h1 - two skips per card, so a directory of
   thirteen doctors reported thirteen. It is a caption, so it is a <p> now and
   keeps the size it had. */
body.sh p.user-info { font-size: var(--sh-t-small); color: var(--sh-ink-2);
                      margin: 0; line-height: 1.35; }
body.sh h2.my-10    { font-size: var(--sh-t-section); }

/* --------------------------------------------------------------------------
 * 28. Django admin chrome
 *
 * Two pages in this product are standalone templates carrying Django's admin
 * stylesheet - the attribute editors behind /ExcelFormData/ and
 * /addAdminScreening/. Django's header blue #79AEC8 with its own breadcrumb
 * text #C4DCE8 measures 1.70:1, and the section link at #FFFFCC is 2.35:1.
 *
 * Darkening the header rather than lightening the text, so white passes on it
 * and the chrome still reads as the admin area.
 * ------------------------------------------------------------------------ */

body.sh #header,
body.sh .breadcrumbs,
body.sh div.breadcrumbs {
  background: #2E6F8E !important;                  /* white on it 5.13:1 */
  color: #fff !important;
}
body.sh #header a, body.sh #header a:link, body.sh #header a:visited,
body.sh .breadcrumbs a, body.sh div.breadcrumbs a {
  color: #fff !important;
  text-decoration: underline;
}
body.sh #branding h1, body.sh #branding h1 a { color: #fff !important; }
body.sh #user-tools, body.sh #user-tools a { color: #fff !important; }

/* Vital values that were <h5>. Keeping the size they had; they are data, and a
   number under a label is not a section of the document. */
body.sh span.mb-0 > strong,
body.sh span[id="weight"] > strong,
body.sh span[id="comment"] > strong { font-size: var(--sh-t-section); font-weight: 600; }

/* Django admin's module header link: #FFFFCC on #79AEC8, 2.35:1. The
   breadcrumb bar above it was already darkened; this is the same bar's
   sibling and needs the same treatment. */
body.sh a.section, body.sh .module h2 a, body.sh #content-main .section {
  color: #fff !important;
  text-decoration: underline;
}
body.sh #content-main > .module > h2,
body.sh .module caption, body.sh .module h2 {
  background: #2E6F8E !important; color: #fff !important;
}

/* Django admin's module captions carry the app label ("Categoryss") on the
   header blue at 4.20:1, and its base template emits a branding <h1> of its
   own alongside the page heading, so these two pages report two top-level
   headings. Both are Django's markup rather than this project's.
   The caption takes white on the darkened bar; the branding line becomes an
   h2-equivalent visually and is removed from the outline by the template. */
body.sh #content h2, body.sh .module > h2, body.sh table caption {
  background: #2E6F8E !important;
  color: #fff !important;
}
body.sh #content h2 a, body.sh .module > h2 a, body.sh table caption a {
  color: #fff !important;
}

/* --------------------------------------------------------------------------
 * 29. Loader failsafe
 *
 * The theme's #loader is a fixed white panel at z-index 999999, faded out by
 * template.js on DOMContentLoaded. DoctorBase supplies the shell's markup but
 * not its JavaScript - each child template loads its own bundle - so a page
 * that does not happen to include template.js renders correctly and then stays
 * invisible behind that panel, with nothing in the console to say why.
 *
 * This is the belt to that braces: after two seconds the loader stops being a
 * thing that can hide a page, whatever the script did or did not do. A
 * still-loading page showing its content is a far better failure than a
 * finished page showing nothing.
 * ------------------------------------------------------------------------ */

@keyframes sh-loader-failsafe {
  to { opacity: 0; visibility: hidden; }
}
body.sh #loader {
  animation: sh-loader-failsafe 0.3s ease 2s forwards;
}
@media (prefers-reduced-motion: reduce) {
  body.sh #loader { animation-duration: 0.01ms; }
}

/* ---------------------------------------------------------------------------
   30. Conversation list (patient chat)

   The chat page listed one hard-coded conversation and could only be reached
   by POST. It is a list now, and each entry is a form button rather than an
   anchor, because choosing a conversation is a POST.
   --------------------------------------------------------------------------- */

body.sh .sh-convo { margin: 0; }

body.sh .sh-convo__btn {
  display: flex;
  align-items: center;
  gap: var(--sh-3);
  width: 100%;
  padding: var(--sh-3) var(--sh-4);
  text-align: left;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--sh-line);
  cursor: pointer;
  transition: background 0.12s ease;
}

body.sh .sh-convo__btn:hover { background: var(--sh-surface-sunk); }
body.sh .sh-convo__btn:focus-visible {
  outline: 2px solid var(--sh-emerald);
  outline-offset: -2px;
}

/* The open conversation.

   This had a 3px emerald bar down the left edge - the side-tab accent that is
   the most recognisable tell of a generated interface, and the comment here
   claimed it was "a rule rather than a fill" while setting both.

   It also set the same background as :hover, so running the mouse down the
   list made every row look open. The background cannot carry the distinction
   anyway: --sh-emerald-wash and --sh-surface-sunk are 1.01:1 apart, which is
   no difference at all.

   So the surface says "active or hovered" and the name says which one is
   open - 6.93:1 on the sunk surface. The template pairs it with
   aria-current, because a colour on its own is not a state (WCAG 1.4.1). */
body.sh .sh-convo__btn--on { background: var(--sh-surface-sunk); }
body.sh .sh-convo__btn--on .sh-convo__name { color: var(--sh-emerald); }

body.sh .sh-convo__name {
  display: block;
  font-weight: 600;
  font-size: var(--sh-t-body);
  color: var(--sh-ink);
}

body.sh .sh-convo__meta {
  display: block;
  margin-top: 2px;
  font-size: var(--sh-t-micro);
  color: var(--sh-ink-3);
}
