/* ==========================================================================
   NephrOne — deep clinical green theme, horizontal navigation
   Colours are chosen for long shifts under fluorescent light: a dark, low-glare
   header and high-contrast text on white cards.
   ========================================================================== */

:root {
    --n-green-900: #11463c;
    --n-green-800: #1f7666;
    --n-green-700: #1d6e5f;
    --n-green-600: #258a76;
    --n-green-500: #34a58c;
    --n-accent:    #1f7666;
    --n-accent-soft: #e2f1ed;

    --n-bg: #f0f5f3;
    --n-border: #d6e3df;
    --n-ink: #17251f;
    --n-ink-soft: #5b6c65;

    --n-danger: #b02a37;
    --n-warning: #b8860b;
}

body {
    background: var(--n-bg);
    color: var(--n-ink);
    font-size: 0.925rem;
}

a { color: var(--n-green-700); }
a:hover { color: var(--n-green-600); }

/* ---------------------------------------------------------------- top bars */

.n-brandbar {
    /* Deliberately NOT green: the white plate separates identity from navigation,
       so the green bar below reads as "where am I" rather than decoration. */
    background: #ffffff;
    color: var(--n-ink);
    height: 3.25rem;
    padding: 0 1.25rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    border-bottom: 1px solid var(--n-border);
    /* Above the sticky nav, or the account menu drops behind it. */
    position: relative;
    z-index: 1040;
}

.n-brandbar .n-brand {
    display: flex;
    align-items: center;
    gap: .6rem;
    text-decoration: none;
    color: var(--n-green-900);
}

.n-brandbar .n-brand img {
    width: 2rem;
    height: 2rem;
    display: block;
    /* The mark is square and the file is square, but say so anyway: a logo squashed by half a
       pixel is the sort of thing nobody reports and everybody notices. */
    object-fit: contain;
}

/* The sign-in lockup. Sized by height so the aspect ratio is the file's business, not the
   stylesheet's. */
.n-login-logo {
    height: 5.5rem;
    width: auto;
    display: inline-block;
}

.n-brandbar .n-brand strong {
    font-size: 1.2rem;
    letter-spacing: .2px;
    line-height: 1.05;
    display: block;
    /* The wordmark as written — MedVel — in the brand green (Pantone 3288 C). */
    text-transform: none;
    color: var(--n-green-800);
}

.n-brandbar .n-brand span {
    font-size: .66rem;
    color: var(--n-ink-soft);
    letter-spacing: .06em;
    text-transform: uppercase;
    display: block;
}

.n-brandbar .n-facility {
    font-size: .82rem;
    color: var(--n-ink-soft);
    border-left: 1px solid var(--n-border);
    padding-left: 1rem;
}

/* Bootstrap puts the menu in the flex flow otherwise, which is what pushed the
   account menu on top of the page heading. */
.n-brandbar .dropdown-menu { z-index: 1050; }

/* The sticky head: impersonation banner, then navigation. Sticking as one block is what stops
   the two overlapping — see the note in _Layout.cshtml. */
.n-sticky-head {
    position: sticky;
    top: 0;
    z-index: 1030;
}

/* An anchor jumped to lands below the fixed head, not under it. */
html { scroll-padding-top: calc(var(--n-head-h, 6.5rem) + .5rem); }

.n-navbar {
    background: var(--n-green-700);
    border-bottom: 3px solid var(--n-green-600);
    padding: 0 .75rem;
    /* Not sticky itself: .n-sticky-head is. */
    position: relative;
}

.n-navbar .nav-link,
.n-navbar .dropdown-toggle {
    color: #d8ece1;
    font-size: .875rem;
    font-weight: 500;
    padding: .6rem .9rem;
    border-bottom: 3px solid transparent;
    margin-bottom: -3px;
    background: none;
    border-top: 0;
    border-left: 0;
    border-right: 0;
    border-radius: 0;
}

.n-navbar .nav-link:hover,
.n-navbar .dropdown-toggle:hover,
.n-navbar .show > .dropdown-toggle {
    color: #fff;
    background: rgba(255, 255, 255, .09);
}

.n-navbar .nav-link.active,
.n-navbar .dropdown-toggle.active {
    color: #fff;
    border-bottom-color: #7fd4ad;
    background: rgba(255, 255, 255, .07);
}

/* ------------------------------------------------------- masters mega menu */

.n-mega {
    width: min(1180px, calc(100vw - 2rem));
    padding: 1rem 1.15rem;
    border: 1px solid var(--n-border);
    border-radius: .35rem;
    box-shadow: 0 12px 32px rgba(14, 53, 39, .18);
    max-height: min(72vh, 640px);
    overflow-y: auto;
}

/* Eight sections of two or three lines each do not need the width sixty master tables need, and
   a 1180px panel hanging off a button in the middle of the bar looks like a mistake. */
.n-mega.n-mega-narrow { width: min(820px, calc(100vw - 2rem)); }

.n-mega .n-mega-grid {
    column-count: 4;
    column-gap: 1.5rem;
}

@media (max-width: 1200px) { .n-mega .n-mega-grid { column-count: 3; } }
@media (max-width: 900px)  { .n-mega .n-mega-grid { column-count: 2; } }
@media (max-width: 640px)  { .n-mega .n-mega-grid { column-count: 1; } }

.n-mega .n-mega-group {
    break-inside: avoid;
    margin-bottom: 1rem;
}

.n-mega .n-mega-title {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--n-green-600);
    font-weight: 700;
    padding-bottom: .25rem;
    margin-bottom: .3rem;
    border-bottom: 1px solid var(--n-border);
}

.n-mega a {
    display: block;
    padding: .2rem .35rem;
    font-size: .83rem;
    color: var(--n-ink);
    text-decoration: none;
    border-radius: .2rem;
}

.n-mega a:hover { background: var(--n-accent-soft); color: var(--n-green-800); }
.n-mega a.active { background: var(--n-accent-soft); color: var(--n-green-800); font-weight: 600; }


/* ------------------------------------------------------- clinical notes

   The forms the ward runs on. Two contexts share one set of rules: the editor, where the doctor
   types into the form, and the read view, where somebody reads it back — including on paper. They
   have to look the same, or the note the doctor signed is not the note that prints. */

.n-note-day {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--n-green-600);
    font-weight: 700;
    margin-top: .6rem;
}

.n-note-day:first-child { margin-top: 0; }

.n-note { border-left: 3px solid transparent; }

/* An unsigned draft is marked on the left edge rather than with a background wash. A wash makes
   the text harder to read, and a draft is the one somebody is still working on. */
.n-note-draft { border-left-color: #c58a00; }
.n-note-void { border-left-color: #a52a2a; opacity: .75; }

.n-note-heading {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    background: none;
    border: 0;
    padding: 0;
    text-align: left;
    font-weight: 600;
    color: var(--n-ink);
    font-size: .95rem;
}

.n-note-heading:hover { color: var(--n-green-800); }
.n-note-caret { font-size: .75rem; color: var(--n-green-600); }

.n-note-body { border-top: 1px solid var(--n-border); padding-top: .6rem; }

/* The note itself. */
.n-note-text { font-size: .9rem; line-height: 1.5; }
.n-note-text > *:first-child { margin-top: 0; }
.n-note-text > *:last-child { margin-bottom: 0; }
.n-note-text p { margin: 0 0 .5rem; }
.n-note-text ul, .n-note-text ol { margin: 0 0 .5rem; padding-left: 1.3rem; }

.n-note-text h3, .n-note-text h4, .n-note-text h5 {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--n-green-600);
    font-weight: 700;
    margin: .85rem 0 .3rem;
}

/* The tables the forms are made of.

   Ruled, because that is what makes a form read as a form: a handover with no lines is a list of
   phrases and a reader cannot tell the prompt from the answer. The prompt column is shaded and
   holds its width; the answer column takes the rest. */
.n-note-text table {
    width: 100%;
    border-collapse: collapse;
    margin: 0 0 .6rem;
    font-size: .87rem;
}

.n-note-text th, .n-note-text td {
    border: 1px solid var(--n-border);
    padding: .3rem .45rem;
    vertical-align: top;
}

.n-note-text th {
    background: var(--n-accent-soft);
    font-weight: 600;
    text-align: left;
    width: 38%;
}

/* A framework letter in the first column — the I S B A R of a handover. Narrow and centred,
   because it is a label for the rows beside it and not a heading of its own. */
.n-note-text th:first-child:not(:only-of-type) { width: 2.2rem; text-align: center; }

.n-note-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    margin-top: .8rem;
    padding-top: .4rem;
    border-top: 1px solid var(--n-border);
    font-size: .78rem;
    color: #555;
}

/* The note being corrected, shown above the empty box. */
.n-note-original { border-left: 3px solid var(--n-green-600); background: var(--n-accent-soft); }

/* ---- the editor ---- */

.n-editor-tools {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .15rem;
    background: var(--n-accent-soft);
}

.n-editor-surface {
    min-height: 22rem;
    outline: 0;
    padding: .2rem;
}

.n-editor-surface:focus { box-shadow: inset 0 0 0 2px var(--n-accent-soft); }

/* An empty cell has no height of its own, so a freshly opened form draws as a row of lines with
   nowhere to click. */
.n-editor-surface td:empty { min-height: 1.4rem; }
.n-editor-surface td { min-width: 4rem; }

/* Which cell the caret is in. A form is filled top to bottom and without this the doctor loses
   their place every time they look away. */
.n-editor-surface td:focus-within,
.n-editor-surface td:hover { background: #fffdf3; }

@media print {
    /* The note prints with its rules. Tables break across pages badly and a form split mid-row is
       a form where the prompt is on one sheet and the answer on the next. */
    .n-note-text table { page-break-inside: auto; }
    .n-note-text tr { page-break-inside: avoid; }
    .n-note-text th { background: #f4f4f4 !important; -webkit-print-color-adjust: exact; }
    .n-note-text h3, .n-note-text h4, .n-note-text h5 { page-break-after: avoid; }
    .n-note-foot { page-break-inside: avoid; }
}


/* ------------------------------------------------------- the patient panel

   A rail down the left with the standing facts, and the work beside it. The shape of the paper
   file: the front sheet stays open on the desk while somebody writes on a different page. */

.n-panel {
    display: grid;
    grid-template-columns: 17rem minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

/* The rail sticks, because it is only worth having if it is still there when the reader has
   scrolled to the bottom of a long list. Its own scrollbar for the tall case, so the page's
   scroll position and the rail's are independent. */
.n-rail {
    position: sticky;
    top: calc(var(--n-head-h, 6.5rem) + .5rem);
    max-height: calc(100vh - var(--n-head-h, 6.5rem) - 1.5rem);
    overflow-y: auto;
    background: #fff;
    border: 1px solid var(--n-border);
    border-radius: .35rem;
    font-size: .82rem;
}

.n-rail-name {
    background: #fcd34d;
    color: #3f2d00;
    font-weight: 700;
    font-size: .95rem;
    padding: .4rem .6rem;
    text-transform: uppercase;
    letter-spacing: .02em;
}

.n-rail-dead {
    display: block;
    font-size: .7rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    color: #7a1a1a;
}

.n-rail-who { display: flex; gap: .55rem; padding: .6rem; }

.n-rail-photo {
    width: 3.4rem;
    height: 4.2rem;
    object-fit: cover;
    border: 1px solid var(--n-border);
    border-radius: .2rem;
    background: var(--n-accent-soft);
    flex: 0 0 auto;
}

.n-rail-photo-none {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
    color: var(--n-green-600);
}

.n-rail-uhid { font-weight: 700; font-size: .9rem; }
.n-rail-dob, .n-rail-age { color: #555; font-size: .76rem; }

.n-rail-chips { display: flex; flex-wrap: wrap; gap: .25rem; padding: 0 .6rem .5rem; }

.n-rail-chip {
    font-size: .68rem;
    font-weight: 700;
    padding: .1rem .4rem;
    border-radius: .2rem;
    background: var(--n-accent-soft);
    color: var(--n-green-800);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.n-rail-chip-episode { background: var(--n-green-800); color: #fff; }
.n-rail-chip-alert { background: #fde2e2; color: #a52a2a; }
.n-rail-chip-vip { background: #fff3cd; color: #7a5a00; }

/* The facts. A definition list because that is what they are, laid out as two columns so the
   labels form a readable left edge — eleven rows of "Label: value" on one line each is a column
   of ragged text nobody scans. */
.n-rail-facts {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: .1rem .5rem;
    margin: 0;
    padding: .5rem .6rem;
    border-top: 1px solid var(--n-border);
}

.n-rail-facts dt {
    font-weight: 400;
    color: #666;
    font-size: .72rem;
    white-space: nowrap;
    display: flex;
    align-items: center;
    gap: .3rem;
}

.n-rail-facts dt i { color: var(--n-green-600); }
.n-rail-facts dd { margin: 0; font-size: .78rem; overflow-wrap: anywhere; }

.n-rail-section { border-top: 1px solid var(--n-border); }

.n-rail-section > summary {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .4rem .6rem;
    cursor: pointer;
    font-weight: 600;
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--n-green-800);
    list-style: none;
}

.n-rail-section > summary::-webkit-details-marker { display: none; }

.n-rail-section > summary::before {
    content: "\203A";
    color: var(--n-green-600);
    font-weight: 700;
    transition: transform .12s;
}

.n-rail-section[open] > summary::before { transform: rotate(90deg); }
.n-rail-section > *:not(summary) { padding: 0 .6rem .55rem; }

.n-rail-when { font-weight: 400; text-transform: none; letter-spacing: 0; color: #777; }

.n-rail-count {
    margin-left: auto;
    background: var(--n-accent-soft);
    color: var(--n-green-800);
    border-radius: 1rem;
    padding: 0 .35rem;
    font-size: .7rem;
}

.n-rail-count-alert { background: #fde2e2; color: #a52a2a; }

/* Plus signs that are only obvious when wanted. A rail with five bright buttons on it reads as a
   toolbar, and the rail is not where the work happens. */
.n-rail-add { margin-left: .3rem; color: var(--n-green-600); opacity: .45; }
.n-rail-section > summary:hover .n-rail-add, .n-rail-add:hover { opacity: 1; }
.n-rail-count + .n-rail-add { margin-left: .3rem; }

.n-rail-vitals {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: .05rem .5rem;
    margin: 0;
}

.n-rail-vitals dt { font-weight: 400; color: #666; font-size: .74rem; white-space: nowrap; }
.n-rail-vitals dd { margin: 0; font-size: .78rem; font-weight: 600; }

.n-rail-list { list-style: none; margin: 0; padding: 0; }
.n-rail-list li { padding: .15rem 0; border-bottom: 1px dotted var(--n-border); font-size: .78rem; }
.n-rail-list li:last-child { border-bottom: 0; }
.n-rail-list li.is-critical { color: #a52a2a; font-weight: 600; }

.n-rail-foot {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    padding: .5rem .6rem;
    border-top: 1px solid var(--n-border);
    background: var(--n-accent-soft);
    font-size: .76rem;
}

/* ---- the work beside it ---- */

.n-panel-work { min-width: 0; }

.n-panel-tabs {
    display: flex;
    align-items: center;
    gap: .15rem;
    border-bottom: 2px solid var(--n-border);
    margin-bottom: .75rem;
    flex-wrap: wrap;
}

.n-panel-tabs > a {
    padding: .4rem .8rem;
    font-size: .85rem;
    font-weight: 600;
    color: #555;
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
}

.n-panel-tabs > a:hover { color: var(--n-green-800); }

.n-panel-tabs > a.is-on {
    color: var(--n-green-800);
    border-bottom-color: var(--n-green-800);
    background: var(--n-accent-soft);
}

/* Two columns of small grids: what was decided on the left, what is outstanding on the right. */
.n-panel-grids {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .75rem;
    align-items: start;
}

.n-panel-grids > div { display: flex; flex-direction: column; gap: .75rem; min-width: 0; }

.n-pg {
    border: 1px solid var(--n-border);
    border-radius: .3rem;
    background: #fff;
    overflow: hidden;
}

.n-pg > h2 {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    font-weight: 700;
    color: var(--n-green-800);
    background: var(--n-accent-soft);
    margin: 0;
    padding: .35rem .6rem;
    border-bottom: 1px solid var(--n-border);
}

.n-pg-add { margin-left: auto; font-size: .72rem; font-weight: 400; text-transform: none; letter-spacing: 0; }
.n-pg > p { margin: 0; padding: .6rem; }
.n-pg .table { font-size: .8rem; margin: 0; }
.n-pg .table th { font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; color: #555; }
.n-pg .table > :not(caption) > * > * { padding: .3rem .5rem; }
.n-pg .field-help { font-size: .72rem; }
.n-pg > .field-help, .n-pg > div > .field-help { padding: 0 .6rem .4rem; }

@media (max-width: 1400px) {
    .n-panel-grids { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 991.98px) {
    /* On a telephone the rail goes above the work rather than beside it, and stops sticking —
       a sticky rail on a short screen leaves no room for the thing it is beside. */
    .n-panel { grid-template-columns: minmax(0, 1fr); }
    .n-rail { position: static; max-height: none; }
    .n-rail-facts { grid-template-columns: repeat(2, auto minmax(0, 1fr)); }
}


/* ------------------------------------------------------- the day's counters

   Five tiles across the top of the doctor's day. Each carries a total and the two or three
   sub-counts that are the actual question — a total on its own is a number a consultant already
   knew. */

.n-tiles {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: .6rem;
    margin-bottom: 1rem;
}

.n-tile {
    border: 1px solid var(--n-border);
    border-left: 3px solid var(--n-green-600);
    border-radius: .3rem;
    background: #fff;
    padding: .5rem .65rem;
    min-width: 0;
}

/* Drawn faint rather than hidden. A missing tile reads as a broken screen; a faint one reads as
   a quiet day, which is what it is. */
.n-tile.is-empty { opacity: .55; border-left-color: var(--n-border); }

.n-tile-appointment { border-left-color: #6f5bd1; }
.n-tile-outpatient { border-left-color: #c0559a; }
.n-tile-inpatient { border-left-color: var(--n-green-600); }
.n-tile-investigation { border-left-color: #2f7fb5; }
.n-tile-surgery { border-left-color: #c26a3a; }

/* Deep teal, and chosen rather than picked. The five above are all mid-tone and already sit close
   together once colour vision is anything but typical — outpatient and surgery are all but
   identical to a tritan eye. A sixth mid-tone hue would have landed on top of one of them, so this
   one is separated by lightness as well as hue: it clears the normal-vision floor against every
   other tile, its nearest neighbour being inpatient green. None of it is load-bearing — each tile
   carries its own icon and its own word, so the colour reinforces the identity and never carries
   it. */
.n-tile-video { border-left-color: #164e63; }

.n-tile-head { display: flex; align-items: baseline; gap: .4rem; }
.n-tile-head > i { color: #888; font-size: .85rem; }
.n-tile-total { font-size: 1.5rem; font-weight: 700; line-height: 1; color: var(--n-ink); }

.n-tile-label {
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    font-weight: 600;
    color: #555;
    text-decoration: none;
}

a.n-tile-label:hover { color: var(--n-green-800); text-decoration: underline; }

.n-tile-parts {
    display: flex;
    flex-wrap: wrap;
    gap: .1rem .7rem;
    margin-top: .3rem;
    font-size: .72rem;
    color: #666;
}

.n-tile-part b { color: var(--n-ink); font-weight: 700; }
.n-tile-part a { color: inherit; text-decoration: none; }
.n-tile-part a:hover { text-decoration: underline; }
.n-tile-part.is-urgent, .n-tile-part.is-urgent b { color: #a52a2a; }

@media (max-width: 1200px) { .n-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 700px) { .n-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* The one patient list. Tighter than a default table because eleven columns of clinical detail
   at default padding is a table that scrolls sideways on a consulting-room screen. */
.n-worklist { font-size: .82rem; }
.n-worklist th { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: #555; }
.n-worklist > :not(caption) > * > * { padding: .3rem .45rem; }
.n-worklist-filters th { padding: .2rem .25rem !important; }
.n-worklist-filters input { font-size: .72rem; }


/* The counter's search grid. Eleven columns of a patient's standing at a default table's padding
   is a grid that scrolls sideways on the counter's own screen, which is usually the smallest in
   the building. */
.n-counter-grid { font-size: .82rem; }
.n-counter-grid th { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: #555; }
.n-counter-grid > :not(caption) > * > * { padding: .35rem .5rem; }

/* ---------------------------------------------------------------- content */

.n-content { padding: 1.25rem; }

.n-pagehead {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: .75rem;
    margin-bottom: 1rem;
}

.n-pagehead h1 { font-size: 1.15rem; margin: 0 0 .15rem; color: var(--n-green-900); }
.n-pagehead p { margin: 0; max-width: 78ch; }

/* ---------------------------------------------------------------- widgets */

.card { border: 1px solid var(--n-border); box-shadow: 0 1px 2px rgba(14, 53, 39, .05); }
.card-header {
    background: #fff;
    border-bottom: 1px solid var(--n-border);
    font-weight: 600;
    color: var(--n-green-900);
}

.stat-tile {
    background: #fff;
    border: 1px solid var(--n-border);
    border-radius: .4rem;
    padding: .85rem 1rem;
    border-left: 3px solid var(--n-green-600);
}
.stat-tile .value { font-size: 1.6rem; font-weight: 600; color: var(--n-green-800); line-height: 1.1; }
.stat-tile .label { font-size: .74rem; color: var(--n-ink-soft); text-transform: uppercase; letter-spacing: .05em; }
.stat-tile i { color: var(--n-green-600); }

.table { font-size: .875rem; }
.table > thead { background: #e8f0ec; }
.table > thead th {
    font-weight: 600;
    color: var(--n-green-900);
    border-bottom: 1px solid var(--n-border);
    white-space: nowrap;
}
.table td { vertical-align: middle; }
.table-hover > tbody > tr:hover > * { background-color: var(--n-accent-soft); }

.badge-system { background: #e4ebe8; color: #4c5f57; font-weight: 500; }

.btn-primary,
.btn-primary:disabled {
    background: var(--n-green-700);
    border-color: var(--n-green-700);
}
.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
    background: var(--n-green-800) !important;
    border-color: var(--n-green-800) !important;
}
.btn-outline-primary { color: var(--n-green-700); border-color: var(--n-green-700); }
.btn-outline-primary:hover { background: var(--n-green-700); border-color: var(--n-green-700); }

.form-label { font-weight: 500; font-size: .84rem; margin-bottom: .2rem; color: #33453d; }
.form-control:focus, .form-select:focus {
    border-color: var(--n-green-500);
    box-shadow: 0 0 0 .2rem rgba(47, 158, 117, .18);
}
.form-text { font-size: .78rem; }
.required::after { content: " *"; color: var(--n-danger); }
.field-help { font-size: .78rem; color: var(--n-ink-soft); }

.htmx-indicator { display: none; }
.htmx-request .htmx-indicator { display: inline-block; }

.section-title {
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--n-green-600);
    font-weight: 700;
    border-bottom: 1px solid var(--n-border);
    padding-bottom: .3rem;
    margin: 1.1rem 0 .75rem;
}
.section-title:first-child { margin-top: 0; }

/* ------------------------------------------------------------ patient banner */

.n-banner {
    background: #fff;
    border: 1px solid var(--n-border);
    border-left: 4px solid var(--n-green-600);
    border-radius: .4rem;
    padding: .85rem 1.1rem;
    margin-bottom: 1rem;
}
.n-banner .n-banner-name { font-size: 1.1rem; font-weight: 600; color: var(--n-green-900); }
.n-banner .n-uhid {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .82rem;
    background: var(--n-accent-soft);
    color: var(--n-green-800);
    padding: .1rem .4rem;
    border-radius: .2rem;
}
.n-banner dl { margin: 0; }
.n-banner dt { font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; color: var(--n-ink-soft); font-weight: 600; }
.n-banner dd { margin: 0 0 .4rem; font-size: .875rem; }

.n-chip {
    display: inline-block;
    font-size: .74rem;
    padding: .12rem .5rem;
    border-radius: 1rem;
    border: 1px solid var(--n-border);
    background: #fff;
    color: var(--n-ink-soft);
}
.n-chip.n-chip-alert { border-color: #f0c2c6; background: #fdf0f1; color: var(--n-danger); }
.n-chip.n-chip-info  { border-color: #b9dfd2; background: var(--n-accent-soft); color: var(--n-green-800); }
.n-chip.n-chip-warn  { border-color: #f0dcae; background: #fdf7e6; color: var(--n-warning); }
/* Used by the medical-records screens since they were written, and never defined — a document
   marked "checked" has been drawing as a plain grey chip, which is the one state that wanted to
   look settled. */
.n-chip.n-chip-good  { border-color: #b9ddc9; background: var(--n-accent-soft); color: var(--n-green-700); }

.n-dup {
    border: 1px solid #f0dcae;
    background: #fdf7e6;
    border-radius: .35rem;
    padding: .6rem .8rem;
    font-size: .85rem;
}

/* ---------------------------------------------------------------- login */

.login-shell {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(140deg, var(--n-green-900) 0%, var(--n-green-700) 60%, var(--n-accent) 140%);
    padding: 1rem;
}
.login-card { width: 100%; max-width: 400px; }

/* --------------------------------------------------------------- modals */

/*
 * Bootstrap's .modal-dialog-scrollable makes .modal-body scroll, but only when .modal-body is a
 * direct child of .modal-content. Every editor here wraps header/body/footer in a <form>, which
 * breaks that chain and makes tall forms unreachable below the fold. Re-establishing the flex
 * column on the form restores it for every modal in the app at once.
 */
.modal-dialog-scrollable .modal-content > form {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    max-height: 100%;
}

.modal-dialog-scrollable .modal-content > form > .modal-body {
    overflow-y: auto;
    min-height: 0;
}

.modal-content > form > .modal-header,
.modal-content > form > .modal-footer { flex-shrink: 0; }

.modal-header {
    background: #f4f8f6;
    border-bottom: 1px solid var(--n-border);
    padding: .7rem 1rem;
}
.modal-header .modal-title { font-size: 1rem; font-weight: 600; color: var(--n-green-900); }
.modal-footer { background: #f4f8f6; border-top: 1px solid var(--n-border); padding: .6rem 1rem; }
.modal-body { padding: 1rem; }

/* Long editors get a visible scroll affordance rather than a silently clipped form. */
.modal-body::-webkit-scrollbar { width: 10px; }
.modal-body::-webkit-scrollbar-thumb { background: #cbd8d2; border-radius: 5px; }
.modal-body::-webkit-scrollbar-track { background: transparent; }

/* ------------------------------------------------------------- patient card */

.n-card-sheet { display: flex; justify-content: center; }

.n-card {
    width: 640px;
    background: #fff;
    border: 1px solid var(--n-border);
    border-radius: .5rem;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(14, 53, 39, .08);
}

.n-card-header {
    background: var(--n-green-800);
    color: #fff;
    padding: .7rem 1rem;
    text-align: center;
}
.n-card-hospital { font-size: 1.05rem; font-weight: 700; letter-spacing: .2px; }
.n-card-hospital-meta { font-size: .72rem; color: #bcd9ca; margin-top: .1rem; }
.n-card-hospital-meta span { margin-right: .25rem; }

.n-card-body { display: flex; gap: 1rem; padding: 1rem; align-items: flex-start; }

.n-card-photo { flex: 0 0 96px; }
.n-card-photo img {
    width: 96px; height: 116px; object-fit: cover;
    border: 1px solid var(--n-border); border-radius: .25rem;
}
.n-card-photo-empty {
    width: 96px; height: 116px;
    border: 1px dashed var(--n-border); border-radius: .25rem;
    display: flex; align-items: center; justify-content: center;
    color: #9db0a7; font-size: 2rem; background: #f6f9f7;
}

.n-card-details { flex: 1 1 auto; min-width: 0; }
.n-card-name { font-size: 1.1rem; font-weight: 700; color: var(--n-green-900); line-height: 1.2; }
.n-card-uhid {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .9rem; color: var(--n-green-700); font-weight: 600; margin-bottom: .4rem;
}

.n-card-table { width: 100%; font-size: .78rem; border-collapse: collapse; }
.n-card-table th {
    text-align: left; font-weight: 600; color: var(--n-ink-soft);
    padding: .12rem .5rem .12rem 0; white-space: nowrap; width: 1%;
    text-transform: uppercase; font-size: .66rem; letter-spacing: .03em;
}
.n-card-table td { padding: .12rem 1rem .12rem 0; }

.n-card-clinical { margin-top: .45rem; display: flex; flex-wrap: wrap; gap: .25rem; }
.n-card-tag {
    font-size: .68rem; padding: .1rem .45rem; border-radius: 1rem;
    background: var(--n-accent-soft); color: var(--n-green-800); border: 1px solid #b9dfd2;
}
.n-card-tag-alert { background: #fdf0f1; color: var(--n-danger); border-color: #f0c2c6; }

.n-card-qr { flex: 0 0 108px; text-align: center; }
.n-card-qr svg { display: block; }
.n-card-qr-label {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .6rem; color: var(--n-ink-soft); margin-top: .2rem; word-break: break-all;
}

.n-card-footer {
    border-top: 1px solid var(--n-border);
    padding: .5rem 1rem;
    font-size: .7rem;
    color: var(--n-ink-soft);
    text-align: center;
    background: #f6f9f7;
}

@media print {
    /* Print the card and nothing else — no navigation, no buttons, no page chrome.
     *
     * `.alert` used to be in this list flat, and this file loads after Bootstrap, so an alert
     * marked `d-print-block` was hidden anyway — two `!important` rules of equal weight and the
     * later one wins. The one alert in the application that is marked that way is the "Unsigned
     * draft" warning on a radiology report, so an unsigned draft printed came out looking exactly
     * like the department's signed report. Whoever asks to be printed stays printed. */
    .n-brandbar, .n-navbar, .n-sticky-head, .d-print-none { display: none !important; }
    .alert:not(.d-print-block):not(.d-print-inline):not(.d-print-inline-block) { display: none !important; }
    body { background: #fff; }
    .n-content { padding: 0; }
    .n-card { border: 1px solid #999; box-shadow: none; width: 100%; max-width: 640px; }
    .n-card-header { background: #1f7666 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .n-card-footer { background: #fff !important; }

    /* The one @page rule in the application. `@page` cannot be scoped to a class, so a second one
       added for the radiology report changed the margins of every gate pass and day book in the
       building — and the two disagreed about the top margin, which cost twelve millimetres of
       every sheet and pushed the signature off the end of a report that fitted. A4 stated
       explicitly because every printer in an Indian hospital is loaded with it and a document
       that lays out for Letter wastes a centimetre down one side. */
    @page { size: A4; margin: 12mm; }
}

/* ------------------------------------------------------------------ scheduling
   Slot buttons carry two numbers (the time and how full the slot is), so they
   need a fixed width or the picker reflows every time a booking lands. */
.n-slot {
    min-width: 5.6rem;
    padding: .2rem .35rem;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

.n-slot .n-slot-count {
    display: block;
    font-size: .68rem;
    opacity: .75;
}

.n-slot-full {
    text-decoration: line-through;
    opacity: .55;
    pointer-events: none;
}

/* The queue board is read at a distance from a waiting-room screen. */
.n-queue-now {
    background: var(--n-green-900);
    color: #fff;
    border-radius: .6rem;
    padding: 1.25rem 1.5rem;
    text-align: center;
}

.n-queue-token {
    font-size: 3.6rem;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.n-queue-late {
    color: #b42318;
    font-weight: 600;
}

/* ------------------------------------------------------------------ footer */

.n-footer {
    margin-top: 2rem;
    padding: .85rem 1.25rem;
    border-top: 1px solid var(--n-border);
    background: #fff;
    color: var(--n-ink-soft);
    font-size: .76rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem 1.25rem;
}

.n-footer a { color: var(--n-green-700); text-decoration: none; }
.n-footer a:hover { text-decoration: underline; }
.n-footer .n-footer-sep { color: var(--n-border); }

/* The page body must be able to push the footer down on short screens. */
body { display: flex; flex-direction: column; min-height: 100vh; }
body > .n-sticky-head { flex-shrink: 0; }
body > main { flex: 1 0 auto; }
body > .n-footer { flex-shrink: 0; }

@media print {
    .n-brandbar, .n-navbar, .n-sticky-head, .n-footer { display: none !important; }
}

/* ------------------------------------------------------------------ dialysis
   The unit board is read two ways: at a desk while placing patients, and from
   across the room on a wall screen. Same markup, one modifier class. */
.n-chair-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: .6rem;
}

.n-chair-grid-lg {
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: .9rem;
}

.n-chair {
    border: 1px solid var(--n-border);
    border-radius: .5rem;
    padding: .5rem .6rem;
    background: #fff;
    min-height: 6.5rem;
    display: flex;
    flex-direction: column;
    position: relative;
}

.n-chair-grid-lg .n-chair { min-height: 9rem; padding: .75rem .9rem; }

.n-chair-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--n-ink-soft);
    margin-bottom: .25rem;
}

.n-chair-grid-lg .n-chair-head { font-size: .85rem; }

.n-chair-name { font-weight: 700; }

.n-chair-tag {
    background: var(--n-danger);
    color: #fff;
    border-radius: .2rem;
    padding: 0 .25rem;
    font-size: .62rem;
    letter-spacing: .08em;
}

.n-chair-body { display: block; text-decoration: none; color: inherit; flex: 1; }
.n-chair-body:hover { color: inherit; }

.n-chair-patient { font-weight: 600; font-size: .84rem; line-height: 1.2; }
.n-chair-grid-lg .n-chair-patient { font-size: 1.15rem; }

.n-chair-uhid { font-size: .68rem; color: var(--n-ink-soft); font-variant-numeric: tabular-nums; }
.n-chair-grid-lg .n-chair-uhid { font-size: .9rem; }

.n-chair-vitals {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    font-size: .72rem;
    margin-top: .3rem;
    font-variant-numeric: tabular-nums;
}

.n-chair-grid-lg .n-chair-vitals { font-size: 1rem; gap: .8rem; margin-top: .5rem; }

.n-chair-empty {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--n-ink-soft);
    font-size: .8rem;
}

.n-chair-alert { font-size: .68rem; color: var(--n-danger); font-weight: 700; margin-top: .2rem; }
.n-chair-grid-lg .n-chair-alert { font-size: .85rem; }

.n-chair-book {
    font-size: .7rem;
    text-decoration: none;
    color: var(--n-green-600);
    margin-top: .3rem;
}

/* State is carried on the left edge so it reads at a glance without relying on
   colour alone — the border width changes too. */
.n-chair-free    { border-style: dashed; }
.n-chair-booked  { border-left: 4px solid var(--n-green-500); }
.n-chair-running { border-left: 4px solid var(--n-accent); background: var(--n-accent-soft); }
.n-chair-done    { border-left: 4px solid var(--n-border); opacity: .8; }
.n-chair-breach  { border: 2px solid var(--n-danger); background: #fdf0f1; }
.n-chair-iso .n-chair-name::after { content: ""; }

.n-monitor .n-chair { background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .2); }

/* ---------------------------------------------------------------- ward board
   Beds reuse the chair tile: same grid, same reading distance, different states.
   A nurse who has learned one board has learned both. */
.n-chair-occupied  { border-left: 4px solid var(--n-green-500); }
.n-chair-discharge { border-left: 4px solid var(--n-accent); background: var(--n-accent-soft); }
.n-chair-cleaning  { border-left: 4px solid #b8860b; background: #fdf8e8; }
.n-chair-blocked   { border-style: dashed; opacity: .65; }
/* Held for a family. Deliberately unlike both neighbours: not the solid green of an occupied
   bed, because nobody is being treated in it and a nurse must not go looking; not the dashed
   edge of a free one, because somebody is sleeping in it. */
.n-chair-attender  { border-left: 4px dashed var(--n-green-500); background: var(--n-surface-2, #eef2f0); }

.n-bed-flags { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .3rem; }
.n-bed-flag {
    font-size: .62rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    border-radius: .2rem;
    padding: 0 .25rem;
    background: var(--n-surface-2, #eef2f0);
    color: var(--n-ink-soft);
    border: 1px solid var(--n-border);
}
.n-chair-grid-lg .n-bed-flag { font-size: .8rem; padding: .05rem .4rem; }
.n-bed-flag-due   { background: #e8f1ff; color: #14509c; border-color: #b9d3f5; }
.n-bed-flag-order { background: #fff3e0; color: #8a4b00; border-color: #f3d3a8; }
.n-bed-flag-dues  { background: #fdeaea; color: #a01722; border-color: #f2c3c6; }
.n-bed-flag-seen  { background: #e9f7ef; color: #1b6b43; border-color: #bde3cd; }

.n-bed-actions { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .35rem; }
.n-bed-actions .btn { --bs-btn-padding-y: .05rem; --bs-btn-padding-x: .3rem;
                      --bs-btn-font-size: .68rem; }

/* ------------------------------------------------------------ match summary
   The screen a transplant decision is made in front of. Severity is carried by a
   left border and a label, never by colour alone — a red-green colourblind
   nephrologist has to read this as reliably as anybody else. */
.n-finding {
    border: 1px solid var(--n-border);
    border-left-width: 5px;
    border-radius: .4rem;
    padding: .6rem .8rem;
    margin-bottom: .5rem;
    background: #fff;
}
.n-finding-label {
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    font-weight: 700;
    display: inline-block;
    margin-bottom: .15rem;
}
.n-finding-text { font-weight: 600; font-size: .92rem; line-height: 1.35; }
.n-finding-detail { font-size: .8rem; color: var(--n-ink-soft); margin-top: .2rem; }

.n-finding-contraindication { border-left-color: var(--n-danger); background: #fdf0f1; }
.n-finding-contraindication .n-finding-label { color: var(--n-danger); }
.n-finding-caution { border-left-color: #b8860b; background: #fdf8e8; }
.n-finding-caution .n-finding-label { color: #8a6100; }
.n-finding-incomplete { border-left-color: #6c757d; background: #f5f6f7; }
.n-finding-incomplete .n-finding-label { color: #5a6169; }
.n-finding-good { border-left-color: var(--n-green-500); background: #eef8f2; }
.n-finding-good .n-finding-label { color: #1b6b43; }
.n-finding-info { border-left-color: var(--n-border); }
.n-finding-info .n-finding-label { color: var(--n-ink-soft); }

.n-mismatch-badge {
    display: inline-block;
    min-width: 2.4rem;
    text-align: center;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    border-radius: .3rem;
    padding: .05rem .4rem;
    border: 1px solid var(--n-border);
}
.n-mismatch-0 { background: #eef8f2; border-color: #bde3cd; color: #1b6b43; }
.n-mismatch-1 { background: #f4faf6; border-color: #cfe6da; }
.n-mismatch-2 { background: #fdf8e8; border-color: #eedfae; color: #8a6100; }
.n-mismatch-unknown { background: #f5f6f7; color: var(--n-ink-soft); font-style: italic;
                      font-weight: 500; }

.n-mfi { font-variant-numeric: tabular-nums; font-weight: 600; }
.n-mfi-strong { color: var(--n-danger); }
.n-mfi-moderate { color: #8a6100; }


/* ------------------------------------------------------------------ impersonation
   Deliberately loud. An administrator signed in as somebody else must never be in any
   doubt about it, so this sits above the content, spans the full width and uses a colour
   that appears nowhere else in the application. */
.n-impersonation-bar {
    /* Positioned by .n-sticky-head. It used to stick on its own at the same top and the same
       z-index as the navigation, which is what put it on top of the menus. */
    position: relative;
    background: #7c2d12;
    color: #fff;
    padding: .5rem 1.25rem;
    font-size: .875rem;
    border-bottom: 3px solid #f97316;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
}

.n-impersonation-bar .btn-light {
    --bs-btn-color: #7c2d12;
}

@media print {
    /* A printed prescription or discharge summary must not carry this stripe across it. The
       record itself already names both people. */
    .n-impersonation-bar,
    .n-sticky-head { display: none !important; }
}

/* --------------------------------------------------------------------- type-ahead
   Services and medicines run past two hundred entries. A native dropdown of that length
   is a scroll, not a choice. */
.n-typeahead { position: relative; }

.n-typeahead-list {
    position: absolute;
    z-index: 1050;
    left: 0;
    right: 0;
    max-height: 16rem;
    overflow-y: auto;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--bs-border-color, #ced4da);
    border-radius: .375rem;
    box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .15);
    margin-top: .125rem;
}

.n-typeahead-item {
    padding: .375rem .625rem;
    font-size: .875rem;
    cursor: pointer;
    border-bottom: 1px solid var(--bs-border-color-translucent, #0000001a);
}

.n-typeahead-item:last-child { border-bottom: 0; }

/* One highlight for both the mouse and the arrow keys, so the two never disagree about
   which row is about to be taken. */
.n-typeahead-item:hover,
.n-typeahead-item.is-active {
    background: var(--bs-primary-bg-subtle, #cfe2ff);
    color: var(--bs-emphasis-color, #000);
}

.n-typeahead-item[aria-disabled="true"] {
    opacity: .55;
    cursor: not-allowed;
}

/* Shown for information, not for choosing. It must not light up under the mouse, or it looks
   like it is about to be taken. */
.n-typeahead-item[aria-disabled="true"]:hover {
    background: transparent;
    color: inherit;
}

.n-typeahead-empty {
    padding: .5rem .625rem;
    font-size: .8125rem;
    color: var(--bs-secondary-color, #6c757d);
}

/* The second line of a result: what is on the shelf, when the batch expires. It is why the
   pharmacist picks one entry over another, so it sits under the name rather than beside it. */
.n-typeahead-text { display: block; }

.n-typeahead-hint {
    display: block;
    font-size: .75rem;
    color: var(--bs-secondary-color, #6c757d);
}

/* An entry that cannot be taken says so in the colour of a refusal, not in grey — grey reads as
   "not loaded yet", and the pharmacist tries again instead of raising an indent. */
.n-typeahead-item[aria-disabled="true"] .n-typeahead-hint {
    color: var(--bs-danger-text-emphasis, #b02a37);
}

/* A row that behaves like a link should look like one under the cursor. Without this the
   click works and nobody discovers it. */
.n-row-link { cursor: pointer; }

/* ------------------------------------------------------- keyboard-first counter

   A pharmacy window billing three hundred times a day. The keys have to be readable without
   being loud: a pharmacist glances at the bar once on their first morning and then never
   looks at it again. */

.n-key-hint {
    display: inline-block;
    font-size: .6875rem;
    font-weight: 600;
    line-height: 1;
    padding: .15rem .3rem;
    border: 1px solid var(--bs-border-color, #ced4da);
    border-bottom-width: 2px;
    border-radius: .2rem;
    color: var(--bs-secondary-color, #6c757d);
    background: var(--bs-tertiary-bg, #f8f9fa);
    vertical-align: middle;
}

/* The row where all the typing happens. Lifted off the page so the eye returns to it after
   every line without having to search.

   It is also a Bootstrap .row, whose negative margins (the gutter) pulled the box up into the
   fields above it and out past their left edge - the UHID box sat on its border. A framed row
   keeps its own margins: clear space above and below, and its edges in line with the fields. */
.n-entrybar {
    margin: 1rem 0 1rem 0 !important;
    padding: .75rem .625rem .875rem;
    border: 1px solid var(--bs-border-color-translucent, #0000001a);
    border-left: 3px solid var(--bs-primary, #0d6efd);
    border-radius: .375rem;
    background: var(--bs-tertiary-bg, #f8f9fa);
}

.n-keybar {
    position: sticky;
    bottom: 0;
    z-index: 1020;
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1.25rem;
    margin-top: .75rem;
    padding: .4rem .75rem;
    font-size: .75rem;
    color: var(--bs-secondary-color, #6c757d);
    background: var(--bs-tertiary-bg, #f8f9fa);
    border-top: 1px solid var(--bs-border-color, #ced4da);
}

.n-keybar b {
    color: var(--bs-emphasis-color, #000);
    font-weight: 600;
}

/* Numbered lines. At a counter the pharmacist reads a line number out loud to the patient
   more often than they read the drug name. */
.n-issue-table tbody tr td:first-child { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ records */

/* A scanned page is read, not glanced at, so the viewer gets the height of the
   window rather than a fixed box — and scrolls inside itself so the page
   furniture stays put while somebody works through a folder. */
.n-mrd-image {
    max-height: calc(100vh - 16rem);
    object-fit: contain;
}

.n-mrd-frame {
    width: 100%;
    height: calc(100vh - 16rem);
    min-height: 24rem;
    border: 0;
    background: #fff;
}

.n-scan-video {
    width: 100%;
    max-height: 26rem;
    background: #000;
    border-radius: .375rem;
}

.n-scan-pages {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.n-scan-page {
    position: relative;
    width: 5rem;
}

.n-scan-page img {
    width: 100%;
    border: 1px solid var(--bs-border-color);
    border-radius: .25rem;
}

.n-scan-page-no {
    position: absolute;
    left: .2rem;
    bottom: .2rem;
    background: rgba(0, 0, 0, .65);
    color: #fff;
    font-size: .7rem;
    line-height: 1;
    padding: .15rem .3rem;
    border-radius: .2rem;
}

.n-scan-drop {
    position: absolute;
    top: -.4rem;
    right: -.4rem;
    padding: 0 .3rem;
    line-height: 1.1;
}

/* A consultant's format can ask for a section to start a new sheet — a discharge prescription
   the pharmacy keeps, or a set of instructions the patient is meant to pin up. Only on paper:
   on screen a page break is meaningless and hiding the section behind one would be worse. */
@media print {
    .n-page-break {
        break-before: page;
        page-break-before: always;
    }
}


/* ==========================================================================
   Letterhead — the top of everything that reaches paper.

   Left mark | name, address, telephone, website, e-mail | right mark, a rule, then
   the document's own caption. Screen-hidden by the partial's d-none d-print-block;
   the sizes below are print sizes and are stated in millimetres where a printer
   cares about them.
   ========================================================================== */

.n-letterhead { margin-bottom: 4mm; }

.n-lh-row { display: flex; align-items: center; gap: 6mm; }

/* Both marks reserve their box whether or not there is a logo in it. Collapsing the
   empty one would centre the name against the remaining logo instead of against the
   page, and a hospital with one mark would print every sheet slightly off-centre. */
.n-lh-mark { flex: 0 0 18mm; width: 18mm; height: 18mm; }
.n-lh-mark img { max-width: 100%; max-height: 18mm; object-fit: contain; display: block; }

.n-lh-who { flex: 1 1 auto; text-align: center; }
.n-lh-name { font-size: 15pt; font-weight: 700; color: #1f7666; letter-spacing: .2px; }
.n-lh-address { font-size: 8pt; color: #3c4a44; margin-top: .6mm; }
.n-lh-contact { font-size: 7.5pt; color: #5b6c65; margin-top: .4mm; }
.n-lh-sep { color: #b8c6c0; margin: 0 2mm; }

.n-lh-rule { border: 0; border-top: 1.2pt solid #1f7666; margin: 2mm 0 1mm; }

.n-lh-caption { display: flex; justify-content: space-between; align-items: flex-end; }
.n-lh-title { font-size: 10.5pt; font-weight: 700; letter-spacing: .5px;
              text-transform: uppercase; }
.n-lh-sub { font-size: 8pt; color: #5b6c65; }
.n-lh-when { font-size: 7.5pt; color: #7b8b84; }

@media print {
    /* The letterhead repeats on every page of a long register. Without this, page four of
       a fifty-page trial balance is a sheet of numbers with no hospital on it — which is
       exactly the sheet that gets pulled out of the file on its own. */
    .n-letterhead { break-inside: avoid; }

    /* Printers drop background colours by default and the rule under the letterhead is the
       one piece of colour that has to survive. */
    .n-lh-rule { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* The upload screen's preview draws the same letterhead on screen, so what somebody
   approves is what prints. */
.n-lh-preview { background: #fff; border: 1px solid var(--n-border); border-radius: 4px;
                padding: 6mm 8mm; }
.n-lh-preview .n-letterhead { display: block !important; margin-bottom: 0; }


/* ==========================================================================
   The image viewer.

   Black, because everything else is: a chest film on a white page reads a stop
   darker than it is, and a radiologist comparing it with the same film on a
   workstation will say so.
   ========================================================================== */

.n-img-viewport { width: 100%; height: 62vh; min-height: 320px; background: #000;
                  display: block; object-fit: contain; }

.n-img-message { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
                 color: #e8f1ec; background: rgba(0, 0, 0, .72); border-radius: 4px;
                 padding: .5rem .9rem; font-size: .82rem; max-width: 80%; text-align: center; }
.n-img-message[hidden] { display: none !important; }

.n-img-overlay { position: absolute; top: .4rem; left: .6rem; color: #b8d8c9;
                 font-size: .72rem; pointer-events: none; text-shadow: 0 1px 2px #000; }

/* The series list is a scan list, and a scan list is read by running down it. Fixed height with
   its own scrollbar so the viewer beside it does not move as the list grows. */
.n-img-list { max-height: 68vh; overflow-y: auto; }

.n-img-item { display: flex; align-items: center; justify-content: space-between; }
.n-img-item-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The theatre recorder: a live preview, and a red dot that means it really is writing. */
.n-rec-preview { width: 100%; max-height: 46vh; background: #000; border-radius: 4px;
                 display: block; }

.n-rec-dot { display: inline-block; width: .6rem; height: .6rem; border-radius: 50%;
             background: #c0392b; margin-right: .35rem; }
.n-rec-live .n-rec-dot { animation: n-rec-pulse 1.4s ease-in-out infinite; }

@keyframes n-rec-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }


/* ==========================================================================
   Capturing and marking up.
   ========================================================================== */

/* The strip of grabbed stills. Newest first, scrolling in its own box so the camera
   beside it does not jump down the page every time somebody presses the pedal. */
.n-cap-strip { display: flex; flex-wrap: wrap; gap: .35rem; max-height: 62vh;
               overflow-y: auto; }

.n-cap-thumb { display: block; width: 5.4rem; height: 4rem; border-radius: 3px;
               overflow: hidden; background: #000; border: 1px solid var(--n-border); }
.n-cap-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.n-cap-thumb:hover { border-color: var(--n-green-700); }

/* The mark-up canvas is the picture's own size and is scaled down to fit. Height is
   capped so a tall radiograph does not push the toolbar off the screen. */
.n-annotate-canvas { max-width: 100%; max-height: 74vh; touch-action: none;
                     cursor: crosshair; display: inline-block; }

/* The colour swatches on the mark-up toolbar are the letter itself, coloured. */
[data-colour].active { outline: 2px solid var(--n-green-700); outline-offset: -2px; }
[data-tool].active   { background: var(--n-accent-soft); }

/* Pictures printed on a report: two to a row, never split across a page break. */
@media print {
    .n-report-images { display: grid; grid-template-columns: 1fr 1fr; gap: 4mm;
                       margin-top: 3mm; }
    .n-report-images figure { break-inside: avoid; margin: 0; }
    .n-report-images img { width: 100%; max-height: 72mm; object-fit: contain;
                           border: .4pt solid #999; }
    .n-report-images figcaption { font-size: 7.5pt; color: #555; margin-top: .8mm; }
}

.n-report-images { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem;
                   margin-top: .75rem; }
.n-report-images figure { margin: 0; }
.n-report-images img { width: 100%; max-height: 260px; object-fit: contain;
                       background: #000; border-radius: 3px; }
.n-report-images figcaption { font-size: .74rem; color: var(--n-muted); margin-top: .2rem; }

/* Said on the report when a key image is a DICOM instance, which no browser can draw. Printed
   as well as shown on screen: the person who needs to act on it is holding the paper. */
.n-report-note { font-size: .78rem; color: var(--n-muted); margin-top: .6rem;
                 padding: .4rem .6rem; border-left: 3px solid var(--n-accent);
                 background: var(--n-accent-soft); }

@media print {
    .n-report-note { font-size: 7.5pt; border-left: .8pt solid #666; background: none;
                     padding: 1mm 2mm; margin-top: 2mm; }
}

/* ---------------------------------------------------------------- wide master grids

   The Actions column, pinned to the right edge.

   A master with fifteen columns in its grid — the medicine master has that many — is wider than
   a laptop screen, so the row's Edit button sits off the end of a horizontal scroller most people
   never notice is there. It was reported as "there is no edit option in the medicine master",
   which is exactly what it looks like.

   Pinned rather than the columns trimmed, because the next wide master would do it again. */
.table > thead > tr > th.n-actions-col,
.table > tbody > tr > td.n-actions-col {
    position: sticky;
    right: 0;
    z-index: 2;
    background-color: var(--bs-body-bg, #fff);
    /* A hairline so the pinned column reads as pinned rather than as text overlapping text when
       the table is scrolled under it. */
    box-shadow: -0.5rem 0 0.5rem -0.5rem rgba(0, 0, 0, .18);
}

/* Striped and highlighted rows paint their own background, and a transparent sticky cell would
   let the scrolling columns show through it. */
.table > tbody > tr.table-secondary > td.n-actions-col {
    background-color: var(--bs-table-bg, #e9ecef);
}

@media print {
    /* Nothing is scrolling on paper, and a shadow prints as a grey smear. */
    .table > thead > tr > th.n-actions-col,
    .table > tbody > tr > td.n-actions-col {
        position: static;
        box-shadow: none;
    }
}

/* ---------------------------------------------------------------- the master editor

   Headings inside the editor dialog. A master with twenty-five fields — the medicine master —
   is a wall of boxes without them; with them it is four short groups, each of which fits in the
   reader's head at once. */
.n-editor-section {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-top: .75rem;
}

/* The rule that runs on past the words, so a section reads as a divider and not as a stray
   label belonging to the field under it. */
.n-editor-section::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background-color: var(--bs-border-color, #dee2e6);
}

.n-editor-section > span {
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color, #6c757d);
    white-space: nowrap;
}

/* The first heading sits at the top of its group and needs no space above it. */
.n-editor-section:first-of-type {
    margin-top: 0;
}

/* A tick box, lined up with the text boxes beside it rather than nudged down by a fixed margin
   that only ever looked right on one row. */
/* A tick box on a two-column editor row.
 *
 * Every other field is a label with a box under it, so it starts 2rem down the cell — a
 * label's line (1.5rem) plus its margin (.5rem). A tick box has no label above it and so
 * starts at the very top, half a field higher than the box beside it. Pushed down by that
 * 2rem, plus .4rem to land on the middle of the box rather than its top edge, less the
 * .25em Bootstrap already puts above the tick itself.
 *
 * Do NOT make this a flex container. `.form-check` positions the tick with a negative
 * margin inside its own left padding, and flex takes that layout away: in column direction
 * the tick stacks ON TOP of its own label, which is what this rule did until it was looked
 * at in a browser. */
.n-editor-check {
    padding-top: calc(1.5rem + .5rem + .4rem - .25em);
    min-height: calc(1.5em + .75rem + 2px + 1.5rem);
}

/* ==========================================================================================
   Tablet and telephone.

   Measured before any of this was written, across thirty-three screens at six viewport sizes
   from a 390px telephone to a 13-inch tablet: nothing overflowed horizontally anywhere, which
   is the failure that breaks a layout outright. Two things did fail.

   The navigation was desktop-shaped. Thirty-three top-level menus in a wrapping row took 216px
   on a 10-inch tablet in landscape, 296px on an 8-inch in portrait and 577px on a telephone —
   thirty-nine per cent of the screen before a single row of content. There was no hamburger and
   no collapse anywhere in the layout.

   And the controls were desktop-sized: between thirty-five and forty-one per cent of every
   button, input, checkbox and select was under 32px tall, which is the -sm sizing that makes a
   billing counter dense and a tablet frustrating.

   Of the eleven media queries in this file before today, eight were @media print and the other
   three set mega-menu column counts. Everything below is the screen half of the job.
   ========================================================================================== */

/* ---- the menu button. Only exists below the breakpoint; d-lg-none hides it above. ---- */
.n-navtoggle {
    background: none;
    border: 1px solid var(--n-border);
    border-radius: .375rem;
    color: var(--n-green-900);
    /* 44px, because it is the first thing a thumb reaches for. */
    min-width: 44px;
    min-height: 44px;
    font-size: 1.35rem;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-right: .25rem;
}

.n-navtoggle:focus-visible { outline: 2px solid var(--n-green-600); outline-offset: 2px; }

.n-navbackdrop {
    position: fixed;
    inset: 0;
    background: rgba(6, 28, 21, .45);
    z-index: 1035;
}

/* The menu button and the backdrop exist only where the panel does — same condition, stated
   once here and once on the panel below, because a button that opens nothing is worse than no
   button. */
.n-navtoggle, .n-navbackdrop { display: none; }

/* ---- WHEN the bar becomes a panel.
   Width OR pointer, not width alone. An eight-inch tablet in landscape is 1024px wide and a
   13-inch in portrait is 1024px too — both are tablets, and a width-only breakpoint of 992px
   leaves exactly the devices this was built for on the desktop side of it. Measured: those three
   viewports got WORSE on the first attempt, because the touch sizing made each of the six
   wrapped nav rows taller while the width rule declined to collapse them.
   A mouse-driven desktop keeps the bar it was designed with. ---- */
@media (max-width: 991.98px), (pointer: coarse) {
    .n-navtoggle { display: inline-flex; }
    body.n-navopen .n-navbackdrop { display: block; }
}

@media (max-width: 991.98px), (pointer: coarse) {
    /* ---- the menu becomes a panel, not a wall of wrapped rows ---- */
    .n-navbar { padding: 0; }

    .n-navbar .n-navitems {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        width: min(20rem, 86vw);
        background: var(--n-green-700);
        z-index: 1040;
        /* Column, not a wrapping row: thirty-three menus read as a list. */
        flex-direction: column;
        align-items: stretch !important;
        flex-wrap: nowrap !important;
        /* Its own scroller, so a long menu scrolls and the page behind it does not. */
        overflow-y: auto;
        overscroll-behavior: contain;
        padding: .5rem 0 1.5rem;
        transform: translateX(-100%);
        transition: transform .18s ease-out;
    }

    /* The shadow only while open. Parked off-screen, its 2rem blur still fell across the left
       edge of every page as a grey smear down the side of a phone. */
    body.n-navopen .n-navbar .n-navitems { transform: translateX(0); box-shadow: 0 0 2rem rgba(0, 0, 0, .35); }
    body.n-navopen { overflow: hidden; }

    .n-navbar .n-navitems > .nav-item,
    .n-navbar .n-navitems > .nav-link,
    .n-navbar .n-navitems > form { width: 100%; }

    .n-navbar .nav-link,
    .n-navbar .dropdown-toggle {
        width: 100%;
        text-align: left;
        /* 44px minimum, and the active marker moves to the left edge because a bottom border on
           a full-width row reads as a divider rather than as "you are here". */
        min-height: 44px;
        padding: .7rem 1rem;
        border-bottom: 0;
        border-left: 3px solid transparent;
        margin-bottom: 0;
        display: flex;
        align-items: center;
    }

    .n-navbar .nav-link.active,
    .n-navbar .dropdown-toggle.active { border-left-color: #fff; border-bottom: 0; }

    /* A submenu opens in place. Absolutely positioned it would hang outside the panel and be
       unreachable. */
    .n-navbar .dropdown-menu {
        position: static !important;
        transform: none !important;
        float: none;
        width: 100%;
        margin: 0;
        border: 0;
        border-radius: 0;
        background: rgba(0, 0, 0, .22);
        padding: .25rem 0;
    }

    .n-navbar .dropdown-menu .dropdown-item {
        color: #e6f2ec;
        min-height: 44px;
        display: flex;
        align-items: center;
        padding: .55rem 1rem .55rem 2rem;
        white-space: normal;
    }

    .n-navbar .dropdown-menu .dropdown-item:hover,
    .n-navbar .dropdown-menu .dropdown-item:focus {
        background: rgba(255, 255, 255, .12);
        color: #fff;
    }

    .n-navbar .dropdown-menu .dropdown-header { color: #a9cfbe; padding-left: 1rem; }
    .n-navbar .dropdown-menu .dropdown-divider { border-top-color: rgba(255, 255, 255, .18); }

    /* The mega menu's columns collapse to one inside a 20rem panel. */
    .n-navbar .n-mega .n-mega-grid { column-count: 1 !important; }

    /* And the panel itself has to give up its desktop width, or a 1180px grid sits inside a 20rem
       drawer and the whole menu scrolls sideways. */
    .n-navbar .n-mega,
    .n-navbar .n-mega.n-mega-narrow { width: auto; max-height: none; }

    /* A mega menu's links are plain <a>, not .dropdown-item, so every text colour set for this
       panel above misses them — and this panel is dark. Master data has been listing sixty tables
       in near-black ink on dark green on every telephone since the mega menu was written; nobody
       reported it because nobody could read it well enough to know what they were missing. */
    .n-navbar .n-mega .n-mega-title {
        color: #a9cfbe;
        border-bottom-color: rgba(255, 255, 255, .18);
    }

    .n-navbar .n-mega a {
        color: #e6f2ec;
        min-height: 44px;
        display: flex;
        align-items: center;
        padding: .45rem .5rem;
    }

    .n-navbar .n-mega a:hover,
    .n-navbar .n-mega a:focus,
    .n-navbar .n-mega a.active {
        background: rgba(255, 255, 255, .12);
        color: #fff;
    }

    /* ---- the brand bar. It wrapped mid-word on a telephone: the hospital name and the edition
       badge both sat in a 390px row with the logo and the account menu. ---- */
    .n-brandbar {
        height: auto;
        min-height: 3.25rem;
        padding: .35rem .75rem;
        gap: .5rem;
        flex-wrap: nowrap;
    }

    .n-brandbar .n-brand strong { font-size: 1.05rem; }
    .n-brandbar .n-brand span { display: none; }
    .n-brandbar .n-facility {
        max-width: 9rem;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

@media (max-width: 575.98px) {
    /* On a telephone the facility name and the edition badge are the first things to go: the
       account menu and the menu button are what somebody actually reaches for. */
    .n-brandbar .n-facility { display: none; }
    .n-brandbar .n-brand strong { font-size: .95rem; }
}

/* ==========================================================================================
   Touch. Keyed on the pointer, not on the width: a 1366px tablet is a touch device and a 1024px
   desktop window is not, and sizing by width gets both of them wrong.

   Deliberately scoped so the desktop register keeps the density it was designed with — nobody at
   a billing counter loses a row.
   ========================================================================================== */
@media (pointer: coarse) {
    .btn, .btn-sm,
    .form-control, .form-control-sm,
    .form-select, .form-select-sm,
    .input-group-sm > .form-control,
    .input-group-sm > .form-select,
    .input-group-sm > .btn {
        min-height: 44px;
    }

    .btn, .btn-sm { padding-top: .5rem; padding-bottom: .5rem; }

    /* A tick box you can actually hit, and a label you can hit instead of it. */
    .form-check-input { width: 1.25rem; height: 1.25rem; margin-top: .15rem; }
    .form-check { min-height: 44px; display: flex; align-items: center; }
    .form-check-label { padding-left: .25rem; min-height: 1.5rem; }

    /* Table rows: the link inside the cell is the target, so give it the height rather than
       padding every cell and losing half the rows on screen. */
    .table td a, .table th a { display: inline-block; padding: .35rem 0; }
    .table-sm > :not(caption) > * > * { padding: .5rem .5rem; }

    /* Dropdown items in the account and menu bars. */
    .dropdown-item { min-height: 44px; display: flex; align-items: center; }

    /* A date input on a tablet gets a real tap target for its picker. */
    input[type="date"], input[type="datetime-local"], input[type="time"] { min-height: 44px; }
}

/* ==========================================================================================
   CHINTU — the assistant button and drawer.

   The drawer deliberately mirrors the navigation drawer above it: same backdrop colour, same
   .18s ease-out slide, same "fixed, full height, translateX off screen" shape. Two panels that
   slide differently on one screen read as two products.

   It comes from the RIGHT, where the nav comes from the left, so that a tablet user with both
   open has not lost the thing they were reading — and so the two can never be confused.
   ========================================================================================== */

.n-chintu-btn {
    position: fixed;
    /* Above the footer, clear of a tablet's bottom-edge gesture area. */
    right: 1rem;
    bottom: 1rem;
    width: 56px;
    height: 56px;
    padding: 0;
    border: 1px solid var(--n-border);
    border-radius: 50%;
    background: #ffffff;
    box-shadow: 0 3px 10px rgba(6, 28, 21, .18);
    overflow: hidden;
    display: grid;
    place-items: center;
    /* Under Bootstrap's modal (1055) and its backdrop (1050), over the nav drawer's backdrop
       (1035). A help button that floats on top of a dialog is a help button in the way. */
    z-index: 1040;
}

.n-chintu-btn img {
    width: 52px;
    height: 52px;
    display: block;
}

.n-chintu-btn:hover { box-shadow: 0 5px 14px rgba(6, 28, 21, .26); }
.n-chintu-btn:focus-visible { outline: 2px solid var(--n-green-600); outline-offset: 3px; }

.n-chintu-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(6, 28, 21, .45);
    z-index: 1041;
}

.n-chintu {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(22rem, 92vw);
    background: #ffffff;
    border-left: 1px solid var(--n-border);
    box-shadow: -6px 0 20px rgba(6, 28, 21, .16);
    z-index: 1042;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    transform: translateX(100%);
    transition: transform .18s ease-out;
}

.n-chintu-backdrop { display: none; }
body.n-chintuopen .n-chintu-backdrop { display: block; }
body.n-chintuopen .n-chintu { transform: translateX(0); }

/* Closed is closed: a drawer parked off-screen still takes tab stops and still gets read out,
   so it is taken out of the page rather than just moved. */
.n-chintu[aria-hidden="true"] { visibility: hidden; }
body.n-chintuopen .n-chintu { visibility: visible; }

.n-chintu-head {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .7rem .8rem;
    background: var(--n-green-800);
    color: #ffffff;
    position: sticky;
    top: 0;
    z-index: 1;
}

.n-chintu-head img {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #ffffff;
    flex: 0 0 auto;
}

.n-chintu-head strong { font-size: 1rem; }
.n-chintu-who { font-size: .76rem; opacity: .85; }

.n-chintu-body { padding: .8rem; }
.n-chintu-loading { padding: 1.2rem; color: var(--n-ink-soft); }

.n-chintu-section { margin-top: 1.1rem; }

.n-chintu-section h3 {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--n-ink-soft);
    margin: 0 0 .45rem;
}

.n-chintu-note {
    font-size: .82rem;
    color: var(--n-ink-soft);
}

.n-chintu-work,
.n-chintu-hits {
    list-style: none;
    margin: 0;
    padding: 0;
}

.n-chintu-work > li,
.n-chintu-hits > li { margin-bottom: .3rem; }

.n-chintu-work a,
.n-chintu-hits a {
    display: flex;
    align-items: center;
    gap: .55rem;
    padding: .5rem .6rem;
    border: 1px solid var(--n-border);
    border-radius: .375rem;
    text-decoration: none;
    color: var(--n-ink);
    background: #ffffff;
    /* A drawer is reached by thumb more often than by mouse. */
    min-height: 44px;
}

.n-chintu-work a:hover,
.n-chintu-hits a:hover {
    background: var(--n-accent-soft);
    border-color: var(--n-green-500);
}

.n-chintu-work small,
.n-chintu-hits small {
    display: block;
    font-size: .72rem;
    color: var(--n-ink-soft);
}

.n-chintu-work span { line-height: 1.25; }
.n-chintu-hits > li a > span:first-child { font-size: .88rem; }

.n-chintu-count {
    flex: 0 0 auto;
    min-width: 1.9rem;
    padding: .1rem .35rem;
    border-radius: .3rem;
    background: var(--n-green-700);
    color: #ffffff;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    text-align: center;
}

/* The first row is the one whose delay is measured in a patient, so it is the one row allowed to
   shout. Driven by position rather than by a flag, because the catalogue is ordered by urgency
   and a second way of saying which row matters would be a second thing to keep in step. */
.n-chintu-work > li:first-child .n-chintu-count { background: var(--n-danger); }

@media print {
    .n-chintu-btn,
    .n-chintu,
    .n-chintu-backdrop { display: none !important; }
}

/* Department chips in the Chintu panel. They run the same search typing the name would, so they
   are one tap instead of eight letters rather than a second way of navigating. */
.n-chintu-chips { display: flex; flex-wrap: wrap; gap: .3rem; }

.n-chintu-chip {
    border: 1px solid var(--n-border);
    background: #ffffff;
    border-radius: 999px;
    padding: .3rem .65rem;
    font-size: .78rem;
    color: var(--n-ink);
    /* Smaller than the 44px rule on purpose: these are a dense secondary list, spaced so a thumb
       does not hit two of them, and every one of them is also reachable by typing. */
    min-height: 32px;
}

.n-chintu-chip:hover { background: var(--n-accent-soft); border-color: var(--n-green-500); }
.n-chintu-chip:focus-visible { outline: 2px solid var(--n-green-600); outline-offset: 2px; }

/* ---- Chintu's greeting, and the "how do I" answers ---- */

.n-chintu-greeting {
    font-size: .9rem;
    line-height: 1.35;
    margin: 0 0 .25rem;
    color: var(--n-ink);
}

.n-chintu-cando {
    font-size: .76rem;
    color: var(--n-ink-soft);
    margin: 0 0 .6rem;
}

.n-chintu-subhead {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--n-ink-soft);
    margin: .9rem 0 .35rem;
}

.n-chintu-answer {
    border: 1px solid var(--n-green-500);
    border-radius: .375rem;
    padding: .55rem .6rem;
    margin-top: .75rem;
    background: var(--n-accent-soft);
}

.n-chintu-answer-head {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    font-size: .86rem;
    margin-bottom: .35rem;
}

.n-chintu-watch {
    margin-left: auto;
    flex: 0 0 auto;
    font-size: .76rem;
    text-decoration: none;
    white-space: nowrap;
}

.n-chintu-steps {
    margin: 0;
    padding-left: 1.15rem;
    font-size: .82rem;
}

.n-chintu-steps > li { margin-bottom: .3rem; }
.n-chintu-steps a { text-decoration: none; }
.n-chintu-steps a:hover { text-decoration: underline; }

.n-chintu-steps small {
    display: block;
    font-size: .7rem;
    color: var(--n-ink-soft);
}

/* A step somebody else does. Dimmed, not hidden: a nurse told discharge is three steps has been
   taught the wrong process. */
.n-chintu-theirs { color: var(--n-ink-soft); }

.n-chintu-answer-note {
    font-size: .76rem;
    color: var(--n-green-900);
    margin: .45rem 0 0;
}

.n-chintu-faqlink {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .5rem .6rem;
    min-height: 44px;
    border: 1px solid var(--n-border);
    border-radius: .375rem;
    text-decoration: none;
    color: var(--n-ink);
    font-size: .82rem;
    background: #ffffff;
}

.n-chintu-faqlink:hover { background: var(--n-accent-soft); border-color: var(--n-green-500); }
.n-chintu-faqlink .bi { font-size: 1.2rem; color: var(--n-green-700); }

/* ---- the FAQ video library ---- */

.n-faq-mascot { width: 52px; height: 52px; flex: 0 0 auto; }

.n-faq-category {
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--n-ink-soft);
    margin: 1.1rem 0 .4rem;
}

.n-faq-card {
    height: 100%;
    border: 1px solid var(--n-border);
    border-radius: .375rem;
    background: #ffffff;
}

.n-faq-card > a {
    display: flex;
    gap: .6rem;
    align-items: flex-start;
    padding: .6rem .7rem;
    text-decoration: none;
    color: var(--n-ink);
    height: 100%;
    /* Reached by thumb on a tablet as often as by mouse. */
    min-height: 44px;
}

.n-faq-card:hover { border-color: var(--n-green-500); background: var(--n-accent-soft); }

.n-faq-play .bi { font-size: 1.5rem; color: var(--n-green-600); line-height: 1; }

/* A topic nobody has filmed yet still reads as a topic, not as a broken card. */
.n-faq-pending .n-faq-play .bi { color: var(--n-ink-soft); }
.n-faq-pending { background: #fbfcfb; }

.n-faq-text { display: block; }
.n-faq-text strong { display: block; font-size: .88rem; }

.n-faq-text small {
    display: block;
    font-size: .76rem;
    color: var(--n-ink-soft);
    margin-top: .1rem;
}

.n-faq-meta {
    display: block;
    font-size: .7rem;
    color: var(--n-green-700);
    margin-top: .25rem;
}

.n-faq-video {
    width: 100%;
    max-width: 100%;
    border: 1px solid var(--n-border);
    border-radius: .375rem;
    background: #000;
    /* The recordings are 1200x750 — 8:5. Stated so the page does not jump when metadata lands. */
    aspect-ratio: 8 / 5;
}

.n-faq-steps {
    margin: 0;
    padding: .6rem .6rem .6rem 1.6rem;
    font-size: .84rem;
}

.n-faq-steps > li { margin-bottom: .35rem; }

@media print {
    .n-faq-video { display: none !important; }
}

/* ------------------------------------------------------- inpatient billing
   Money columns line up or they cannot be added up by eye. A family reading a
   forty-line bill at a counter scans the right-hand edge, and a proportional
   font puts ₹1,111.00 and ₹9,999.00 at different widths. */
.n-num { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* The header-wise summary and the split-up sit on one page and are read
   together, so the split-up's header rows repeat the summary's wording. */
.n-splitup tbody tr.n-splitup-header td {
    background: var(--bs-tertiary-bg, #f2f4f7);
    font-weight: 600;
}
.n-splitup tbody tr.n-splitup-header td:first-child { border-left: 3px solid var(--bs-primary); }

/* ------------------------------------------------------------- the dental arch
   Two arches, the shape the person in the chair is, because a dentist finds the
   upper left first molar by looking where it would be in a mouth. A row of
   thirty-two identical boxes made them count along.

   It is still made of real <button> elements, absolutely positioned, and that
   is deliberate. An SVG mouth looks the same and cannot be tabbed to, read out
   by a screen reader, or given a disabled state — and this chart is the one
   screen in the module where being unreadable has a patient-safety cost. The
   picture is the tooth shape inside each button; the button is a button. */
.dt-arch {
    position: relative;
    width: 100%;
    max-width: 46rem;
    margin: 0 auto;
}

/* The gum, drawn from the same ellipse as the teeth — see the note in _Arch.cshtml. Behind
   them, and taking no pointer events, so every click belongs to a tooth. */
.dt-arch-gum {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}
.dt-arch-gum path {
    fill: none;
    stroke: #f4c8d2;
    stroke-width: 56;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.dt-arch-midline {
    position: absolute;
    left: 50%;
    top: 4%;
    height: 92%;
    border-left: 1px dashed #c8d2ce;
}

.dt-arch-label,
.dt-arch-side {
    position: absolute;
    font-size: .72rem;
    color: var(--n-ink-soft, #6b7a75);
    letter-spacing: .04em;
    text-transform: uppercase;
    pointer-events: none;
}
.dt-arch-label { left: 0; right: 0; text-align: center; }
.dt-arch-upper { top: 44%; }
.dt-arch-lower { top: 51%; }
.dt-arch-side  { top: 47.2%; font-weight: 600; }
.dt-arch-right { left: 0; }
.dt-arch-left  { right: 0; }

.dt-arch .dt-tooth {
    position: absolute;
    transform: translate(-50%, -50%) rotate(var(--dt-rot, 0deg));
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    line-height: 1;
}
.dt-arch .dt-tooth:disabled { cursor: default; }

.dt-arch .dt-shape { width: 100%; height: 100%; display: block; overflow: visible; }
.dt-arch .dt-shape path:first-of-type { stroke: #55636e; stroke-width: 2; fill: #fff; }
.dt-arch .dt-shape .dt-shape-line { stroke: #cdd6dc; stroke-width: 1.6; fill: none; }
.dt-arch .dt-shape .dt-shape-cusp { fill: #eef2f5; stroke: #d7dee4; stroke-width: 1; }

/* The number stays upright however the tooth is rotated. A number lying on its
   side at the back of the arch is a number nobody reads. */
.dt-arch .dt-num {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) rotate(calc(-1 * var(--dt-rot, 0deg)));
    font-size: .62rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: #3d4b55;
    pointer-events: none;
}

/* The same four states as the old grid, and from the same rule — what the status
   MEANS, not a list of statuses. */
.dt-arch .dt-decayed .dt-shape path:first-of-type { fill: #f7d0d0; stroke: #c96a6a; }
.dt-arch .dt-filled  .dt-shape path:first-of-type { fill: #cfe0f4; stroke: #6f97c4; }
.dt-arch .dt-missing .dt-shape path:first-of-type { fill: #ececec; stroke: #bdbdbd;
                                                    stroke-dasharray: 4 3; }
.dt-arch .dt-missing .dt-num { color: #9aa4ab; text-decoration: line-through; }
.dt-arch .dt-perio   .dt-shape path:first-of-type { stroke: #b8860b; stroke-width: 3.2; }

.dt-arch .dt-tooth:not(:disabled):hover .dt-shape path:first-of-type,
.dt-arch .dt-tooth:focus-visible .dt-shape path:first-of-type {
    stroke: #1f7666;
    stroke-width: 3.4;
}
.dt-arch .dt-tooth:focus-visible { outline: none; }

/* A legend, because four fills and an outline are five things to remember. */
.dt-arch-legend { display: flex; flex-wrap: wrap; gap: .75rem; font-size: .72rem;
                  color: var(--n-ink-soft, #6b7a75); }
.dt-arch-legend span { display: inline-flex; align-items: center; gap: .3rem; }
.dt-arch-legend i { width: .85rem; height: .85rem; border-radius: .18rem;
                    border: 1.5px solid #55636e; background: #fff; display: inline-block; }
.dt-arch-legend .lg-decayed { background: #f7d0d0; border-color: #c96a6a; }
.dt-arch-legend .lg-filled  { background: #cfe0f4; border-color: #6f97c4; }
.dt-arch-legend .lg-missing { background: #ececec; border-color: #bdbdbd; border-style: dashed; }
.dt-arch-legend .lg-perio   { border-color: #b8860b; border-width: 2.5px; }

@media print {
    .dt-arch { max-width: 100%; }
    .dt-arch .dt-tooth { break-inside: avoid; }
}

/* ---- The doctor's portal on a tablet or a phone ---- */
/* A report impression, two lines and an ellipsis; the whole report is one tap away. */
.n-clamp2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.min-w-0 { min-width: 0; }
.n-reportlist .list-group-item { padding: .6rem .9rem; }
.n-reportlist .btn { min-height: 36px; }
/* A page's action buttons wrap onto a second line instead of pushing the page wider than a
   phone: a signed consultation carries five of them, and at 412px they ran 40px off-screen. */
.n-pagehead > .d-flex { flex-wrap: wrap; }
/* A preformatted block (a set-up instruction, a command) wraps on a phone rather than widening
   the page to the length of its longest line. */
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
@media (max-width: 575.98px) {
    /* Label/value tables (a report header, a bill header) break a long number rather than run
       off the side of a phone. */
    .table-bordered th, .table-bordered td { overflow-wrap: anywhere; }
}

/* ---- Ward orders: the bed board ----
   Drawn after the ward's own bed-status board: a status pill and the ward type on top, the bed
   in a ruled box, and underneath either "Ready" or who is in it. A bed with a patient is the
   button that opens the order panel. */
.n-bedboard { background: linear-gradient(180deg, #eef3f8, #e3eaf2); border-radius: .5rem; overflow: hidden; }
.n-bedboard-tabs { display: flex; flex-wrap: wrap; background: #1aa84c; }
.n-bedboard-tabs a {
    color: #eafff0; text-decoration: none; font-weight: 700; padding: .55rem 1.1rem;
    border-right: 1px solid rgba(255,255,255,.35); display: inline-flex; gap: .45rem; align-items: center;
}
.n-bedboard-tabs a span { background: rgba(0,0,0,.18); border-radius: 999px; padding: 0 .5rem; font-size: .78rem; }
.n-bedboard-tabs a.is-active { background: #13863c; color: #fff; }
.n-bedgrid {
    display: grid; gap: 1.1rem; padding: 1.1rem;
    grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr));
}
.n-bedcard {
    display: block; width: 100%; text-align: left; font: inherit; color: inherit;
    background: #fff; border: 1px solid #b14b4b; border-radius: .45rem; padding: .55rem .6rem .6rem;
    box-shadow: 0 3px 8px rgba(40, 60, 90, .12);
}
button.n-bedcard { cursor: pointer; transition: transform .08s ease, box-shadow .12s ease; }
button.n-bedcard:hover { transform: translateY(-1px); box-shadow: 0 6px 14px rgba(40, 60, 90, .18); }
.n-bedcard.is-selected { border-color: #4f5bd5; box-shadow: 0 0 0 2px rgba(79, 91, 213, .45), 0 6px 14px rgba(40, 60, 90, .18); }
.n-bedcard-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: .35rem; }
.n-bedpill {
    white-space: nowrap;
    font-size: .68rem; font-weight: 800; letter-spacing: .04em; color: #fff;
    border-radius: 999px; padding: .1rem .5rem; background: #6c757d;
}
.n-bedpill-ready { background: #1f8f3a; }
.n-bedpill-occupied { background: #a52a2a; }
.n-bedpill-discharge { background: #c77700; }
.n-bedpill-cleaning { background: #b58900; }
.n-bedpill-held { background: #6f42c1; }
.n-wardpill {
    font-size: .68rem; font-weight: 800; color: #0b5d8a; background: #dbeefb;
    border-radius: 999px; padding: .1rem .5rem;
}
.n-bedcard-inner { display: block; border: 1px solid #b14b4b; border-radius: .3rem; overflow: hidden; }
.n-bedcard-row { display: flex; border-bottom: 1px solid #b14b4b; }
.n-bedcard-room {
    flex: 0 0 auto; min-width: 2.2rem; padding: .3rem .5rem; border-right: 1px solid #b14b4b;
    text-align: center; color: #444;
}
.n-bedcard-bed { flex: 1; text-align: center; font-weight: 700; padding: .3rem .4rem; color: #222; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.n-bedcard-body {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    text-align: center; min-height: 4.6rem; padding: .45rem .35rem; background: #f7faff;
}
.n-bedcard-status { font-weight: 800; color: #0f6b3d; font-size: 1.02rem; }
.n-bedcard-type { font-weight: 700; color: #1b3b66; font-size: .75rem; }
.n-bedcard-name { overflow-wrap: anywhere; font-weight: 800; color: #1a1a1a; font-size: .92rem; line-height: 1.2; }
.n-bedcard-ip { font-weight: 700; color: #1b3b66; font-size: .75rem; margin-top: .15rem; }
.n-bedcard-doc { font-weight: 700; color: #1b3b66; font-size: .72rem; margin-top: .1rem; }
.n-bedcard-cleaning .n-bedcard-status { color: #8a6d00; }
.n-bedcard-blocked .n-bedcard-status { color: #a52a2a; }
@media (max-width: 575.98px) {
    .n-bedgrid { grid-template-columns: repeat(2, 1fr); gap: .7rem; padding: .7rem; }
}

/* ---- Ward orders: patient marks ---- */
.n-flag { display: inline-block; font-size: .62rem; font-weight: 800; letter-spacing: .03em; border-radius: 3px;
          padding: .05rem .3rem; margin-left: .15rem; vertical-align: middle; color: #fff; }
.n-flag-mlc { background: #c62828; }
.n-flag-ins { background: #1565c0; max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.n-flag-vip { background: #b8860b; }
.n-bedcard-flags { display: block; margin-top: .25rem; }
.n-bedcard.n-mark-mlc { border-color: #c62828; box-shadow: inset 5px 0 0 #c62828, 0 3px 8px rgba(40,60,90,.12); }
.n-bedcard.n-mark-mlc .n-bedcard-body { background: #fdecec; }
.n-bedcard.n-mark-mlc .n-bedcard-name { color: #b71c1c; }
.n-bedcard.n-mark-ins { box-shadow: inset 5px 0 0 #1565c0, 0 3px 8px rgba(40,60,90,.12); }
.n-bedcard.n-mark-ins .n-bedcard-body { background: #e8f1fd; }
.n-bedcard.n-mark-ins .n-bedcard-name { color: #0d47a1; }
.n-bedcard.n-mark-vip { box-shadow: inset 5px 0 0 #b8860b, 0 3px 8px rgba(40,60,90,.12); }
.n-bedcard.n-mark-vip .n-bedcard-body { background: #fff7e0; }
.n-bedcard.n-mark-vip .n-bedcard-name { color: #7a5a00; }
.n-bedcard.is-selected { outline: 3px solid #4f5bd5; outline-offset: 1px; }
.n-pt-name.is-mlc { color: #b71c1c; }
.n-pt-name.is-ins { color: #0d47a1; }
.n-pt-name.is-vip { color: #7a5a00; }
.n-bedboard-legend { margin-left: auto; display: inline-flex; gap: .9rem; align-items: center; padding: 0 1rem;
                     color: #eafff0; font-size: .78rem; font-weight: 600; }
.n-dot { display: inline-block; width: .7rem; height: .7rem; border-radius: 2px; margin-right: .3rem; vertical-align: -1px;
         border: 1px solid rgba(255,255,255,.8); }
.n-dot-mlc { background: #c62828; } .n-dot-ins { background: #1565c0; } .n-dot-vip { background: #b8860b; }
.n-wp-tabs .nav-link { font-weight: 600; }

@media (max-width: 575.98px) {
    .n-bedboard-legend { width: 100%; padding: .35rem 1rem; }
    .n-wp-tabs { flex-wrap: nowrap; overflow-x: auto; }
    .n-wp-tabs .nav-link { white-space: nowrap; }
}

/* ---- Ward board: the same tiles, with the ward's quick actions under each ---- */
.n-bedboard-title { color: #fff; font-weight: 800; padding: .55rem 1.1rem; border-right: 1px solid rgba(255,255,255,.35); }
.n-bedboard-stat { color: #eafff0; font-weight: 600; padding: .55rem .9rem; font-size: .85rem; }
.n-wardpill-iso { background: #fde2e2; color: #a52a2a; margin-right: .2rem; }
.n-bedcard { display: flex; flex-direction: column; }
.n-bedcard-chips { display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .45rem; }
.n-bedcard-chips .n-chip { font-size: .68rem; }
.n-bedcard-actions { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: auto; padding-top: .45rem; }
.n-bedcard-actions .btn { padding: .15rem .5rem; font-size: .78rem; }
a.n-bedcard-body:hover { filter: brightness(.97); }
.n-bedcard-breach { border-color: #c62828; background: #fff5f5; }
@media (max-width: 575.98px) {
    /* Two tiles a row on a phone, and nothing inside a tile may push it wider than its column. */
    .n-bedgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .n-bedcard { min-width: 0; padding: .45rem; }
    .n-bedcard .n-wardpill:not(.n-wardpill-iso) { display: none; }
    .n-bedcard-name { font-size: .82rem; }
    .n-bedcard-ip, .n-bedcard-doc { font-size: .68rem; overflow-wrap: anywhere; }
    .n-bedboard-title, .n-bedboard-stat { padding: .4rem .7rem; }
}

/* ---- settings hub: one page per module -------------------------------------------------- */
.n-settings-hub { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); gap: .75rem; }
.n-settings-tile { display: flex; gap: .85rem; align-items: flex-start; padding: .9rem 1rem; border: 1px solid var(--bs-border-color); border-radius: .6rem; background: var(--bs-body-bg); color: inherit; text-decoration: none; transition: border-color .15s, box-shadow .15s; }
.n-settings-tile:hover { border-color: var(--bs-primary); box-shadow: 0 2px 10px rgba(0,0,0,.06); color: inherit; }
.n-settings-icon { flex: 0 0 2.4rem; width: 2.4rem; height: 2.4rem; border-radius: .55rem; display: inline-flex; align-items: center; justify-content: center; background: var(--bs-primary-bg-subtle); color: var(--bs-primary); font-size: 1.15rem; }
.n-settings-body { display: flex; flex-direction: column; min-width: 0; }
.n-settings-title { font-weight: 600; }
.n-settings-desc { font-size: .82rem; color: var(--bs-secondary-color); margin-top: .1rem; }
.n-settings-meta { font-size: .75rem; color: var(--bs-secondary-color); margin-top: .35rem; }
.n-settings-menu { max-height: 75vh; overflow-y: auto; }

/* ---- speciality registers: neurology, dermatology, BMT, diabetes ---------------------------- */
.n-sp-kpis { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 11rem), 1fr)); gap: .6rem; }
.n-sp-kpis-tight { grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr)); }
.n-sp-kpi { display: flex; flex-direction: column; padding: .7rem .85rem; border: 1px solid var(--bs-border-color); border-left: 4px solid var(--bs-secondary-bg); border-radius: .5rem; background: var(--bs-body-bg); color: inherit; text-decoration: none; min-width: 0; }
a.n-sp-kpi:hover { border-color: var(--bs-primary); color: inherit; }
.n-sp-kpi > span { font-size: .75rem; color: var(--bs-secondary-color); }
.n-sp-kpi > strong { font-size: 1.45rem; font-weight: 650; line-height: 1.25; }
.n-sp-kpi > small { font-size: .72rem; color: var(--bs-secondary-color); }
.n-sp-kpi.is-warn { border-left-color: #d97706; }
.n-sp-kpi.is-good { border-left-color: #059669; }
.n-sp-bar { display: grid; grid-template-columns: minmax(0, 11rem) 1fr 2.2rem; gap: .5rem; align-items: center; font-size: .8rem; padding: .15rem 0; }
.n-sp-bar > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.n-sp-bar > i { display: block; height: .55rem; border-radius: 1rem; background: linear-gradient(90deg, var(--bs-primary) var(--w), var(--bs-secondary-bg) var(--w)); }
.n-sp-bar > b { text-align: right; font-weight: 600; }
.n-sp-bar-0 > i { background: linear-gradient(90deg, #059669 var(--w), var(--bs-secondary-bg) var(--w)); }
.n-sp-bar-2 > i, .n-sp-bar-3 > i { background: linear-gradient(90deg, #d97706 var(--w), var(--bs-secondary-bg) var(--w)); }
.n-sp-bar-3 > i { background: linear-gradient(90deg, #dc2626 var(--w), var(--bs-secondary-bg) var(--w)); }
.n-sp-patient { display: flex; gap: .75rem; align-items: center; min-width: 0; }
.n-sp-avatar { flex: 0 0 2.6rem; height: 2.6rem; border-radius: 50%; background: var(--bs-primary-bg-subtle); color: var(--bs-primary); display: inline-flex; align-items: center; justify-content: center; font-size: 1.2rem; }
.n-sp-gcs { display: inline-block; padding: .05rem .45rem; border-radius: .35rem; background: var(--bs-secondary-bg); font-size: .8rem; font-weight: 600; }
.n-sp-gcs.is-warn { background: #fef3c7; color: #92400e; }
.n-sp-gcs.is-bad { background: #fee2e2; color: #991b1b; }
.n-sp-spark polyline { fill: none; stroke: var(--bs-primary); stroke-width: 2; stroke-linejoin: round; }
.n-sp-thresh { stroke: #d97706; stroke-width: 1; stroke-dasharray: 4 3; }
.n-sp-chart { width: 100%; height: auto; max-height: 150px; border: 1px solid var(--bs-border-color); border-radius: .4rem; margin-top: .5rem; }
.n-sp-anc { fill: none; stroke: var(--bs-primary); stroke-width: 2; }
.n-sp-plt { fill: none; stroke: #7c3aed; stroke-width: 1.5; stroke-dasharray: 5 3; }
.n-sp-lbl { font-size: 10px; fill: var(--bs-secondary-color); }
.n-sp-key { display: inline-block; width: 1.2rem; height: 0; border-top: 2px solid var(--bs-primary); vertical-align: middle; margin-right: .3rem; }
.n-sp-key-plt { border-top: 2px dashed #7c3aed; }
.n-sp-section { margin: 1.25rem 0 .6rem; padding-top: .8rem; border-top: 1px solid var(--bs-border-color); font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--bs-secondary-color); }
.n-sp-total { padding: .35rem .6rem; border-radius: .4rem; background: var(--bs-secondary-bg); font-size: .9rem; }
.n-sp-clock { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 11rem), 1fr)); gap: .75rem; }
.n-sp-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); gap: .6rem; }
.n-sp-card { display: block; padding: .8rem .9rem; border: 1px solid var(--bs-border-color); border-radius: .55rem; background: var(--bs-body-bg); color: inherit; text-decoration: none; }
.n-sp-card:hover { border-color: var(--bs-primary); color: inherit; }
.n-sp-day { font-weight: 700; font-size: .95rem; padding: .15rem .55rem; border-radius: .4rem; background: var(--bs-primary-bg-subtle); color: var(--bs-primary); white-space: nowrap; }
.n-sp-void summary { cursor: pointer; list-style: none; display: inline; }
.n-sp-void summary::-webkit-details-marker { display: none; }
.n-sp-void[open] { min-width: 14rem; }
.n-sp-scroll { max-height: 28rem; overflow-y: auto; }
.n-sp-tabs .nav-link { padding: .3rem .75rem; font-size: .85rem; }
details.card > summary { cursor: pointer; }
.n-sp-tag { display: inline-block; font-size: .72rem; font-weight: 600; border-radius: .3rem; padding: .05rem .4rem; margin: .05rem .1rem .05rem 0; background: var(--bs-secondary-bg); color: var(--bs-body-color); white-space: nowrap; }
.n-sp-tag-good { background: #d1fae5; color: #065f46; }
.n-sp-tag-warn { background: #fef3c7; color: #92400e; }
.n-sp-tag-bad { background: #fee2e2; color: #991b1b; }
.n-sp-scale td, .n-sp-scale th { padding: .3rem .4rem; }
.n-sp-scale th { font-weight: 500; font-size: .72rem; line-height: 1.15; min-width: 4.5rem; }
.n-sp-q9 td { background: #fef2f2; }

/* ==================================================================== the reporting console
   Three columns, its own scroll. The point of the layout is that the queue, the report and the
   assistant are all on the screen at once and none of them moves the others — a radiologist who
   loses their place in the findings because a panel grew has lost thirty seconds and their
   temper. So each column scrolls inside itself and the page does not scroll at all. */
.n-rc { display: flex; flex-direction: column; height: calc(100vh - 8.5rem); min-height: 34rem; }
.n-rc-head { display: flex; align-items: flex-start; gap: 1rem; padding: .5rem .25rem .6rem; border-bottom: 1px solid var(--bs-border-color); }
.n-rc-head-what { min-width: 0; }
.n-rc-head-who { min-width: 0; padding-left: 1rem; border-left: 1px solid var(--bs-border-color); }
.n-rc-head-actions { margin-left: auto; display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }

.n-rc-body { display: grid; grid-template-columns: 16rem minmax(0, 1fr) 20rem; gap: .75rem; flex: 1; min-height: 0; padding-top: .6rem; }
.n-rc-left, .n-rc-right { min-height: 0; overflow-y: auto; }
.n-rc-centre { min-height: 0; overflow-y: auto; padding-right: .3rem; }

.n-rc-card { height: auto; }
.n-rc-left .n-rc-card { display: flex; flex-direction: column; max-height: 100%; }

/* ---- the queue ---- */
.n-rc-queue-tabs { display: flex; border-bottom: 1px solid var(--bs-border-color); }
.n-rc-qtab { flex: 1; border: 0; background: none; padding: .35rem .2rem; font-size: .72rem; color: var(--bs-secondary-color); border-bottom: 2px solid transparent; }
.n-rc-qtab.is-on { color: var(--bs-primary); border-bottom-color: var(--bs-primary); font-weight: 600; }
.n-rc-count { display: inline-block; min-width: 1.2rem; padding: 0 .25rem; border-radius: .6rem; background: var(--bs-secondary-bg); font-size: .68rem; }
.n-rc-queue { overflow-y: auto; flex: 1; }
.n-rc-qrow { display: block; padding: .45rem .6rem; border-bottom: 1px solid var(--bs-border-color); color: inherit; text-decoration: none; }
.n-rc-qrow:hover { background: var(--bs-tertiary-bg); color: inherit; }
.n-rc-qrow.is-current { background: var(--bs-primary-bg-subtle); box-shadow: inset 3px 0 0 var(--bs-primary); }
.n-rc-qname { font-size: .82rem; font-weight: 600; line-height: 1.25; }
.n-rc-qwhat { font-size: .76rem; line-height: 1.25; }
.n-rc-qmeta { font-size: .7rem; color: var(--bs-secondary-color); line-height: 1.3; }
.n-rc-qtime { font-size: .72rem; font-variant-numeric: tabular-nums; }
.n-rc-qwait { font-size: .68rem; color: var(--bs-secondary-color); font-variant-numeric: tabular-nums; }

/* ---- the editor ---- */
.n-rc-toolbar { display: flex; align-items: center; gap: .4rem; padding: 0 0 .5rem; flex-wrap: wrap; }
.n-rc-section { margin-bottom: .7rem; }
.n-rc-box { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .84rem; line-height: 1.45; resize: vertical; }
.n-rc-box:focus { border-color: var(--bs-primary); box-shadow: 0 0 0 .18rem var(--bs-primary-bg-subtle); }
.n-rc-footer { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; padding: .6rem 0; border-top: 1px solid var(--bs-border-color); margin-top: .4rem; }

/* ---- priors ---- */
.n-rc-priors { margin: .6rem 0; padding: .55rem .7rem; border: 1px solid var(--bs-border-color); border-radius: .5rem; background: var(--bs-tertiary-bg); }
.n-rc-prior { font-size: .8rem; padding: .2rem 0; border-top: 1px dotted var(--bs-border-color); }
.n-rc-prior:first-of-type { border-top: 0; }
.n-rc-prior summary { cursor: pointer; }
.n-rc-prior.is-same summary { color: var(--bs-emphasis-color); }
.n-rc-prior-body { padding: .3rem 0 .4rem 1rem; font-size: .8rem; color: var(--bs-secondary-color); white-space: pre-wrap; }

/* ---- the assistant ---- */
.n-rc-answer { margin-top: .6rem; padding: .55rem .6rem; border: 1px solid var(--bs-primary-border-subtle); border-radius: .5rem; background: var(--bs-primary-bg-subtle); }
.n-rc-answer-body { font-size: .8rem; line-height: 1.45; white-space: pre-wrap; max-height: 20rem; overflow-y: auto; }
.n-rc-answer-caveat { margin-top: .4rem; font-size: .7rem; color: var(--bs-secondary-color); line-height: 1.35; }

/* ---- tags ---- */
.n-rc-tag { display: inline-block; padding: 0 .35rem; border-radius: .3rem; background: var(--bs-secondary-bg); color: var(--bs-secondary-color); font-size: .68rem; font-weight: 600; vertical-align: middle; }
.n-rc-tag-good { background: #dcfce7; color: #166534; }
.n-rc-tag-warn { background: #fef3c7; color: #92400e; }
.n-rc-tag-bad { background: #fee2e2; color: #991b1b; }

/* ---- the drawer ----
   Over the right-hand column rather than over the middle, so the report stays readable while a
   template is being chosen against it. Anchored to the bottom of the window and not the top,
   because the navigation bar is two or three rows deep depending on which modules a hospital has
   licensed and a drawer pinned to a fixed top edge covered the menus on a wide screen. */
.n-rc-drawer { position: fixed; top: auto; right: .75rem; bottom: 1rem; max-height: calc(100vh - 13rem); width: min(26rem, 94vw); z-index: 1040; display: flex; flex-direction: column; background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); border-radius: .55rem; box-shadow: 0 .6rem 2rem rgba(0,0,0,.18); }
.n-rc-drawer[hidden] { display: none; }
.n-rc-drawer-head { display: flex; align-items: center; gap: .3rem; padding: .5rem .6rem; border-bottom: 1px solid var(--bs-border-color); }
.n-rc-drawer-body { padding: .6rem; overflow-y: auto; }
.n-rc-drawer-group { margin: .7rem 0 .3rem; font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--bs-secondary-color); }
.n-rc-tpl { display: block; width: 100%; text-align: left; padding: .45rem .55rem; margin-bottom: .3rem; border: 1px solid var(--bs-border-color); border-radius: .45rem; background: var(--bs-body-bg); }
.n-rc-tpl:hover { border-color: var(--bs-primary); background: var(--bs-primary-bg-subtle); }
.n-rc-tpl-name { font-size: .82rem; font-weight: 600; }
.n-rc-tpl-preview { font-size: .74rem; color: var(--bs-secondary-color); line-height: 1.3; }

/* Under 1200px the console stops being three columns: the queue and the assistant go under the
   report rather than squeezing it, because a 40-character-wide findings box is unusable and a
   radiologist on a laptop should get the plain screen or this, not a broken version of this. */
@media (max-width: 1199.98px) {
    .n-rc { height: auto; }
    .n-rc-body { grid-template-columns: minmax(0, 1fr); }
    .n-rc-left, .n-rc-right, .n-rc-centre { overflow: visible; }
    .n-rc-left { order: 3; }
    .n-rc-centre { order: 1; }
    .n-rc-right { order: 2; }
}

@media print {
    .n-rc-left, .n-rc-right, .n-rc-toolbar, .n-rc-head-actions, .n-rc-drawer { display: none !important; }
}

/* ---- the shared viewer ----
   One set of rules for the full-page viewer and for the compact one inside the reporting console.
   The furniture is the same; only the proportions differ, which is the point of sharing it. */
.n-viewer { display: grid; grid-template-columns: 16rem minmax(0, 1fr); gap: .75rem; }
.n-viewer-series { border: 1px solid var(--bs-border-color); border-radius: .5rem; overflow: hidden; background: var(--bs-body-bg); }
.n-viewer-series-head { padding: .4rem .6rem; border-bottom: 1px solid var(--bs-border-color); font-size: .82rem; }
.n-viewer-stage { display: flex; flex-direction: column; border: 1px solid var(--bs-border-color); border-radius: .5rem; overflow: hidden; background: var(--bs-body-bg); }
.n-viewer-tools { display: flex; flex-wrap: wrap; gap: .25rem; align-items: center; padding: .3rem .4rem; border-bottom: 1px solid var(--bs-border-color); }
.n-viewer-body { position: relative; flex: 1; min-height: 0; }
.n-viewer-foot { display: flex; justify-content: space-between; gap: .5rem; padding: .25rem .5rem; border-top: 1px solid var(--bs-border-color); font-size: .74rem; color: var(--bs-secondary-color); }

/* Compact: inside the console. A narrower series strip, and the viewport is sized by the row it
   sits in rather than by a slice of the window — the console owns the height, not the viewer. */
.n-viewer.is-compact { grid-template-columns: 11rem minmax(0, 1fr); gap: .5rem; height: 100%; }
.n-viewer.is-compact .n-img-viewport { height: 100%; min-height: 0; }
.n-viewer.is-compact .n-img-list { max-height: 100%; }
.n-viewer.is-compact .n-viewer-tools { padding: .2rem .3rem; }

/* ---- the console's reading layout ----
   The pictures across the top and the report underneath, with the list and the assistant out of
   the way. For one screen: a radiologist with two monitors puts the viewer on the other one and
   never comes here. */
.n-rc-pictures { height: 52vh; min-height: 18rem; margin-bottom: .6rem; }
.n-rc-pictures[hidden] { display: none; }
.n-rc.is-reading .n-rc-body { grid-template-columns: minmax(0, 1fr); }
.n-rc.is-reading .n-rc-left,
.n-rc.is-reading .n-rc-right { display: none; }
.n-rc.is-reading { height: auto; }
.n-rc.is-reading .n-rc-centre { overflow: visible; }

/* One section at a time in the reading layout, with the toolbar buttons acting as its tabs. The
   pictures have taken the top half of the screen; five boxes in what is left would put the
   impression below the fold, and a radiologist writing findings while scrolling is exactly what
   this layout exists to stop. */
.n-rc.is-reading .n-rc-section { display: none; }
.n-rc.is-reading .n-rc-section.is-open { display: block; }
.n-rc.is-reading .n-rc-box { height: auto; }

/* Draggable. The right split between the pictures and the words is different for a chest film and
   a twelve-series MRI, and it is different for the same radiologist on a laptop and at their desk
   — so the browser's own resize handle is the answer rather than a number somebody chose here. */
.n-rc-pictures { resize: vertical; overflow: hidden; }

/* The priors and the measurements belong to the writing layout. In the reading one the screen is
   short and the pictures are the comparison. */
.n-rc.is-reading .n-rc-priors { display: none; }

@media (max-width: 1199.98px) {
    .n-viewer { grid-template-columns: minmax(0, 1fr); }
    .n-viewer-series { max-height: 12rem; overflow-y: auto; }
    .n-rc-pictures { height: 42vh; }
}

/* ==================================================================== a clinical report on paper
   Applied by putting n-report on the print view's wrapper. Everything here is inside a print
   media query: the screen copy of the report is already readable and does not want A4 margins.

   The target is the PDF a hospital sends out, which in practice is the browser's own "Save as
   PDF" — so this has to be right rather than approximately right. A report that runs to three
   pages and carries the patient's name on only the first is a report where page two is anonymous,
   and page two is where the impression usually is. */
@media print {
    .n-report { font-size: 10.5pt; line-height: 1.45; color: #000; }

    /* No CSS running header here, and no CSS page numbers.
     *
     * There was, and it was wrong. `position: fixed` does repeat on every sheet in Chrome, but it
     * is placed against the page box rather than the margin box, so the strip printed over the
     * findings; and `counter(page)` is not supported outside an `@page` margin box, which Chrome
     * does not implement at all — every sheet came out saying "Page 0" on top of a sentence.
     *
     * The browser's own print dialogue already offers headers, footers and page numbers, and gets
     * them right. Per-page patient identity — the thing that actually matters on a three-page
     * report — cannot be done properly this way at all. It needs either a table-header repetition
     * trick that distorts the layout inside it, or a real PDF writer on the server. That is a
     * decision about a dependency, not something to fake here.
     *
     * So: the identity strip prints once, under the letterhead, and the break rules below make
     * sure a finding is never cut in half. */

    /* Nothing that carries a finding may be split across a page break. A findings paragraph cut
       in half mid-sentence is readable; an impression cut in half is dangerous, and the signature
       block landing alone on page three is a report somebody will ask about. */
    .n-report h6 { break-after: avoid; page-break-after: avoid; margin-top: 4mm; margin-bottom: 1mm; font-size: 11pt; }
    .n-report p { break-inside: avoid; page-break-inside: avoid; orphans: 3; widows: 3; }
    .n-report table { break-inside: auto; }
    .n-report thead { display: table-header-group; }
    .n-report tr { break-inside: avoid; page-break-inside: avoid; }
    /* The signature. `mt-5` on screen is three rem, which on paper is thirteen millimetres of
       white space on top of whatever margin this adds — enough that a report with a third of a
       page left pushed the signature onto a sheet of its own, and a signature alone on page two
       is a report somebody rings up about. Overridden rather than added to. */
    .n-report .n-report-sign {
        break-inside: avoid;
        page-break-inside: avoid;
        margin-top: 8mm !important;
        padding-top: 2mm !important;
    }
    .n-report .n-report-addendum { break-inside: avoid; page-break-inside: avoid; }

    /* The impression is the part that gets read and acted on, so it is the part that is allowed
       to look different from everything else on the sheet. */
    .n-report .n-report-impression { font-weight: 600; padding-left: 3mm; border-left: 1.5pt solid #000; }

    /* Key images are already sized for paper further up this file — two across an A4 column at
       72mm, which somebody tuned against a real printer. Not restated here: two rules for one
       measurement is one rule that will be edited and one that will be forgotten. Only the break
       behaviour is added, which that block does not cover. */
    .n-report .n-report-images { break-inside: avoid; page-break-inside: avoid; }

    .n-report table.table-bordered th,
    .n-report table.table-bordered td { border-color: #666 !important; padding: 1mm 1.5mm !important; }
    .n-report .table-light td { background: #eee !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* The identity strip prints, and is hidden on screen — the banner above the screen copy already
   says who and what, and repeating it wastes the top of the page somebody is reading. */
.n-report-identity { display: none; }

@media print {
    .n-report-identity {
        display: flex !important;
        justify-content: space-between;
        gap: 4mm;
        margin: 0 0 3mm;
        padding-bottom: 1.5mm;
        border-bottom: .3pt solid #666;
        font-size: 8.5pt;
        color: #333;
        break-after: avoid;
        page-break-after: avoid;
    }
}

/* ==========================================================================
   The visit block on the registration form
   ==========================================================================
   Given a tinted header rather than left as another plain card, because it is
   the one block on the form that does something other than record what the
   clerk was told: ticking it creates a second record, puts a charge on a bill
   and places the patient in a queue. A block with side effects should not look
   like the block above it that has none.

   The dimming when the switch is off is done in JavaScript on the inner div,
   not here, so that a browser with scripting disabled shows the fields at full
   contrast — the fields are still submitted in that case, and a faint block
   whose values count would be a lie. */
.n-visitblock {
    border-color: #bcd9cb;
}

.n-visitblock > .card-header {
    background: #eef6f1;
    border-bottom-color: #bcd9cb;
}

.n-visitblock #visitFields {
    /* Matches the opacity transition of the switch itself so the two read as one
       gesture rather than two things happening. */
    transition: opacity 120ms ease-in-out;
}

/* The token is a read-only box that must not read as an input somebody forgot
   to fill in. Monospaced and centred: it is a number to be read out loud. */
.n-visitblock #tokenPreview {
    font-family: var(--n-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 1.05rem;
    font-weight: 600;
    text-align: center;
    letter-spacing: 0.02em;
}

/* The token column on the outpatient board and the doctor's worklist.
   A number that gets read out loud across a room: large, monospaced so a 1 and
   a 7 cannot be confused at a glance, and tabular so the column of them lines
   up under the eye rather than wandering. */
.n-token {
    font-family: var(--n-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-variant-numeric: tabular-nums;
    font-size: 1.05rem;
    font-weight: 600;
}

/* ==========================================================================
   The ordering pad
   ==========================================================================
   Two columns: what can be added, and what has been added. Fixed at that
   split rather than letting the basket grow, because the basket is a list of
   short names and the pick list is a list of long ones — giving them equal
   width wraps every test name and leaves the basket half empty.

   Collapses to one column on a tablet, pick list first. A doctor on an iPad
   in a consulting room is choosing before they are reviewing. */
.n-pad {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

@media (max-width: 1100px) {
    .n-pad { grid-template-columns: minmax(0, 1fr); }
}

.n-pad-pick,
.n-pad-basket {
    background: #fff;
    border: 1px solid #dfe7e2;
    border-radius: .5rem;
    overflow: hidden;
}

.n-pad-search {
    display: flex;
    gap: .5rem;
    align-items: center;
    padding: .6rem;
    border-bottom: 1px solid #eef2f0;
    flex-wrap: wrap;
}

.n-pad-search .input-group { flex: 1 1 14rem; }

/* ---- favourites ---- */
.n-pad-favs {
    padding: .6rem;
    background: #f6faf8;
    border-bottom: 1px solid #eef2f0;
}

.n-pad-favs-head {
    font-size: .8rem;
    font-weight: 600;
    color: #2f5d4a;
    margin-bottom: .35rem;
}

.n-pad-favs-head .field-help {
    display: block;
    font-weight: 400;
    margin: 0;
}

.n-pad-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}

.n-pad-chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    border: 1px solid #bcd9cb;
    background: #fff;
    border-radius: 999px;
    padding: .2rem .6rem;
    font-size: .82rem;
    line-height: 1.3;
    cursor: pointer;
    /* 32px is under the 44px touch target used elsewhere, and deliberately: a
       favourites strip of full-height buttons is two inches of screen before
       the list starts. These sit beside a full-size list row that does the
       same job, so the small target is a shortcut rather than the only way. */
    min-height: 32px;
}

.n-pad-chip:hover { background: #eef6f1; }

.n-pad-chip-count {
    font-size: .7rem;
    color: #6b8579;
    background: #eef6f1;
    border-radius: 999px;
    padding: 0 .35rem;
}

/* ---- the pick list ---- */
.n-pad-list {
    /* Bounded so the basket beside it stays on screen. An unbounded list of
       three hundred tests pushes the total and the place button below the fold,
       and a doctor cannot see what they are about to charge. */
    max-height: 26rem;
    overflow-y: auto;
}

.n-pad-row { cursor: pointer; }
.n-pad-row.is-hollow { cursor: not-allowed; background: #fff6f6; }
.n-pad-rate { font-variant-numeric: tabular-nums; }

/* ---- the basket ---- */
.n-pad-basket-head,
.n-pad-foot {
    padding: .6rem;
    border-bottom: 1px solid #eef2f0;
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

.n-pad-foot {
    display: block;
    border-bottom: 0;
    border-top: 1px solid #eef2f0;
    background: #fafcfb;
}

.n-pad-lines {
    max-height: 22rem;
    overflow-y: auto;
}

.n-pad-line {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 4.5rem auto 5.5rem auto;
    gap: .4rem;
    align-items: center;
    padding: .4rem .6rem;
    border-bottom: 1px solid #f0f5f3;
}

.n-pad-line-name {
    font-size: .88rem;
    min-width: 0;
    /* Wraps rather than truncating. A truncated test name is the one thing on
       this screen that must never be ambiguous — "Anti-HCV" and "Anti-HBs"
       differ in their last two characters. */
    overflow-wrap: anywhere;
}

.n-pad-qty { text-align: center; }

.n-pad-stat {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    font-size: .75rem;
    color: #8a4b12;
    white-space: nowrap;
    cursor: pointer;
}

.n-pad-line-rate {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-size: .85rem;
}

/* A line that was just added or incremented. Brief, because it is telling the
   doctor where their click landed — twenty rows down, outside their eyeline. */
.n-pad-line.is-new { animation: n-pad-flash 700ms ease-out; }

@keyframes n-pad-flash {
    from { background: #d9efe4; }
    to   { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .n-pad-line.is-new { animation: none; background: #eef6f1; }
}

.n-pad-total {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-weight: 600;
    font-size: 1.05rem;
}

.n-pad-total span:last-child { font-variant-numeric: tabular-nums; }

/* The visit-package panel on the bill.
   Sits above Save & print because it is a decision taken before the bill is
   settled, not after — and because a cashier who sees "package used up" needs
   to see it while they can still offer another one. */
.n-pkg {
    border: 1px solid #dfe7e2;
    border-radius: .45rem;
    padding: .55rem;
    background: #fafcfb;
}

.n-pkg-held {
    border-left: 3px solid #bcd9cb;
    padding: .25rem .5rem;
    margin-bottom: .4rem;
}

/* A live package and a finished one have to be tellable apart at a glance:
   the first means charge nothing, the second means charge full price, and
   getting them the wrong way round is an argument at the window. */
.n-pkg-held.is-live { border-left-color: #2f7d5d; }
.n-pkg-held.is-done { border-left-color: #c9822f; background: #fdf8f2; }

/* ==========================================================================
   OP BILL PAYMENT I / II / III — the counter's three tabs
   ==========================================================================
   Three equal tabs across the full width, which is the shape the counter
   already knows. The first version of this was three small pale outlines and
   the response from the desk was that the tabs were missing — correctly, because
   a control that runs three bills at once has to look like the three tabs it
   replaces, not like a row of badges.

   Above the patient's name on the page, because these are how the cashier
   changes which patient the rest of the screen is about: putting them below
   would have the name change above the control that changed it. */
.n-tabs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .35rem;
    margin-bottom: .85rem;
}

/* A fourth interruption extends the row rather than being refused — cancelling
   a bill to make room is the thing this feature exists to stop. Past three the
   tabs share the width. */
.n-tabs:has(> :nth-child(4)) { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }

.n-tab {
    display: flex;
    align-items: stretch;
    min-height: 3.1rem;
    border: 1px solid #cfdcd5;
    border-bottom: 3px solid #cfdcd5;
    border-radius: .3rem .3rem 0 0;
    background: #eef2f0;
    text-decoration: none;
    color: #435a50;
    overflow: hidden;
}

.n-tab > a,
a.n-tab {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: .1rem;
    padding: .4rem .7rem;
    text-decoration: none;
    color: inherit;
    min-width: 0;
    flex: 1 1 auto;
}

.n-tab:hover { background: #e4ebe7; }

/* The bill the cashier is looking at. Filled dark green, asked for in those
   words from the desk, and it is the right answer: at a counter running three
   bills at once the live one has to be findable from a step back, and a white
   face among pale grey faces is a difference you have to go looking for.

   The darker underline stays, so which tab is live is still answered by shape
   as well as by colour — which is what a colour-blind cashier and a
   black-and-white screenshot both rely on. */
.n-tab.is-on {
    background: #1d5c43;
    border-color: #1d5c43;
    border-bottom-color: #0f3a2a;
    color: #fff;
}

.n-tab.is-on:hover { background: #17503a; }

/* Everything inside the live tab is now read against dark green, so the greys
   that were right on a white face have to be re-picked. Left alone, the UHID
   and the amount on the tab the cashier is working on were the one thing on the
   strip they could not read. */
.n-tab.is-on .n-tab-meta { color: #c3ddd0; }
.n-tab.is-on .n-tab-stale { color: #ffd08a; }
.n-tab.is-on .n-tab-x { color: #cfe4d9; }
.n-tab.is-on .n-tab-x:hover { color: #ffb4ab; }
.n-tab.is-on .n-tab-go:focus-visible { outline-color: #ffffff; }

/* A free counter: dashed, so it reads as available rather than as disabled.
   Pale alone would look switched off, and this one is a link that does
   something. */
.n-tab.is-free {
    border-style: dashed;
    border-bottom-style: dashed;
    background: #fafcfb;
    color: #7d968a;
}

.n-tab.is-free:hover {
    background: #f1f7f4;
    border-color: #2f7d5d;
    border-bottom-color: #2f7d5d;
    color: #2f5d4a;
}

/* The tab's own label, in the counter's words. Small caps and letter-spaced so
   three of them read as a set rather than as three sentences. */
.n-tab-title {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .74rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.n-tab-sub {
    display: block;
    font-size: .82rem;
    line-height: 1.25;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.n-tab-meta {
    display: block;
    font-size: .72rem;
    color: #6b8579;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.n-tab-stale {
    margin-left: .3rem;
    color: #a8590f;
    font-weight: 600;
}

.n-tab-close {
    display: flex;
    align-items: flex-start;
    padding: .15rem;
}

.n-tab-close .btn { color: #8c9d95; }
.n-tab-close .btn:hover { color: #b3261e; }

@media (max-width: 860px) {
    /* One under the other on a phone. Three tabs at this width are three
       columns of two characters each, which is not a tab, it is a decoration. */
    .n-tabs { grid-template-columns: minmax(0, 1fr); }
    .n-tab { min-height: 0; border-radius: .3rem; border-bottom-width: 1px; }
    .n-tab.is-on { border-left: 3px solid #0f3a2a; }
}

/* A tab that is a submit button has to look exactly like a tab that is a link.
   Buttons bring their own background, border, padding and font, and a row of
   three where one is a button and two are links reads as a broken screen. */
.n-tab-go {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: .1rem;
    flex: 1 1 auto;
    min-width: 0;
    padding: .4rem .7rem;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.n-tab-go:focus-visible {
    outline: 2px solid #2f7d5d;
    outline-offset: -2px;
}

.n-tab-x { color: #8c9d95; align-self: flex-start; }
.n-tab-x:hover { color: #b3261e; }

.n-tabs-help {
    margin: -.55rem 0 .85rem;
}

/* ==========================================================================
   International Patient Services
   ==========================================================================
   One section on the registration form, switched on by a tick, holding a
   passport, a visa, an FRRO deadline, an accommodation address and two
   attendants. It is full width because at a third of the screen every one of
   those became a stack of half-width boxes and the clerk lost track of which
   passport they were typing — the patient's or the brother's. */
.n-ips .card-header {
    background: #f3f7f5;
}

/* Switched on, the card is given an edge so that a form with eight cards on it
   still answers "which of these applies to this patient" at a glance. */
.n-ips.is-on {
    border-color: #bcd9cb;
}

.n-ips.is-on .card-header {
    background: #e7f1ec;
}

/* The little headings inside the section. Deliberately not <h4 class="h6"> and
   friends: three columns of sub-blocks need one weight and one size, and
   Bootstrap's heading scale gives neither at this size. */
.n-ips-head {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: #2f5d4a;
    margin: 0 0 .6rem;
    padding-bottom: .3rem;
    border-bottom: 1px solid #e2ebe6;
}

.n-ips-choices {
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

/* FRRO position, passport expiry, visa expiry. Four tones, and they are read
   left to right in the header — the desk looks here before it reads a field. */
.n-ips-chip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .12rem .5rem;
    border-radius: 1rem;
    font-size: .74rem;
    font-weight: 600;
    white-space: nowrap;
}

.n-ips-ok { background: #e3f1e9; color: #1d5c43; }
.n-ips-info { background: #e7eef5; color: #2c4a63; }
.n-ips-warn { background: #fdf0d9; color: #8a5200; }

/* Overdue. Filled rather than tinted, because an overdue FRRO registration is
   the one thing on this screen that has a legal deadline attached to it and a
   pale chip in a row of pale chips is a chip nobody reads. */
.n-ips-danger { background: #b3261e; color: #fff; }

/* The attender table runs to twelve columns. It scrolls sideways inside its own
   wrapper rather than squeezing, because squeezing turns a passport number into
   three characters and an ellipsis. */
.n-ips-attenders th {
    font-size: .72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: #6b8579;
    white-space: nowrap;
}

.n-ips-attenders td { vertical-align: top; }
.n-ips-attenders .n-typeahead { min-width: 10rem; }

@media (max-width: 1200px) {
    /* Below three columns the section reads as one long form, which is fine —
       but the headings then have to do the dividing that the columns were
       doing. */
    .n-ips-head { margin-top: .5rem; }
}

/* ==========================================================================
   Video consultations
   ==========================================================================
   Two audiences on two machines. The hospital's screens sit inside the usual
   layout; the patient's join page is a bare page on a phone, opened from a
   link, with no navigation on it at all — every menu item is a door, and the
   holder of a join token is not entitled to any of them. */
.n-tele-chip {
    display: inline-block;
    padding: .1rem .45rem;
    border-radius: 1rem;
    font-size: .72rem;
    font-weight: 600;
    white-space: nowrap;
}

.n-tele-ok { background: #e3f1e9; color: #1d5c43; }
.n-tele-warn { background: #fdf0d9; color: #8a5200; }

/* The call itself. Sixteen by nine at the top of the page, tall enough that a
   face is a face rather than a letterbox, and it takes the width it is given. */
.n-tele-room {
    margin-bottom: 1rem;
}

.n-tele-stage {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    min-height: 320px;
    background: #0d1a15;
    border-radius: .4rem;
    overflow: hidden;
}

.n-tele-stage iframe {
    width: 100%;
    height: 100%;
    border: 0;
}

.n-tele-waiting,
.n-tele-ended {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #d7e6de;
    text-align: center;
    padding: 1rem;
}

/* ---- the patient's page ---- */

.n-tele-page {
    background: #f2f6f4;
    min-height: 100vh;
}

/* Narrow on purpose. This is read on a phone held in one hand, and a column
   that runs the width of a desktop screen is a column nobody scrolls. */
.n-tele-shell {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.25rem 1rem 3rem;
}

.n-tele-header {
    text-align: center;
    margin-bottom: 1.25rem;
}

.n-tele-header h1 {
    font-size: 1.15rem;
    font-weight: 700;
    color: #1d5c43;
    margin: 0;
}

.n-tele-header p {
    margin: .15rem 0 0;
    font-size: .82rem;
    color: #6b8579;
    text-transform: uppercase;
    letter-spacing: .06em;
}

.n-tele-facts > div + div {
    margin-top: .6rem;
}

/* The label above the fact rather than beside it. Side by side, a long doctor's
   name wrapped under a right-aligned label and the pair stopped reading as one
   thing. */
.n-tele-label {
    display: block;
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: #6b8579;
}

.n-tele-consent {
    font-size: .9rem;
    line-height: 1.5;
    background: #f7faf9;
    border: 1px solid #e2ebe6;
    border-radius: .3rem;
    padding: .75rem;
}

.n-tele-footer {
    margin-top: 1.5rem;
    text-align: center;
    font-size: .78rem;
    color: #6b8579;
}

/* On a phone the call takes the screen. A 16:9 box inside a 34rem column on a
   handset is a postage stamp. */
@media (max-width: 576px) {
    .n-tele-stage { aspect-ratio: auto; height: 70vh; }
}

/* A scan the hospital already holds, above the chooser that would replace it.
   A link and not a thumbnail: a passport page is held because a government
   asks for it, and rendering one inline puts somebody's passport on a screen
   at a counter with a queue behind it. Opening it is a deliberate act. */
.n-ips-onfile {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    margin-bottom: .3rem;
    font-size: .78rem;
    font-weight: 600;
    color: #1d5c43;
    text-decoration: none;
}

.n-ips-onfile:hover { text-decoration: underline; }

/* ── What a note may look like ────────────────────────────────────────────────
   The other half of NoteHtml. That file stores a class out of a closed list and
   never a style attribute; this is where the list is given a meaning. Keeping
   the appearance here rather than in the note means a hospital can restyle every
   note it has ever stored by editing one file — and that a note written on one
   installation looks like a note on the next, instead of carrying one machine's
   idea of "large" into another's.

   Everything below is scoped to .n-note-text so a class name in a note can only
   ever affect the inside of that note. */

.n-note-text .n-note-align-left    { text-align: left; }
.n-note-text .n-note-align-centre  { text-align: center; }
.n-note-text .n-note-align-right   { text-align: right; }
.n-note-text .n-note-align-justify { text-align: justify; }

.n-note-text .n-note-indent-1 { padding-left: 2rem; }
.n-note-text .n-note-indent-2 { padding-left: 4rem; }
.n-note-text .n-note-indent-3 { padding-left: 6rem; }
.n-note-text .n-note-indent-4 { padding-left: 8rem; }

/* Ink first, then the coloured ones. Each is dark enough to read on white and to
   survive a monochrome laser printer as a distinguishable grey, because a ward
   printer is monochrome more often than not. */
.n-note-text .n-note-fg-ink    { color: #1a1a1a; }
.n-note-text .n-note-fg-grey   { color: #6b6b6b; }
.n-note-text .n-note-fg-red    { color: #b3271c; }
.n-note-text .n-note-fg-orange { color: #a8560f; }
.n-note-text .n-note-fg-green  { color: #1d5c43; }
.n-note-text .n-note-fg-blue   { color: #1f5f8b; }
.n-note-text .n-note-fg-purple { color: #6b3a86; }

/* Pale on purpose: a highlighter over black text, not a block of colour. A
   saturated background prints as a dark rectangle with the words lost in it. */
.n-note-text .n-note-bg-yellow { background-color: #fff2a8; }
.n-note-text .n-note-bg-green  { background-color: #cdf5d8; }
.n-note-text .n-note-bg-blue   { background-color: #d6e9f8; }
.n-note-text .n-note-bg-pink   { background-color: #fbd9e6; }
.n-note-text .n-note-bg-grey   { background-color: #e6e6e6; }

.n-note-text .n-note-font-sans  { font-family: system-ui, -apple-system, "Segoe UI", sans-serif; }
.n-note-text .n-note-font-serif { font-family: Georgia, "Times New Roman", serif; }
.n-note-text .n-note-font-mono  { font-family: ui-monospace, Menlo, Consolas, monospace; }

/* Relative, so a note set "big" is big next to whatever the surrounding page is,
   on the ward screen and on the printed page alike. */
.n-note-text .n-note-size-tiny  { font-size: .75em; }
.n-note-text .n-note-size-small { font-size: .875em; }
.n-note-text .n-note-size-big   { font-size: 1.25em; }
.n-note-text .n-note-size-huge  { font-size: 1.6em; }

.n-note-text a { color: #1f5f8b; text-decoration: underline; }

.n-note-text img {
    max-width: 100%;
    height: auto;
    border: 1px solid var(--n-border);
    border-radius: 3px;
    margin: .35rem 0;
}

/* On paper a link's text is all the reader has, so the address is printed after
   it. A note that says "see the protocol here" and prints without the address is
   a note that has lost the protocol. */
@media print {
    .n-note-text a::after { content: " (" attr(href) ")"; font-size: .85em; word-break: break-all; }
    .n-note-text .n-note-bg-yellow,
    .n-note-text .n-note-bg-green,
    .n-note-text .n-note-bg-blue,
    .n-note-text .n-note-bg-pink,
    .n-note-text .n-note-bg-grey { background-color: transparent; text-decoration: underline; }
}

/* ── MRD folders ─────────────────────────────────────────────────────────────
   The folder number is what the clerk fetches from the shelf by, so it is drawn
   as a label — monospace, boxed — the way it looks on the spine. */
.n-mrd-folder {
    font-family: ui-monospace, Menlo, Consolas, monospace;
    font-weight: 600;
    padding: .05rem .4rem;
    border: 1px solid var(--n-border);
    border-radius: 3px;
    background: #f7f5ef;
    white-space: nowrap;
}
.n-mrd-overdue { color: #a8560f; font-weight: 500; }
.n-mrd-receiving tr.is-overdue > td:first-child { box-shadow: inset 3px 0 0 #a8560f; }

/* ── Consultation recording ──────────────────────────────────────────────────
   The same red on both sides of the call, so the doctor's REC and the patient's
   notice read as one signal. Said in words beside the dot every time: a dot
   alone means nothing to somebody who cannot tell red from brown. */
.n-tele-rec-dot {
    display: inline-block;
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    background: #c62828;
    vertical-align: middle;
    animation: n-tele-rec-pulse 1.4s ease-in-out infinite;
}
@keyframes n-tele-rec-pulse { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .n-tele-rec-dot { animation: none; } }

.n-tele-rec-live {
    font-size: .8rem;
    font-weight: 600;
    color: #c62828;
    letter-spacing: .03em;
}
.n-tele-rec-banner {
    margin: 0 0 .75rem;
    padding: .5rem .75rem;
    border: 1px solid #e8b4b4;
    border-radius: 4px;
    background: #fdecec;
    color: #8e1b1b;
    font-weight: 600;
}
.n-tele-rec-consent { border-top: 1px solid var(--n-border); padding-top: .75rem; }

.n-tele-player {
    width: 100%;
    max-height: 60vh;
    background: #111;
    border-radius: 4px;
}
.n-tele-consent-quote {
    margin: 0 0 .5rem;
    padding: .4rem .6rem;
    border-left: 3px solid var(--n-border);
    background: #f7f7f5;
    font-size: .8rem;
}

/* ==========================================================================
   Payment links — Razorpay links sent to patients and families abroad.
   ==========================================================================
   One chip per state, and the state that needs a person (paid, receipt not
   written) is the loudest of them: it is money in the bank that is not yet in
   the books. */
.n-plink-chip {
    display: inline-block;
    padding: .1rem .45rem;
    border-radius: 1rem;
    font-size: .72rem;
    font-weight: 600;
    white-space: nowrap;
}
.n-plink-Created { background: #e3edf8; color: #1f4e79; }
.n-plink-Paid { background: #fde2c4; color: #8a3b00; }
.n-plink-Posted { background: #e3f1e9; color: #1d5c43; }
.n-plink-Expired,
.n-plink-Cancelled { background: #eeeeec; color: #5c5c58; }
.n-plink-Failed { background: #fdecec; color: #8e1b1b; }

.n-plink-url {
    font-family: var(--bs-font-monospace);
    font-size: .85rem;
    word-break: break-all;
}
.n-plink-attention {
    border-left: 4px solid #d9822b;
}
.n-plink-test {
    display: inline-block;
    padding: .05rem .4rem;
    border-radius: 3px;
    background: #fff4ce;
    color: #6b5100;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .04em;
}

/* ==========================================================================
   Grouped top menus — Front office, Billing, Nephrology, Specialities…
   ==========================================================================
   One button opening several departments side by side, each under its own
   heading, so the bar holds eighteen menus instead of thirty-five and a demo
   can walk left to right through the hospital. */
.n-navgroup-menu.show {
    display: flex;
    width: max-content;
    flex-wrap: wrap;
    align-items: flex-start;
    /* Space between columns is each column's own right margin, not column-gap: Chrome leaves
       the gap out of a wrapping flex box's max-content width, so the second column always
       wrapped underneath the first. */
    row-gap: .25rem;
    padding: .6rem .8rem;
    max-width: min(1340px, calc(100vw - 2rem));
    max-height: 78vh;
    overflow-y: auto;
}
.n-navgroup-col { flex: 0 0 auto; width: 235px; margin-right: 1.1rem; }
.n-navgroup-head {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--n-green-800, #14532d);
    padding: .35rem .5rem .25rem;
    margin-bottom: .2rem;
    border-bottom: 1px solid var(--n-border, #e3e7e5);
    white-space: nowrap;
}
.n-navgroup-col .dropdown-item { white-space: normal; padding: .28rem .5rem; font-size: .86rem; }
.n-navgroup-col .dropdown-divider { margin: .3rem 0; }
@media (max-width: 992px) {
    .n-navgroup-menu.show { display: block; max-width: none; max-height: none; }
    .n-navgroup-col, .n-navgroup-col:has(.n-navgroup-embed) { width: auto; margin: 0 0 .4rem; }
    .n-navbar .n-navgroup-head { color: #a9cfbe; border-bottom-color: rgba(255, 255, 255, .18); padding-left: 1rem; }
}

/* A department that was already a panel of its own (the specialities) keeps its grid inside the
   group, without the panel's own border, shadow and scroll. */
.n-navgroup-embed.n-mega {
    width: auto;
    padding: 0;
    border: 0;
    box-shadow: none;
    max-height: none;
    overflow: visible;
}
.n-navgroup-embed .n-mega-grid { column-count: 4; }
.n-navgroup-col:has(.n-navgroup-embed) { width: calc(4 * 235px + 3 * 1.1rem); }

/* Eighteen menus on one line at a laptop's width: a little less padding on each. */
@media (min-width: 993px) {
    .n-navbar { padding: 0 .4rem; }
    .n-navbar .n-navitems > a,
    .n-navbar .n-navitems > .dropdown > .btn,
    .n-navbar .n-navitems > .nav-item > .btn {
        padding-left: .45rem; padding-right: .45rem; font-size: .82rem; white-space: nowrap;
    }
    .n-navbar .n-navitems > .dropdown > .dropdown-toggle::after { margin-left: .25em; vertical-align: .18em; }
}
/* On a laptop the carets go too: every one of these opens a menu, and without them the
   eighteen fit on one row at 1366px. */
@media (min-width: 993px) and (max-width: 1599.98px) {
    .n-navbar .n-navitems > .dropdown > .dropdown-toggle::after { display: none; }
}
/* Below a wide screen the words carry the menu; the icons come back when there is room. */
@media (min-width: 993px) and (max-width: 1799.98px) {
    .n-navbar .n-navitems > a > .bi,
    .n-navbar .n-navitems > .dropdown > .btn > .bi,
    .n-navbar .n-navitems > .nav-item > .btn > .bi { display: none; }
}
/* Books is an <li> straight inside the bar: without this it draws its list bullet beside Inventory. */
.n-navbar .n-navitems > li { list-style: none; }

/* ==========================================================================
   CHINTU, livelier — a face that floats, says hello, and thinks while it searches.
   Everything here layers over the rules above; motion is dropped for people who ask
   their system for less of it (end of this block).
   ========================================================================== */

/* ---- the button ---- */
.n-chintu-btn {
    width: 64px;
    height: 64px;
    right: 1.1rem;
    bottom: 1.1rem;
    border: 3px solid #ffffff;
    overflow: visible;
    background: radial-gradient(circle at 30% 25%, #ffffff 0%, #d9f3e8 45%, #9fdcc2 100%);
    box-shadow: 0 6px 18px rgba(20, 133, 122, .35), 0 0 0 1px rgba(20, 133, 122, .25);
    animation: n-chintu-float 4.2s ease-in-out infinite;
    transition: transform .18s ease, box-shadow .18s ease;
}
.n-chintu-btn img {
    width: 58px;
    height: 58px;
    border-radius: 50%;
    position: relative;
    z-index: 1;
    transform-origin: 50% 85%;
    animation: n-chintu-wave 9s ease-in-out infinite 2s;
}
.n-chintu-btn:hover {
    animation-play-state: paused;
    transform: scale(1.08);
    box-shadow: 0 10px 26px rgba(20, 133, 122, .45), 0 0 0 1px rgba(20, 133, 122, .35);
}
.n-chintu-halo {
    position: absolute;
    inset: -3px;
    border-radius: 50%;
    border: 2px solid #34a58c;
    opacity: 0;
    pointer-events: none;
    animation: n-chintu-halo 2.8s ease-out infinite;
}
.n-chintu-btn-label {
    position: absolute;
    right: calc(100% + .6rem);
    top: 50%;
    transform: translate(.4rem, -50%);
    white-space: nowrap;
    background: var(--n-green-800);
    color: #fff;
    font-size: .78rem;
    font-weight: 600;
    padding: .3rem .7rem;
    border-radius: 999px;
    box-shadow: 0 4px 12px rgba(6, 28, 21, .25);
    opacity: 0;
    pointer-events: none;
    transition: opacity .18s ease, transform .18s ease;
}
.n-chintu-btn:hover .n-chintu-btn-label,
.n-chintu-btn:focus-visible .n-chintu-btn-label { opacity: 1; transform: translate(0, -50%); }
body.n-chintuopen .n-chintu-btn { animation: none; }
body.n-chintuopen .n-chintu-halo { display: none; }

/* ---- the hello bubble ---- */
.n-chintu-hello {
    position: fixed;
    right: 1.2rem;
    bottom: 5.9rem;
    z-index: 1040;
    max-width: 16rem;
    padding: .65rem 1.9rem .7rem .85rem;
    background: #ffffff;
    border: 1px solid #bfe3d3;
    border-radius: 1rem 1rem .25rem 1rem;
    box-shadow: 0 10px 28px rgba(6, 28, 21, .18);
    font-size: .82rem;
    line-height: 1.35;
    color: var(--n-ink);
    animation: n-chintu-pop .35s cubic-bezier(.2, 1.4, .4, 1) both;
    cursor: pointer;
}
.n-chintu-hello strong { display: block; color: var(--n-green-800); font-size: .88rem; margin-bottom: .1rem; }
.n-chintu-hello kbd {
    background: var(--n-accent-soft);
    color: var(--n-green-800);
    border: 1px solid #bfe3d3;
    padding: 0 .3rem;
    font-size: .74rem;
}
.n-chintu-hello::after {
    content: "";
    position: absolute;
    right: 1.4rem;
    bottom: -7px;
    width: 12px;
    height: 12px;
    background: #fff;
    border-right: 1px solid #bfe3d3;
    border-bottom: 1px solid #bfe3d3;
    transform: rotate(45deg);
}
.n-chintu-hello-x {
    position: absolute;
    top: .2rem;
    right: .35rem;
    border: 0;
    background: none;
    font-size: 1.1rem;
    line-height: 1;
    color: var(--n-ink-soft);
    padding: .15rem .3rem;
}
.n-chintu-hello.is-leaving { animation: n-chintu-out .25s ease-in both; }
body.n-chintuopen .n-chintu-hello { display: none; }

/* ---- the drawer ---- */
.n-chintu {
    width: min(24rem, 94vw);
    border-left: 0;
    background:
        radial-gradient(28rem 16rem at 110% 12%, rgba(47, 158, 117, .13), transparent 70%),
        radial-gradient(20rem 14rem at -10% 60%, rgba(20, 133, 122, .08), transparent 70%),
        linear-gradient(180deg, #f2fbf7 0%, #ffffff 55%);
    box-shadow: -12px 0 36px rgba(6, 28, 21, .22);
    transition: transform .26s cubic-bezier(.2, .9, .3, 1);
}
.n-chintu-backdrop { background: rgba(6, 28, 21, .35); backdrop-filter: blur(2px); }

.n-chintu-head {
    padding: .9rem 1rem;
    background: linear-gradient(135deg, var(--n-green-800) 0%, #1f7666 100%);
    overflow: hidden;
    /* The drawer is a flex column; with overflow hidden the header would otherwise shrink to
       nothing the moment the panel below it is taller than the screen. */
    flex: 0 0 auto;
}
.n-chintu-head::before,
.n-chintu-head::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    background: rgba(255, 255, 255, .08);
    pointer-events: none;
}
.n-chintu-head::before { width: 9rem; height: 9rem; right: -2.5rem; top: -4.5rem; }
.n-chintu-head::after { width: 5rem; height: 5rem; right: 5rem; bottom: -3.2rem; }
.n-chintu-head > * { position: relative; z-index: 1; }
.n-chintu-head strong { font-size: 1.08rem; letter-spacing: .01em; }

/* The face: the avatar in a ring that spins while Chintu is thinking. */
.n-chintu-face {
    position: relative;
    flex: 0 0 auto;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    display: inline-grid;
    place-items: center;
    background: #ffffff;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .35);
}
.n-chintu-face img,
.n-chintu-head .n-chintu-face img {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: transparent;
    position: relative;
    z-index: 1;
}
.n-chintu-face::before {
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    background: conic-gradient(from 0deg, #7fd4ad, #1f7666, transparent 60%, #7fd4ad);
    opacity: 0;
    transition: opacity .2s ease;
}
.n-chintu-face::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: #fff;
}
.n-chintu-face.is-thinking::before,
.n-chintu.is-thinking .n-chintu-head .n-chintu-face::before { opacity: 1; animation: n-chintu-spin 1s linear infinite; }
.n-chintu-face.is-thinking img,
.n-chintu.is-thinking .n-chintu-head .n-chintu-face img { animation: n-chintu-think 1.1s ease-in-out infinite; }

.n-chintu-status { font-size: .74rem; display: flex; align-items: center; gap: .35rem; opacity: .95; margin: .1rem 0; }
.n-chintu-status-dot {
    width: .5rem;
    height: .5rem;
    border-radius: 50%;
    background: #7fe0b5;
    box-shadow: 0 0 0 0 rgba(127, 224, 181, .7);
    animation: n-chintu-live 2s ease-out infinite;
}
.n-chintu.is-thinking .n-chintu-status-dot { background: #ffd166; }

.n-chintu-body { padding: 1rem; }

/* The greeting: a speech bubble that "types" for a moment first. */
.n-chintu-bubble {
    position: relative;
    background: #ffffff;
    border: 1px solid #cfe9dd;
    border-radius: .25rem 1rem 1rem 1rem;
    padding: .65rem .8rem;
    box-shadow: 0 4px 14px rgba(6, 28, 21, .06);
    margin-bottom: .85rem;
    min-height: 2.2rem;
}
.n-chintu-bubble .n-chintu-cando { margin: 0; }
.n-chintu-typing { position: absolute; left: .85rem; top: .95rem; animation: n-chintu-gone 0s linear .9s forwards; }
.n-chintu-bubble-text {
    opacity: 0;
    max-height: 0;
    overflow: hidden;
    animation: n-chintu-say .45s ease-out .9s forwards;
}
@keyframes n-chintu-say {
    from { opacity: 0; max-height: 0; }
    to { opacity: 1; max-height: 14rem; }
}

/* Three bouncing dots, used for typing and for searching. */
.n-chintu-dots { display: inline-flex; gap: 3px; margin-left: .3rem; vertical-align: middle; }
.n-chintu-dots i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--n-green-500);
    animation: n-chintu-dot 1s ease-in-out infinite;
}
.n-chintu-dots i:nth-child(2) { animation-delay: .15s; }
.n-chintu-dots i:nth-child(3) { animation-delay: .3s; }

/* The search box. */
.n-chintu-search { position: relative; }
.n-chintu-search .form-control {
    padding: .65rem .9rem .65rem 2.4rem;
    border-radius: 999px;
    border: 1.5px solid #bfe3d3;
    background: #ffffff;
    box-shadow: 0 3px 10px rgba(6, 28, 21, .05);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.n-chintu-search .form-control:focus {
    border-color: var(--n-green-500);
    box-shadow: 0 0 0 .22rem rgba(47, 158, 117, .18);
}
.n-chintu-search-icon {
    position: absolute;
    left: .95rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--n-green-600);
    z-index: 2;
    pointer-events: none;
}
.n-chintu.is-thinking .n-chintu-search-icon { animation: n-chintu-seek .9s ease-in-out infinite; }

/* Thinking row, shown only while a search is out. */
.n-chintu-thinking {
    display: none;
    align-items: center;
    gap: .6rem;
    margin-top: .8rem;
    padding: .5rem .7rem;
    border-radius: .8rem;
    background: rgba(255, 255, 255, .8);
    border: 1px dashed #bfe3d3;
    color: var(--n-green-800);
    font-size: .84rem;
    font-weight: 500;
}
.n-chintu-thinking .n-chintu-face { width: 34px; height: 34px; box-shadow: none; }
.n-chintu-thinking .n-chintu-face img { width: 30px; height: 30px; }
.n-chintu.is-thinking .n-chintu-thinking { display: flex; animation: n-chintu-in .2s ease-out both; }
.n-chintu.is-thinking #n-chintu-results { display: none; }

/* Results arrive one after another rather than all at once. */
#n-chintu-results > *,
#n-chintu-results .n-chintu-hits > li { animation: n-chintu-in .32s ease-out both; }
#n-chintu-results .n-chintu-hits > li:nth-child(2) { animation-delay: .04s; }
#n-chintu-results .n-chintu-hits > li:nth-child(3) { animation-delay: .08s; }
#n-chintu-results .n-chintu-hits > li:nth-child(4) { animation-delay: .12s; }
#n-chintu-results .n-chintu-hits > li:nth-child(5) { animation-delay: .16s; }
#n-chintu-results .n-chintu-hits > li:nth-child(n+6) { animation-delay: .2s; }

.n-chintu-answer {
    background: #ffffff;
    border: 1px solid #cfe9dd;
    border-left: 4px solid var(--n-green-500);
    border-radius: .6rem;
    box-shadow: 0 4px 14px rgba(6, 28, 21, .06);
}
.n-chintu-work a,
.n-chintu-hits a {
    border-radius: .6rem;
    border-color: #dcebe4;
    transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.n-chintu-work a:hover,
.n-chintu-hits a:hover { transform: translateX(-2px); box-shadow: 0 4px 12px rgba(6, 28, 21, .08); }
.n-chintu-chip { transition: background .12s ease, transform .12s ease; }
.n-chintu-chip:hover { transform: translateY(-1px); }

.n-chintu-loading { display: flex; align-items: center; gap: .7rem; padding: 1.4rem 1rem; color: var(--n-green-800); }

@keyframes n-chintu-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
@keyframes n-chintu-wave {
    0%, 86%, 100% { transform: rotate(0); }
    89% { transform: rotate(-9deg); }
    92% { transform: rotate(8deg); }
    95% { transform: rotate(-5deg); }
    98% { transform: rotate(3deg); }
}
@keyframes n-chintu-halo { 0% { transform: scale(1); opacity: .55; } 100% { transform: scale(1.55); opacity: 0; } }
@keyframes n-chintu-pop { from { opacity: 0; transform: translateY(8px) scale(.92); } to { opacity: 1; transform: none; } }
@keyframes n-chintu-out { to { opacity: 0; transform: translateY(6px) scale(.95); } }
@keyframes n-chintu-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes n-chintu-gone { to { opacity: 0; visibility: hidden; } }
@keyframes n-chintu-dot { 0%, 80%, 100% { transform: translateY(0); opacity: .45; } 40% { transform: translateY(-4px); opacity: 1; } }
@keyframes n-chintu-spin { to { transform: rotate(360deg); } }
@keyframes n-chintu-think { 0%, 100% { transform: rotate(0) translateY(0); } 30% { transform: rotate(-7deg) translateY(-1px); } 60% { transform: rotate(6deg) translateY(0); } }
@keyframes n-chintu-live { 0% { box-shadow: 0 0 0 0 rgba(127, 224, 181, .7); } 100% { box-shadow: 0 0 0 7px rgba(127, 224, 181, 0); } }
@keyframes n-chintu-seek { 0%, 100% { transform: translate(0, -50%); } 25% { transform: translate(2px, -60%); } 75% { transform: translate(-2px, -40%); } }

@media print { .n-chintu-hello { display: none !important; } }

@media (prefers-reduced-motion: reduce) {
    .n-chintu-btn, .n-chintu-btn img, .n-chintu-halo, .n-chintu-status-dot,
    .n-chintu-dots i, .n-chintu-face::before, .n-chintu-face img, .n-chintu-search-icon,
    #n-chintu-results > *, #n-chintu-results .n-chintu-hits > li, .n-chintu-hello {
        animation: none !important;
    }
    .n-chintu-typing { display: none; }
    .n-chintu-bubble-text { opacity: 1; max-height: none; animation: none; }
}

/* ==========================================================================
   Supplier-bill import
   ========================================================================== */
.n-bill-drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .2rem;
    padding: 1.4rem 1rem;
    border: 2px dashed #bfe3d3;
    border-radius: .8rem;
    background: #f5fbf8;
    text-align: center;
    cursor: pointer;
}
.n-bill-drop > .bi { font-size: 2.2rem; color: var(--n-green-600); }
.n-bill-way { display: flex; gap: .6rem; padding: .6rem .7rem; border: 1px solid var(--n-border); border-radius: .6rem; height: 100%; }
.n-bill-way > .bi { font-size: 1.5rem; }
.n-bill-way.is-off { opacity: .7; background: #fafafa; }
.n-bill-columns > summary { cursor: pointer; }
.n-bill-mapped { border-color: var(--n-green-500); background-color: #f2fbf6; }
.n-bill-table td { vertical-align: top; }
.n-bill-kind {
    display: inline-block;
    padding: .05rem .45rem;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 600;
    margin-right: .25rem;
}
.n-bill-kind.n-bill-ok { background: #dff3e8; color: #1f7666; }
.n-bill-kind.n-bill-check { background: #fff1cc; color: #7a5200; }
.n-bill-kind.n-bill-new { background: #e7eefc; color: #1d4ea8; }
.n-bill-check-row { background: #fffbeb; }
.n-bill-new-row { background: #f6f9ff; }
.n-br-key { padding: .45rem .7rem; border: 1px solid #cfe9dd; background: #f3fbf7; border-radius: .5rem; }
.n-br-method { display: flex; align-items: flex-start; padding: .65rem .75rem; border: 1.5px solid var(--n-border); border-radius: .6rem; cursor: pointer; height: 100%; }
.n-br-method.is-on, .n-br-method:has(input:checked) { border-color: var(--n-green-500); background: #f2fbf6; }
.n-bill-shot { display: flex; gap: .75rem; align-items: center; padding: .5rem; border: 1px solid #cfe9dd; border-radius: .6rem; background: #f5fbf8; }
.n-bill-shot img { width: 110px; height: 80px; object-fit: cover; border-radius: .4rem; border: 1px solid var(--n-border); }
.n-bill-video { display: block; width: 100%; max-height: 70vh; object-fit: contain; background: #000; }
.n-bill-frame { position: absolute; inset: 6% 5%; border: 2px dashed rgba(255, 255, 255, .85); border-radius: .5rem; pointer-events: none; display: flex; align-items: flex-end; justify-content: center; }
.n-bill-frame span { background: rgba(0, 0, 0, .55); color: #fff; font-size: .8rem; padding: .15rem .6rem; border-radius: 999px; margin-bottom: .5rem; }

/* The note editor draws its own editing area (Jodit's .jodit-wysiwyg), which the note-text rules
   above never reached — so a form's table collapsed to the width of its prompts, leaving no room
   to write the answers. The same ruled, full-width form while writing as when reading. */
.jodit-wysiwyg table { width: 100% !important; border-collapse: collapse; margin: 0 0 .6rem; font-size: .9rem; }
.jodit-wysiwyg th, .jodit-wysiwyg td { border: 1px solid var(--n-border); padding: .35rem .5rem; vertical-align: top; min-width: 2rem; }
.jodit-wysiwyg th { background: var(--n-accent-soft); font-weight: 600; text-align: left; width: 38%; }
.jodit-wysiwyg th:first-child:not(:only-of-type) { width: 2.2rem; text-align: center; }
.jodit-wysiwyg td { background: #fff; }
.n-note-foot-print { justify-content: space-between; border-top: 1px solid var(--n-border); padding-top: .4rem; font-size: .85rem; }

/* ---- supplier's bill kept with a receipt ---- */
.n-billfiles-img { max-height: 420px; object-fit: contain; background: #f8f9fa; width: 100%; }
.n-billfiles-pdf { height: 420px; }
@media print { .n-billfiles form, .n-billfiles .btn { display: none !important; } }

/* ---- Chintu: asking by voice ---- */
.n-chintu-search.has-mic .form-control { padding-right: 3.1rem; }
.n-chintu-mic {
    position: absolute;
    right: .35rem;
    top: 50%;
    transform: translateY(-50%);
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    border: 0;
    background: linear-gradient(135deg, var(--n-green-500), var(--n-green-600));
    color: #fff;
    display: grid;
    place-items: center;
    z-index: 3;
    box-shadow: 0 3px 10px rgba(6, 28, 21, .18);
    transition: transform .15s ease, background .15s ease;
}
.n-chintu-mic:hover { transform: translateY(-50%) scale(1.06); }
.n-chintu-mic:focus-visible { outline: 3px solid rgba(47, 158, 117, .45); outline-offset: 2px; }
.n-chintu-mic i { position: relative; z-index: 1; font-size: 1rem; }
.n-chintu-mic-rings { position: absolute; inset: 0; border-radius: 50%; pointer-events: none; }
.n-chintu.is-listening .n-chintu-mic { background: linear-gradient(135deg, #e5484d, #c62a2f); }
.n-chintu.is-listening .n-chintu-mic-rings { animation: n-chintu-ring 1.2s ease-out infinite; }
.n-chintu.is-listening .n-chintu-head .n-chintu-face::before { opacity: 1; background: conic-gradient(from 0deg, #ff9a9e, #e5484d, transparent 60%, #ff9a9e); animation: n-chintu-spin 1.4s linear infinite; }
.n-chintu.is-listening .n-chintu-status-dot { background: #ff6b6b; }
@keyframes n-chintu-ring {
    0% { box-shadow: 0 0 0 0 rgba(229, 72, 77, .55), 0 0 0 0 rgba(229, 72, 77, .35); }
    100% { box-shadow: 0 0 0 10px rgba(229, 72, 77, 0), 0 0 0 20px rgba(229, 72, 77, 0); }
}

.n-chintu-voicebar {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-top: .6rem;
    padding: .5rem .75rem;
    border-radius: .75rem;
    background: #fff4f4;
    border: 1px solid #f5c6c7;
    font-size: .88rem;
    animation: n-chintu-in .2s ease-out;
}
.n-chintu-voicebar.is-note { background: #fff8e6; border-color: #f3dd9b; }
.n-chintu-voicebar.is-note .n-chintu-wave { display: none; }
.n-chintu-heard { flex: 1; color: #6b2c2e; font-style: italic; }
.n-chintu-voicebar.is-note .n-chintu-heard { color: #6a4e00; font-style: normal; }
.n-chintu-voice-stop { padding: 0 .25rem; }
.n-chintu-wave { display: inline-flex; align-items: center; gap: 3px; height: 1.2rem; }
.n-chintu-wave i { width: 3px; height: 30%; border-radius: 2px; background: #e5484d; animation: n-chintu-bars .9s ease-in-out infinite; }
.n-chintu-wave i:nth-child(2) { animation-delay: .1s; }
.n-chintu-wave i:nth-child(3) { animation-delay: .2s; }
.n-chintu-wave i:nth-child(4) { animation-delay: .3s; }
.n-chintu-wave i:nth-child(5) { animation-delay: .4s; }
@keyframes n-chintu-bars { 0%, 100% { height: 25%; } 50% { height: 100%; } }

.n-chintu-voiceopts { margin-top: .5rem; font-size: .78rem; color: var(--n-muted, #5f6f69); display: grid; gap: .2rem; }
.n-chintu-voicehint { opacity: .85; }
.n-chintu-youasked { margin: .8rem 0 .2rem; font-size: .82rem; color: #3d5a50; }
.n-chintu-opening {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-top: .6rem;
    padding: .55rem .75rem;
    border-radius: .75rem;
    background: #e9f7f0;
    border: 1px solid #bfe3d3;
    font-size: .9rem;
}
.n-chintu-opening small { color: #5f6f69; margin-left: .25rem; }
.n-chintu-opening .btn { white-space: nowrap; }
.n-chintu-opening.is-cancelled { opacity: .55; }
@media (prefers-reduced-motion: reduce) {
    .n-chintu.is-listening .n-chintu-mic-rings, .n-chintu-wave i { animation: none; }
}

/* ---- Voice typing in note boxes ---- */
.n-dictate-btn {
    position: fixed;
    z-index: 1080;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 0;
    display: grid;
    place-items: center;
    color: #fff;
    background: linear-gradient(135deg, var(--n-green-500), var(--n-green-600));
    box-shadow: 0 3px 10px rgba(6, 28, 21, .22);
    opacity: .9;
    transition: transform .12s ease, opacity .12s ease, background .12s ease;
}
.n-dictate-btn:hover { opacity: 1; transform: scale(1.06); }
.n-dictate-btn:focus-visible { outline: 3px solid rgba(47, 158, 117, .45); outline-offset: 2px; }
.n-dictate-btn.is-on { background: linear-gradient(135deg, #e5484d, #c62a2f); opacity: 1; animation: n-chintu-ring 1.2s ease-out infinite; }
.n-dictate-pill {
    position: fixed;
    z-index: 1080;
    padding: .35rem .7rem;
    border-radius: 999px;
    background: #fff4f4;
    border: 1px solid #f5c6c7;
    color: #6b2c2e;
    font-size: .8rem;
    font-style: italic;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: 0 3px 10px rgba(6, 28, 21, .12);
}
.n-dictate-pill.is-note {
    white-space: normal;
    font-style: normal;
    border-radius: .75rem;
    background: #fff8e6;
    border-color: #f3dd9b;
    color: #5a4300;
}
@media print { .n-dictate-btn, .n-dictate-pill { display: none !important; } }
@media (prefers-reduced-motion: reduce) { .n-dictate-btn.is-on { animation: none; } }

/* ---------------------------------------------------------------- spelling in note boxes */
.n-spell-btn {
    position: fixed;
    z-index: 1080;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--n-green-500);
    display: grid;
    place-items: center;
    color: var(--n-green-600);
    background: #fff;
    box-shadow: 0 3px 10px rgba(6, 28, 21, .16);
    opacity: .92;
}
.n-spell-btn:hover { opacity: 1; transform: scale(1.06); }
.n-spell-btn:focus-visible { outline: 3px solid rgba(47, 158, 117, .45); outline-offset: 2px; }
.n-spell-pill {
    position: fixed;
    z-index: 1085;
    padding: .2rem .6rem;
    border-radius: 999px;
    background: #eef8f3;
    border: 1px solid #bfe3d2;
    color: #1f7666;
    font-size: .78rem;
    box-shadow: 0 2px 8px rgba(6, 28, 21, .12);
    pointer-events: none;
}
.n-spell-panel {
    position: fixed;
    z-index: 1090;
    width: 370px;
    max-height: 320px;
    display: flex;
    flex-direction: column;
}
.n-spell-panel .n-spell-body { overflow-y: auto; }
@media print { .n-spell-btn, .n-spell-pill, .n-spell-panel { display: none !important; } }

/* ---------------------------------------------------------------- ICD code picker */
.n-cp-results {
    position: absolute;
    z-index: 1060;
    left: .25rem;
    right: .25rem;
    max-height: 18rem;
    overflow-y: auto;
}
.n-cp-row { border-bottom: 1px dotted #dfe7e3; }
.n-cp-row:last-child { border-bottom: 0; }
.n-cp-code { min-width: 5.5rem; }
.n-codelist td, .n-codelist th { font-size: .82rem; }

/* ---------------------------------------------------------------- voice notes */
.n-voice-meter {
    display: inline-block;
    width: 70px;
    height: 8px;
    border-radius: 4px;
    background: #e9efec;
    overflow: hidden;
}
.n-voice-meter > span { display: block; height: 100%; width: 0; background: #e5484d; transition: width .08s linear; }
.n-voice-audio { height: 30px; max-width: 260px; }
@media print { .n-voice { display: none !important; } }

/* Underlined as you type: a see-through copy over a text box, and highlights in the rich editor. */
.n-spell-mirror {
    position: absolute;
    z-index: 3;
    pointer-events: none;
    color: transparent;
    background: transparent;
    overflow: hidden;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    word-wrap: break-word;
    margin: 0;
}
.n-spell-mirror .n-sp-bad,
::highlight(n-spell) {
    text-decoration: underline wavy #e5484d;
    text-decoration-thickness: 1.5px;
    text-underline-offset: 3px;
    text-decoration-skip-ink: none;
}
.n-spell-menu { position: fixed; z-index: 1095; min-width: 12rem; display: block; }
.n-spell-menu[hidden] { display: none; }
@media print { .n-spell-mirror, .n-spell-menu { display: none !important; } }
.n-chintu-voicepick { width: auto; justify-self: start; font-size: .78rem; padding-top: .1rem; padding-bottom: .1rem; }

/* A dropdown you can type into (nephrone-select.js). Borrows the type-ahead's list. */
.n-ss .n-typeahead-list { max-height: 18rem; overflow-y: auto; }
.n-ss .n-ss-input { cursor: text; background-image: none; }
.n-ss::after {
    content: "\25BE";
    position: absolute; right: .55rem; top: 50%; transform: translateY(-50%);
    font-size: .7rem; color: var(--bs-secondary-color, #6c757d); pointer-events: none;
}

/* The patient's pages, on top of each of them (Views/Shared/Components/PatientTabs). */
.n-ptabs {
    position: relative;
    background: var(--bs-body-bg, #fff);
    border: 1px solid var(--bs-border-color, #dee2e6); border-radius: .5rem;
    padding: .35rem .5rem; margin-bottom: .9rem;
    box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.n-ptabs-who { display: inline-flex; align-items: baseline; gap: .1rem; padding: .1rem .35rem .3rem;
    color: inherit; text-decoration: none; }
.n-ptabs-who:hover { text-decoration: underline; }
.n-ptabs-row { display: flex; flex-wrap: wrap; gap: .25rem; }
.n-ptabs-row > a, .n-ptabs-row > button {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .3rem .65rem; border-radius: .4rem; font-size: .85rem;
    border: 1px solid transparent; background: transparent; color: var(--bs-body-color);
    text-decoration: none; white-space: nowrap;
}
.n-ptabs-row > a:hover, .n-ptabs-row > button:hover { background: var(--bs-tertiary-bg, #f1f4f3); }
.n-ptabs-row > a.is-on {
    background: var(--n-green, #1f5c45); color: #fff; border-color: var(--n-green, #1f5c45);
}

/* The document-scanner page (Views/Mrd/Scanner.cshtml). */
.n-scanner-drop {
    display: block; text-align: center; cursor: pointer; padding: 1.4rem 1rem;
    border: 2px dashed var(--bs-border-color, #ced4da); border-radius: .6rem;
    background: var(--bs-tertiary-bg, #f6f9f7); color: var(--bs-body-color);
}
.n-scanner-drop:hover, .n-scanner-drop.is-over { border-color: var(--n-green, #1f5c45); background: #eef6f2; }
.n-scanner-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: .6rem; }
.n-scanner-page {
    position: relative; border: 2px solid transparent; border-radius: .4rem; padding: 3px;
    background: var(--bs-body-bg, #fff); cursor: pointer; user-select: none;
    box-shadow: 0 1px 3px rgba(0,0,0,.15);
}
.n-scanner-page img { width: 100%; aspect-ratio: 210 / 297; object-fit: contain; background: #fff; display: block; }
.n-scanner-page-foot { display: flex; align-items: center; gap: .25rem; font-size: .75rem; padding-top: 2px; }
.n-scanner-page-no { font-weight: 600; }
.n-scanner-page.is-selected { border-color: var(--bs-primary, #0d6efd); background: #e8f0fe; }
.n-scanner-page.is-blank img { opacity: .35; }
.n-scanner-page.is-filed { border-color: var(--doc-colour, #6c757d); cursor: default; }
.n-scanner-page.is-filed img { opacity: .8; }
.n-scanner-docs { display: grid; gap: .4rem; }
.n-scanner-doc { border: 1px solid var(--bs-border-color, #dee2e6); border-left: 5px solid #6c757d;
    border-radius: .35rem; padding: .35rem .5rem; font-size: .85rem; }

/* MRD: the patient's OP and IP numbers, one chosen to scan into. */
.n-episode-scroll { max-height: 62vh; overflow-y: auto; }
.n-episode-scroll thead th { position: sticky; top: 0; background: var(--bs-body-bg); z-index: 1; }
.n-episode-row { cursor: pointer; }
.n-episode-pick.is-chosen { border-color: var(--bs-primary); box-shadow: 0 0 0 .15rem rgba(var(--bs-primary-rgb), .15); }
.n-episode-banner { border-left: 4px solid var(--bs-primary); }

/* Purchase entry bar: one line at a time, like the sales counter. */
.n-pe .n-pe-bar .form-label { font-size: .78rem; margin-bottom: .15rem; white-space: nowrap; }
.n-pe .n-pe-num { min-width: 5.2rem; }
.n-pe .n-pe-list { max-height: 22rem; overflow-y: auto; min-width: 26rem; }
.n-pe-alts { border: 1px solid var(--bs-border-color); border-radius: .375rem; padding: .5rem .75rem; background: var(--bs-tertiary-bg); max-width: 42rem; }
.n-pe-table td, .n-pe-table th { white-space: nowrap; }
.n-pe-table tbody tr[data-row] { cursor: pointer; }

/* The laboratory request and print-selection bands — the green strip the BEAT screens use, so
   a technician moving across finds the same landmarks. */
.lab-band td, .lab-band th { background: #1f9a4b !important; color: #fff !important; }
.lab-req td { padding: .3rem .5rem; font-size: .85rem; }

/* ---------------------------------------------------------------- AMC register */
.n-amc-tile { display: block; color: inherit; text-decoration: none; border-left: 4px solid var(--n-border);
    transition: box-shadow .15s ease, transform .15s ease; }
.n-amc-tile:hover { color: inherit; box-shadow: 0 .25rem .75rem rgba(0,0,0,.08); transform: translateY(-1px); }
.n-amc-tile.is-active { box-shadow: 0 0 0 2px var(--n-green-600) inset; }
.n-amc-tile .n-amc-num { font-size: 1.6rem; font-weight: 600; line-height: 1.1; }
.n-amc-tile.t-ok { border-left-color: #198754; }
.n-amc-tile.t-due { border-left-color: #e0a100; }
.n-amc-tile.t-exp { border-left-color: #dc3545; }
.n-amc-tile.t-none { border-left-color: #6c757d; }
.n-amc-tile.t-money { border-left-color: #0d6efd; }
.n-amc-months { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: .375rem; align-items: end; }
.n-amc-month { text-align: center; font-size: .72rem; color: var(--bs-secondary-color); }
.n-amc-month .bar-wrap { height: 56px; display: flex; align-items: flex-end; justify-content: center; }
.n-amc-month .bar { width: 60%; max-width: 28px; min-height: 2px; background: #2f7d5c; border-radius: 4px 4px 0 0; }
.n-amc-month.is-empty .bar { background: var(--n-border); }
.n-amc-month .cnt { font-weight: 600; color: var(--bs-body-color); }
.n-amc-progress { height: 4px; border-radius: 4px; background: var(--n-border); overflow: hidden; }
.n-amc-progress > span { display: block; height: 100%; background: #2f7d5c; border-radius: 4px; }
.n-amc-progress.is-due > span { background: #e0a100; }
.n-amc-progress.is-exp > span { background: #dc3545; }
.n-amc-table tbody tr { cursor: pointer; }
.n-amc-table td { vertical-align: middle; }
.n-amc-contact { border: 1px solid var(--n-border); border-radius: .5rem; padding: .5rem .75rem; height: 100%; }
.n-amc-contact.is-primary { border-color: #2f7d5c; background: rgba(47,125,92,.05); }
.n-amc-dl dt { font-weight: 400; color: var(--bs-secondary-color); font-size: .8rem; margin-bottom: 0; }
.n-amc-dl dd { margin-bottom: .6rem; }
@media (max-width: 767.98px) { .n-amc-months { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
