

:root{
  --np-primary:#89BCBD;
  --np-primary-600:#5A9495;
  --np-blue:#6FAAAB;
  --np-mint:#DCEBEB;
  --np-cream:#FFF8E7;
  --np-coral:#FE84A4;
  --np-ink:#0F2A47;
  --np-surface:#F4F8FB;
  --np-border:#E3ECF5;
  --np-muted:#64748B;
  --np-text:#1E293B;
  --np-card-shadow: 0 1px 2px rgba(15,42,71,.04), 0 4px 16px -4px rgba(15,42,71,.06);
  --np-card-shadow-hover: 0 4px 8px rgba(15,42,71,.06), 0 14px 32px -8px rgba(15,42,71,.12);
  --np-radius-card: 18px;
}

*{ box-sizing:border-box; }
html,body{
  background: var(--np-surface);
  color: var(--np-text);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  margin:0;
}

.np-shell{
  display:grid;
  grid-template-columns: 264px minmax(0, 1fr);
  height:100vh;
  height:100dvh;
  min-height:100vh;
  min-height:100dvh;
  overflow:hidden;
}
@media (max-width: 1023px){ .np-shell{ grid-template-columns: minmax(0, 1fr); } }

.np-sidebar{
  background: var(--nk-card);
  border-right:1px solid var(--np-border);
  display:flex; flex-direction:column;
  position:sticky; top:0;
  height:100vh;
  height:100dvh;
  overflow:hidden;
  z-index:40;
}
@media (max-width:1023px){
  .np-sidebar{ position:fixed; left:0; top:0; bottom:0; width:264px;
    transform:translateX(-100%); transition: transform .25s ease; }
  .np-sidebar.is-open{ transform: translateX(0); }
}
.np-backdrop{
  display:none; position:fixed; inset:0; background: rgba(15,42,71,.4); z-index:39;
  /* v3.3.2: never blur the whole app; never intercept touches when closed. */
  pointer-events:none;
}
@media (max-width:1023px){
  .np-backdrop.is-open{ display:block; pointer-events:auto; }
}

.np-sidebar__brand{
  display:flex; align-items:center; gap:.75rem;
  padding:1.25rem 1.25rem 1rem;
  border-bottom:1px solid var(--np-border);
}
.np-sidebar__logo{
  width:40px; height:40px; border-radius:12px;
  background: linear-gradient(135deg, var(--np-primary), var(--np-blue));
  color:white; display:flex; align-items:center; justify-content:center;
  box-shadow: 0 6px 14px -4px rgba(137,188,189,.5);
}
.np-sidebar__title{ font-weight:700; color:var(--np-ink); line-height:1.1; }
.np-sidebar__subtitle{ font-size:.7rem; letter-spacing:.08em; text-transform:uppercase; color:var(--np-muted); }

.np-sidebar__nav{ padding:.75rem .75rem 1rem; flex:1; min-height:0; }
.np-sidebar__section{ font-size:.7rem; letter-spacing:.1em; text-transform:uppercase; color:var(--np-muted); padding:.75rem .75rem .25rem; }

.np-nav-item{
  width:100%; display:flex; align-items:center; gap:.75rem;
  padding:.65rem .85rem; border-radius:12px;
  color: var(--np-text); font-weight:500; font-size:.93rem;
  border:1px solid transparent; background:transparent; text-align:left;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
  cursor:pointer;
}
.np-nav-item:hover{ background: var(--nk-teal-50); color:var(--np-primary-600); }
.np-nav-item__icon{ width:20px; height:20px; flex-shrink:0; color:currentColor; }
.np-nav-item.active{
  background: linear-gradient(135deg, rgba(137,188,189,.10), rgba(77,168,255,.08));
  color: var(--np-primary-600);
  border-color: rgba(137,188,189,.18);
}
.np-nav-item.active .np-nav-item__icon{ color:var(--np-primary); }
.np-nav-badge{
  margin-left:auto; background:var(--np-coral); color:#7C2D12;
  font-size:.65rem; font-weight:700; padding:.1rem .45rem;
  border-radius:999px; min-width:20px; text-align:center;
}
.np-sidebar__footer{
  padding:.75rem 1rem 1.25rem; border-top:1px solid var(--np-border);
  font-size:.75rem; color:var(--np-muted);
}

.np-main{
  display:flex;
  flex-direction:column;
  min-width:0;
  min-height:0;
  height:100vh;
  height:100dvh;
  overflow:hidden;
}
.np-header{
  background: var(--nk-card); border-bottom:1px solid var(--np-border);
  position:sticky; top:0; z-index:30;
  flex-shrink:0;
}
.np-header__inner{
  display:flex; align-items:center; gap:1rem;
  padding:1rem 1.5rem;
}
.np-header__title{ flex:1; min-width:0; }
.np-header__page-title{ font-size:1.15rem; font-weight:700; color:var(--np-ink); line-height:1.1; }
.np-header__page-subtitle{ font-size:.82rem; color:var(--np-muted); margin-top:.1rem; }

.np-iconbtn{
  width:38px; height:38px; border-radius:10px; border:1px solid var(--np-border);
  background: var(--nk-card); color: var(--np-text); display:inline-flex; align-items:center; justify-content:center;
  cursor:pointer;
}
.np-iconbtn:hover{ background:#F1F6FB; color: var(--np-primary-600); }
.np-menu-toggle{ display:none; }
@media (max-width:1023px){ .np-menu-toggle{ display:inline-flex; } }

.np-profile{ position:relative; }
.np-profile__trigger{
  display:flex; align-items:center; gap:.6rem;
  padding:.35rem .55rem .35rem .35rem;
  background:transparent; border:1px solid transparent; border-radius:12px; cursor:pointer;
}
.np-profile__trigger:hover{ background:#F1F6FB; border-color: var(--np-border); }
.np-profile__avatar{
  width:32px; height:32px; border-radius:10px; overflow:hidden;
  background: linear-gradient(135deg, var(--np-primary), var(--np-blue));
  color:#fff; display:flex; align-items:center; justify-content:center; font-weight:700; font-size:.85rem;
}
.np-profile__avatar img{ width:100%; height:100%; object-fit:cover; }
/* Same fix as .np-doc-card__avatar above — the doctor-insights drawer puts
   this class directly on the <img> (see admin/app.js), which the
   descendant rule above never matches, so the photo stretched to fill
   the box instead of cropping. */
img.np-profile__avatar{ width:100%; height:100%; object-fit:cover; }
.np-profile__meta{ text-align:left; }
.np-profile__name{ font-weight:600; color:var(--np-ink); font-size:.85rem; line-height:1.1; }
.np-profile__role{ font-size:.7rem; color:var(--np-muted); }
.np-profile__menu{
  position:absolute; right:0; top: calc(100% + 6px);
  background: var(--nk-card); border:1px solid var(--np-border); border-radius:12px;
  box-shadow: var(--np-card-shadow-hover);
  min-width: 220px; padding:.35rem;
  display:none; z-index:50;
}
.np-profile__menu.is-open{ display:block; }
.np-profile__menu-item{
  display:flex; align-items:center; gap:.55rem;
  width:100%;
  padding:.5rem .65rem; background:transparent; border:0;
  border-radius:8px; cursor:pointer; text-align:left; font-size:.86rem; color:var(--np-text);
}
.np-profile__menu-item:hover{ background:#F1F6FB; color: var(--np-primary-600); }
.np-profile__menu-item.is-danger{ color:#B91C1C; }
.np-profile__menu-divider{ height:1px; background:var(--np-border); margin:.25rem 0; }
.np-profile__menu-icon{ width:16px; height:16px; }

.np-content{
  flex:1;
  min-height:0;
  overflow-y:auto;
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
  padding: 1.25rem 1.5rem 2rem;
}

.np-panel{
  background: var(--nk-card);
  border:1px solid var(--np-border);
  border-radius: var(--np-radius-card);
  box-shadow: var(--np-card-shadow);
  
}
.np-panel__head{
  display:flex; align-items:center; gap:.75rem;
  padding:1rem 1.25rem .5rem;
}
.np-panel__title{ font-weight:700; color:var(--np-ink); font-size:1rem; }
.np-panel__subtitle{ font-size:.82rem; color:var(--np-muted); margin-top:.1rem; }
/* MOBILE ANALYTICS FIX (Platform-Wide Analytics Audit): every panel head's
   title/subtitle wrapper used to be `<div style="flex:1">` — an inline
   style, so it always won the cascade over any stylesheet rule for the
   same `flex` property, including the max-width:720px rule below that's
   specifically meant to force this div onto its own full-width row on
   phones (flex:1 1 100%). With the inline style still winning at 0%
   flex-basis, the div never claimed a forced full row; instead it just
   flex-shrank (min-width:0) down to near-zero width to make room for
   sibling controls with flex-shrink:0 (buttons, and — worse — a PAIR of
   month/year selects, e.g. Reception's clinic-revenue panel), crushing
   the title/subtitle into a column too narrow for even one word,
   producing exactly the vertical single-word-per-line wrapping seen on
   every panel head with two side-by-side selects on mobile. The markup
   now emits a plain `<div>` (no inline style) for this wrapper across
   every panel in every app (admin/doctor/pharmacy/receptionist), and
   `flex:1` moves here as a real stylesheet rule so the max-width:720px
   override two rules down can finally win at that breakpoint as intended. */
.np-panel__head > div:first-child{ flex:1; min-width:0; }
.np-panel__body{ padding:.5rem 1.25rem 1.25rem; }
/* Pharmacy Prescriptions/Bills tabs read as merged with their header since
   .np-panel__head carries no divider anywhere in the app — scoped here
   rather than on the shared class so every other panel is unaffected. */
#rxView .np-panel__head, #billsView .np-panel__head{
  border-bottom: 1px solid var(--np-border); margin-bottom: .5rem;
}
/* A select/input sitting directly in the panel head (e.g. the Pharmacy
   Prescriptions filter) inherits width:100% from the shared control
   box model, which makes it claim the whole flex row and crush the
   title/subtitle into a narrow wrapped column. Every other panel head
   only has buttons there (intrinsic width), so this never showed up
   elsewhere. Cap it like the other bounded controls in the app. */
.np-panel__head > .np-select,
.np-panel__head > .np-input{ flex:0 0 auto; width:auto; min-width:160px; max-width:220px; }

/* .np-divider is defined once, for both panels, in neokids-theme.css. */

/* Stacked, not side-by-side: the chart panel is naturally much shorter
   than the 10-row Recent Appointments list, so putting them in two grid
   columns left a large empty area next to the shorter chart panel. Full
   width also gives the chart more room to breathe. */
.np-dash-second{
  display:grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
@media (max-width: 640px){
  .np-dash-second{ gap: 1rem; }
}

.np-kpi-grid{
  display:grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
}
.np-kpi{
  position:relative;
  background: var(--nk-card);
  border:1px solid var(--np-border);
  border-radius: var(--np-radius-card);
  padding: 1.1rem 1.25rem;
  box-shadow: var(--np-card-shadow);
  overflow:hidden;
}
.np-kpi::before{
  content:'';
  position:absolute; left:0; top:0; bottom:0;
  width:4px; background: var(--np-primary);
}
.np-kpi--blue::before{ background: var(--np-primary); }
.np-kpi--mint::before{ background:#6FAAAB; }
.np-kpi--coral::before{ background:#F46A8E; }
.np-kpi--cream::before{ background:#E5A93A; }
.np-kpi--violet::before{ background:#7A4FE0; }
.np-kpi--rose::before{ background:#E11D48; }
.np-kpi__label{ font-size:.78rem; color:var(--np-muted); font-weight:500; }
.np-kpi__value{ font-size:1.65rem; font-weight:700; color:var(--np-ink); margin-top:.15rem; line-height:1.1; }
.np-kpi__sub{ font-size:.78rem; color:var(--np-muted); margin-top:.25rem; }

/* Button and badge/pill/chip base styling (sizing, color, radius, padding,
   hover/focus states) is defined ONCE, for both panels, in
   /assets/neokids-theme.css. Do not redeclare `.np-btn` / `.np-badge` here —
   this was the root cause of Admin vs Doctor panel inconsistency and of the
   v3.3.2 page-level patch below (now removed). */

.np-field{ display:flex; flex-direction:column; gap:.35rem; margin-bottom:.85rem; }
.np-field__label{ font-size:.78rem; font-weight:600; color:var(--np-ink); }
.np-field__hint{ font-size:.72rem; color:var(--np-muted); }
/* Form-control box model (padding, radius, border, chevron, focus ring)
   is defined ONCE, for both panels, in /assets/neokids-theme.css. */
/* .np-error is defined once, for both panels, in neokids-theme.css. */

.np-password-wrap{ position:relative; display:block; }
.np-password-wrap .np-input,
.np-password-wrap .np-input--password{ padding-right: 2.6rem; }
.np-password-toggle{
  position:absolute;
  top:50%;
  right:.5rem;
  transform:translateY(-50%);
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:2rem;
  height:2rem;
  padding:0;
  border:0;
  border-radius:8px;
  background:transparent;
  color:var(--nk-muted);
  cursor:pointer;
  transition: background .15s ease, color .15s ease;
}
.np-password-toggle:hover{
  background: rgba(137,188,189,.12);
  color: var(--np-primary);
}
.np-password-toggle:focus{
  outline:none;
  box-shadow: 0 0 0 3px rgba(137,188,189,.25);
}
.np-password-toggle__icon{ width:1.1rem; height:1.1rem; }
html[data-theme="dark"] .np-password-toggle{ color:#94A3B8; }
html[data-theme="dark"] .np-password-toggle:hover{ background: rgba(148,163,184,.15); color:#fff; }

.np-filterbar{
  display:flex; flex-wrap:wrap; gap:.5rem; align-items:center;
  margin-bottom: 1rem;
}
.np-search{
  position:relative; flex:1; min-width:240px;
}
.np-search svg{
  position:absolute; left:.7rem; top:50%; transform:translateY(-50%);
  width:16px; height:16px; color:var(--np-muted);
}
.np-search input{
  width:100%; padding:.55rem .85rem .55rem 2.2rem;
  border:1px solid var(--np-border); border-radius:10px;
  font-size:.85rem; background: var(--nk-card); font-family: inherit;
}
.np-search input:focus{ outline:none; border-color: var(--np-primary); box-shadow:0 0 0 3px rgba(137,188,189,.15); }

.np-table{
  width:100%;
  border-collapse: collapse;
  font-size:.85rem;
}
.np-table--fixed{ table-layout: fixed; }
.np-table--fixed td{ word-wrap: break-word; overflow-wrap: break-word; white-space: normal; }
.np-table--fixed td.np-table__nowrap{ white-space: nowrap; }
.np-table th{
  text-align:left;
  font-weight:600;
  color: var(--np-muted);
  font-size:.72rem;
  letter-spacing:.05em;
  text-transform:uppercase;
  padding:.55rem .75rem;
  border-bottom: 1px solid var(--np-border);
  background:#FAFCFE;
  position:sticky; top:0;
}
.np-table td{
  padding:.6rem .75rem;
  border-bottom:1px solid var(--np-border);
  vertical-align:top;
}
.np-table tr:hover td{ background:#F8FBFE; }
.np-table-wrap{
  border:1px solid var(--np-border);
  border-radius: 14px;
  overflow:auto;
  max-height: 70vh;
}

/* The Notification Logs table now paginates at 50 rows/page (see
   loadNotifications()), so it no longer needs its own internal 70vh
   scroll box — that inner scroll was clipping the last visible row right
   above the pagination bar, making the pagination look "cut off". The
   page itself scrolls instead, same as every other table. */
#notifView .np-table-wrap{ max-height:none; overflow:visible; }

.np-empty{
  text-align:center;
  padding: 2.5rem 1rem;
  color: var(--np-muted);
}
.np-empty__icon{
  width:42px; height:42px; border-radius:14px;
  background: linear-gradient(135deg, rgba(137,188,189,.15), rgba(77,168,255,.1));
  color: var(--np-primary);
  display:inline-flex; align-items:center; justify-content:center;
  margin-bottom: .65rem;
}
.np-empty__title{ font-weight:600; color: var(--np-text); margin-bottom:.25rem; }
.np-empty__sub{ font-size:.85rem; }

/* .np-login, .np-login__card, .np-login__logo, .np-login__title,
   .np-login__subtitle are defined once, for both panels, in
   neokids-theme.css. */

.np-doc-grid{
  display:grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 1rem;
  align-items: stretch;
  min-width:0;
}

.np-doc-card{
  position:relative;
  background: var(--nk-card);
  border:1.5px solid var(--np-border);
  border-radius:16px;
  box-shadow: 0 1px 3px rgba(15,42,71,.04), 0 4px 16px -4px rgba(15,42,71,.07);
  padding:1.1rem 1.1rem 0.9rem;
  display:grid;
  
  grid-template-rows: auto auto 1fr auto auto;
  row-gap:.75rem;
  height:100%;
  min-width:0;          
  box-sizing:border-box;
  transition: box-shadow .2s ease, transform .18s ease, border-color .2s ease;
}
.np-doc-card:hover{
  box-shadow: 0 6px 24px -6px rgba(137,188,189,.16), 0 2px 6px rgba(15,42,71,.05);
  transform: translateY(-2px);
  border-color: rgba(137,188,189,.3);
  z-index:1; 
}

.np-doc-card__head{
  display:flex; gap:.8rem; align-items:center;
  min-width:0;
}
.np-doc-card__avatar{
  flex:0 0 44px;            
  width:44px; height:44px; border-radius:50%;
  background: linear-gradient(135deg, var(--np-primary), var(--np-blue));
  color:#fff;
  display:flex; align-items:center; justify-content:center;
  font-weight:700; font-size:.95rem; letter-spacing:-.3px;
  border:2px solid #fff;
  box-shadow: 0 0 0 1.5px rgba(137,188,189,.18), 0 2px 6px -2px rgba(137,188,189,.25);
  overflow:hidden;
}
.np-doc-card__avatar img{ width:100%; height:100%; object-fit:cover; display:block; }
/* When a doctor has a photo, .np-doc-card__avatar is applied directly to
   the <img> itself (not a wrapping div) — the descendant rule above never
   matches that case, so the image fell back to the default object-fit:fill
   and got stretched/squished to the circle instead of cropped to it. */
img.np-doc-card__avatar{ object-fit:cover; display:block; }
.np-doc-card__head-meta{ min-width:0; flex:1 1 auto; }

.np-doc-card__name{
  font-weight:700; color:var(--np-ink); font-size:.98rem; line-height:1.2;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  margin:0 0 .15rem;
}

.np-doc-card__role{
  font-size:.76rem; color:var(--np-muted); line-height:1.3;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  margin:0;
}

.np-doc-card__qual{
  font-size:.7rem; color:#94A3B8; line-height:1.3;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  margin:.1rem 0 0;
}

.np-doc-card__contact{
  display:flex; flex-direction:column; gap:.2rem;
  font-size:.74rem; color:var(--np-muted);
  min-width:0;
}
.np-doc-card__contact-item{
  display:flex; align-items:center; gap:.4rem;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  min-width:0;
}
.np-doc-card__contact-item svg{
  width:12px; height:12px; flex:0 0 12px; color:#94A3B8;
}
.np-doc-card__contact-item span{
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0;
}

.np-doc-card__badge-row{
  display:flex; align-items:center; gap:.4rem; flex-wrap:wrap;
  min-width:0;
}
.np-doc-card__clinic{
  font-size:.7rem; color:var(--np-muted);
  display:inline-flex; align-items:center; gap:.25rem;
  max-width:100%; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  padding:.15rem .45rem; border-radius:6px;
  background:#F1F6FB;
}

.np-doc-card__stats{
  display:grid; grid-template-columns: 1fr 1fr;
  gap:.5rem;
  background:#F7FAFD;
  border:1px solid var(--np-border);
  border-radius:10px;
  padding:.6rem .7rem;
  min-width:0;
}
.np-doc-card__stat{ min-width:0; }
.np-doc-card__stat-label{
  font-size:.66rem; text-transform:uppercase; letter-spacing:.04em;
  color:var(--np-muted); font-weight:500;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.np-doc-card__stat-value{
  font-size:.88rem; font-weight:700; color:var(--np-ink);
  line-height:1.2; margin-top:.1rem;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

.np-doc-card__meta{
  display:flex; flex-wrap:wrap; gap:.35rem;
  align-items:center;
  min-width:0;
}
.np-doc-card__pill{
  display:inline-flex; align-items:center; gap:.3rem;
  padding:.2rem .5rem; border-radius:999px;
  font-size:.7rem; font-weight:500;
  white-space:nowrap;
  max-width:100%; overflow:hidden; text-overflow:ellipsis;
}
.np-doc-card__pill--warn{ background:#FEF3C7; color:#92400E; }
.np-doc-card__pill--ok  { background:#DCFCE7; color:#15803D; }
.np-doc-card__pill--kyc { background:#EEF2FF; color:#3730A3; }

/* Positive/payable amount text (e.g. "Net Payable" in the Mark Paid
   modal). Was a hardcoded inline color that never adapted for dark
   mode — #15803D on the dark inline-panel background (#0E1A22) falls
   to ~3.5:1 contrast, under the 4.5:1 text minimum. Themed like every
   other colored token in the app instead of inline. */
.np-amount-positive{ color:#15803D; font-weight:700; }
html[data-theme="dark"] .np-amount-positive{ color:#4ADE80; }

.np-doc-card__actions{
  display:grid;
  grid-template-columns: 1fr 1fr 1fr auto;
  gap:.4rem;
  align-items:stretch;
  padding-top:.7rem;
  border-top:1px solid var(--np-border);
}
.np-doc-card__actions .np-btn{
  padding:.4rem .25rem;
  font-size:.76rem;
  white-space:nowrap;
  min-width:0;
  text-overflow:ellipsis; overflow:hidden;
  justify-content:center;
}
/* Visual hierarchy within the action row: Insights (primary, filled) is
   the loudest action; Edit is a clear secondary action with a defined
   border so it doesn't read identically to the neutral Disable/Enable
   toggle; Disable/Enable stays soft/neutral since it's reversible;
   Delete is isolated as an icon-only danger action. */
.np-doc-card__actions .np-btn:not(.np-btn--primary):not(.np-btn--ghost):not(.np-btn--icon){
  border-color: var(--np-ink);
  color: var(--np-ink);
  font-weight:600;
}
.np-doc-card__actions .np-btn:not(.np-btn--primary):not(.np-btn--ghost):not(.np-btn--icon):hover{
  background: var(--np-ink);
  color:#fff;
}
.np-doc-card__actions .np-btn--ghost:not(.np-btn--icon){
  color: var(--np-muted);
  border-style: dashed;
}
/* .np-btn--icon sizing/color lives in the canonical neokids-theme.css
   (loaded after this file) — see the button component rules there.
   Do not redeclare width/height/padding for it here; that previously
   fought the canonical .np-btn base at equal specificity and shrank
   the delete-doctor icon button. */

.np-btn--add-doctor{
  display:inline-flex; align-items:center; gap:.5rem;
  padding:.6rem 1.1rem;
  font-size:.875rem; font-weight:600;
  border-radius:12px;
  box-shadow: 0 4px 14px -4px rgba(137,188,189,.5);
  transition: background .18s ease, box-shadow .18s ease, transform .12s ease;
}
.np-btn--add-doctor:hover{
  box-shadow: 0 6px 20px -4px rgba(137,188,189,.6);
  transform: translateY(-1px);
}
.np-btn--add-doctor:active{ transform: translateY(1px); box-shadow: none; }
.np-btn--add-doctor svg{
  transition: transform .2s ease;
}
.np-btn--add-doctor:hover svg{
  transform: rotate(90deg);
}

#doctorsGrid{ align-items: stretch; min-width:0; }

.np-drawer{
  position:fixed; inset:0; z-index:60;
}
.np-drawer.hidden{ display:none; }
.np-drawer__backdrop{
  position:absolute; inset:0; background: rgba(15,42,71,.45);
  /* v3.3.2: solid dim only; never blur the underlying app. */
}
.np-drawer.hidden .np-drawer__backdrop{ pointer-events:none; }
.np-drawer__panel{
  position:absolute; right:0; top:0; bottom:0;
  width: 100%; max-width: 540px;
  background: var(--nk-card);
  box-shadow: -24px 0 48px -12px rgba(15,42,71,.25);
  display:flex; flex-direction:column;
}
.np-drawer__head{
  padding: 1rem 1.25rem;
  border-bottom:1px solid var(--np-border);
  display:flex; align-items:center; gap:.75rem;
}
.np-drawer__title{ flex:1; font-weight:700; color: var(--np-ink); }
.np-drawer__body{ padding:1rem 1.25rem; overflow-y:auto; flex:1; }

/* ============================================================
   Dashboard: "Appointments — last 14 days" chart
   Responsive SVG bar chart with gridlines, axis labels, a peak
   highlight, an average reference line, and hover/tap tooltips.
   ============================================================ */
.np-chart{ position:relative; width:100%; }
.np-chart__svg{ display:block; width:100%; height:auto; }

.np-chart__grid{ stroke: var(--np-border); stroke-width:1; }
.np-chart__axis{ stroke: var(--np-border); stroke-width:1; }

.np-chart__avgline{
  stroke: var(--np-coral); stroke-width:1; stroke-dasharray:4 3; opacity:.55;
}
.np-chart__avglabel{ fill: var(--np-coral); font-size:10px; font-weight:600; opacity:.85; }

.np-chart__ylabel{ fill: var(--np-muted); font-size:10px; }
.np-chart__xlabel{ fill: var(--np-muted); font-size:10px; }
.np-chart__xlabel--today{ fill: var(--np-primary-600); font-weight:700; }

.np-chart__bar{ fill: var(--np-primary); transition: opacity .15s ease; }
.np-chart__bar--muted{ fill: var(--np-muted); opacity:.3; transition: opacity .15s ease; }
.np-chart__bar--peak{ fill: var(--np-coral); transition: opacity .15s ease; }
.np-chart__peaklabel{ fill: var(--np-coral); font-size:11px; font-weight:700; }

.np-chart__hit{ fill: transparent; cursor:pointer; }
.np-chart__col.is-active .np-chart__bar,
.np-chart__col.is-active .np-chart__bar--muted,
.np-chart__col.is-active .np-chart__bar--peak{ opacity:.75; }
.np-chart__col:focus{ outline:none; }
.np-chart__col:focus-visible .np-chart__hit{
  outline:2px solid var(--np-primary); outline-offset:-2px; border-radius:4px;
}
.np-chart__col--today .np-chart__bar,
.np-chart__col--today .np-chart__bar--muted{
  stroke: var(--np-primary-600); stroke-width:1.5;
}

.np-chart__tooltip{
  position:absolute; z-index:5;
  transform: translate(-50%, calc(-100% - 12px));
  background: var(--nk-card);
  border:1px solid var(--np-border);
  border-radius:10px;
  box-shadow: var(--np-card-shadow-hover);
  padding:.5rem .65rem;
  min-width:150px;
  pointer-events:none;
  opacity:0; visibility:hidden;
  transition: opacity .12s ease;
}
.np-chart__tooltip.is-visible{ opacity:1; visibility:visible; }
/* Only interactive once pinned by a real click — during a plain hover
   pass-through, pointer-events stays off so moving across bars doesn't
   get caught on an unpinned tooltip that's about to disappear anyway. */
.np-chart__tooltip.is-pinned{ pointer-events:auto; }
.np-chart__tooltip-date{ font-size:.72rem; font-weight:700; color:var(--np-ink); margin-bottom:.15rem; }
.np-chart__tooltip-main{ font-size:.82rem; font-weight:700; color:var(--np-primary-600); }
.np-chart__tooltip-sub{ font-size:.72rem; color:var(--np-muted); margin-top:.1rem; }
.np-chart__tooltip-link{
  display:block; width:100%; margin-top:.4rem; padding-top:.4rem; border:0; border-top:1px dashed var(--np-border);
  background:transparent; color:var(--np-primary-600); font-size:.72rem; font-weight:700; text-align:left; cursor:pointer;
}
.np-chart__tooltip-link:hover{ text-decoration:underline; }

.np-chart__legend{
  display:flex; flex-wrap:wrap; align-items:center; gap:.35rem .9rem;
  margin-top:.6rem; padding-top:.6rem; border-top:1px solid var(--np-border);
}
.np-chart__legend-item{ display:inline-flex; align-items:center; gap:.35rem; font-size:.72rem; color:var(--np-muted); }
.np-chart__legend-swatch{ width:8px; height:8px; border-radius:2px; background: var(--np-primary); display:inline-block; }
.np-chart__legend-swatch--peak{ background: var(--np-coral); }
.np-chart__legend-note{ margin-left:auto; color:var(--np-text); font-weight:600; }
@media (max-width:460px){ .np-chart__legend-note{ margin-left:0; width:100%; } }

.np-bars{
  display:flex; align-items:flex-end; gap:4px;
  height: 80px;
}
.np-bars__bar{
  flex:1; background: linear-gradient(180deg, var(--np-blue), var(--np-primary));
  border-radius: 3px 3px 0 0;
  min-height: 2px;
}
.np-bars__bar--muted{
  background: linear-gradient(180deg, #E2E8F0, #CBD5E1);
}

/* ROOT-CAUSE FIX ("Send does nothing"): this was z-index:60. The shared UI
   kit renders toasts at 99999, confirm/alert dialogs at 100000 and the
   lightbox at 100002 — so a receptionist/billing modal built at 60 painted
   UNDER those overlay layers (and under their dark backdrops), reading as
   "the click did nothing at all" even though the modal had opened. Content
   modals must stack above every helper overlay. */
.np-modal{ position:fixed; inset:0; z-index:100050; display:flex; align-items:center; justify-content:center; padding:1rem; background: rgba(15,42,71,.45); }
.np-modal.hidden{ display:none; }
/* On desktop the fixed sidebar occupies the leftmost 264px, so a modal
   centered across the whole viewport reads as shifted left of the content
   area. Offsetting the modal's left edge by the sidebar width re-centers it
   over the content the user is actually looking at. Below 1024px the sidebar
   is an overlay drawer (not in flow), so the modal spans the full viewport. */
@media (min-width:1024px){
  .np-modal{ left:264px; }
}
/* The panel owns the rounded corners + shadow and clips its children
   (overflow:hidden) — it is NOT the scrolling element. Only .np-modal__body
   scrolls (flex:1; min-height:0), so a native scrollbar is always drawn
   flush inside the body's straight-edged box and never crosses the
   panel's rounded corners or renders outside the modal frame. The head
   is a flex:none sibling so it stays put while the body scrolls. */
.np-modal__panel{
  background: var(--nk-card); border-radius: 20px;
  box-shadow: 0 24px 48px -12px rgba(15,42,71,.3);
  width:100%; max-width: 540px; max-height: 90vh;
  overflow:hidden;
  display:flex; flex-direction:column;
}
.np-modal__head{
  display:flex; align-items:center; flex:none;
  padding:1rem 1.25rem;
  border-bottom:1px solid var(--np-border);
}
.np-modal__title{ flex:1; font-weight:700; color:var(--np-ink); }
.np-modal__close{
  width:32px; height:32px; border-radius:8px; border:0; background:transparent;
  color: var(--np-muted); font-size:1.4rem; cursor:pointer;
}
.np-modal__close:hover{ background:#F1F6FB; color: var(--np-text); }
.np-modal__body{
  padding: 1rem 1.25rem 1.25rem;
  flex:1 1 auto;
  min-height:0;
  overflow-y:auto;
}
/* Consistent modal footer: a flex:none sibling of the scrolling body so the
   action buttons keep even spacing and a divider above them instead of
   sitting flush against the panel's bottom edge. Buttons align right on
   desktop and stack full-width on narrow screens. */
.np-modal__foot{
  flex:none;
  display:flex; align-items:center; justify-content:flex-end;
  gap:.6rem; flex-wrap:wrap;
  padding: .85rem 1.25rem;
  border-top:1px solid var(--np-border);
  background: var(--nk-card);
}
.np-modal__foot .np-btn{ min-width:96px; justify-content:center; }
@media (max-width:640px){
  .np-modal__foot{ padding:.85rem 1rem; }
  .np-modal__foot .np-btn{ flex:1 1 auto; }
}

.np-modal__body{ min-width:0; }
.np-modal__body .np-field{ min-width:0; overflow-wrap:anywhere; }

/* Stacked action list inside a modal (invoice actions, bill actions, send
   pickers). These classes were referenced by the receptionist portal long
   before they existed here, so the buttons rendered inline and unstyled. */
.np-action-list{ display:flex; flex-direction:column; gap:.5rem; }
.np-action-list .np-btn{ width:100%; justify-content:center; text-decoration:none; }
.np-btn--block{ display:flex; width:100%; justify-content:center; box-sizing:border-box; text-decoration:none; }
.np-btn--disabled, .np-btn:disabled{ opacity:.5; cursor:not-allowed; pointer-events:none; }
.np-delivery-log{ display:flex; flex-direction:column; gap:.4rem; }
.np-delivery-log__row{ display:flex; flex-wrap:wrap; align-items:center; gap:.35rem .6rem; font-size:.8rem; padding:.45rem .55rem; border:1px solid var(--np-border); border-radius:8px; }
.np-delivery-log__ch{ font-weight:600; color:var(--np-ink); }
.np-delivery-log__to{ color:var(--np-muted); overflow-wrap:anywhere; }
.np-delivery-log__at{ margin-left:auto; color:var(--np-muted); white-space:nowrap; }
.np-delivery-log__err{ width:100%; font-size:.74rem; color:#991B1B; overflow-wrap:anywhere; }

.np-cell-when__line{ display:flex; flex-wrap:wrap; align-items:baseline; gap:.15rem .4rem; }
.np-cell-when__time{ font-size:.78rem; white-space:nowrap; }

#notifView .np-table tr.np-notif-row{
  background: var(--nk-card);
  border:1px solid var(--np-border);
  border-radius:14px;
  box-shadow:var(--np-card-shadow);
}

/* Notification "Date & Time" column — always renders on one line, doesn't
   get squeezed by neighbouring columns. */
.np-table th.np-col-datetime,
.np-table td.np-col-datetime{
  white-space: nowrap;
  min-width: 148px;
  font-variant-numeric: tabular-nums;
}

.np-code-block{
  display:block; max-width:100%; overflow-x:auto;
  white-space:pre-wrap; overflow-wrap:anywhere; word-break:break-word;
  background:#F6F9FC; border:1px solid var(--np-border); border-radius:10px;
  padding:.7rem .85rem; font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:.76rem; line-height:1.5; margin:0;
}

.np-row{ display:flex; align-items:center; gap:.5rem; }

/* Doctor form tabs (Details / KYC & Documents) — keeps the KYC block from
   being buried at the bottom of one long scroll behind ~10 unrelated
   fields, and makes it visually obvious that "Upload selected files" /
   "Verify KYC" are a separate action from the form's own Save button. */
.np-dform-tabs{
  display:flex; gap:.25rem;
  border-bottom:1px solid var(--np-border);
  margin:0 0 1rem;
}
.np-dform-tab{
  appearance:none; background:transparent; border:0;
  padding:.6rem .9rem; font:inherit; font-weight:600; font-size:.85rem;
  color: var(--np-muted);
  border-bottom:2px solid transparent;
  border-radius:8px 8px 0 0;
  cursor:pointer;
  display:inline-flex; align-items:center; gap:.4rem;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.np-dform-tab:hover{ color: var(--np-ink); background: var(--nk-teal-50); }
.np-dform-tab.active{
  color: var(--nk-teal-700, #5A9495);
  border-bottom-color: var(--nk-teal-700, #5A9495);
}
.np-dform-tab:focus-visible{ outline:2px solid var(--nk-teal-700, #5A9495); outline-offset:2px; }
.np-dform-tab__dot{
  width:7px; height:7px; border-radius:50%; flex-shrink:0;
  background: var(--np-muted);
}
.np-dform-tab__dot--slate{ background:#94A3B8; }
.np-dform-tab__dot--amber{ background:#D9A441; }
.np-dform-tab__dot--green{ background:#2FA97E; }
.np-dform-tab__dot--red{ background:#D65B5B; }
.np-dform-pane.hidden{ display:none; }

.np-kyc-grid{
  display:grid;
  grid-template-columns: repeat(2, minmax(0,1fr));
  gap:.75rem;
  align-items:stretch;
}
@media (max-width:599px){ .np-kyc-grid{ grid-template-columns: 1fr; } }
.np-kyc-card{
  display:flex;
  flex-direction:column;
  gap:.55rem;
  min-height:120px;
  background: var(--nk-surface);
  border:1px solid var(--np-border);
  border-radius:12px;
  padding:.85rem .9rem;
  box-sizing:border-box;
  min-width:0;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.np-kyc-card:hover{
  border-color: var(--nk-teal-200);
  box-shadow: 0 4px 14px -8px rgba(15,46,58,.18);
}
/* Once KYC is VERIFIED, the file inputs (and NPDropzone's own wrapper,
   inserted as a sibling right before the input) are hidden so the panel
   reads as read-only until an admin deliberately clicks "Replace
   documents" — previously the upload controls stayed live indefinitely,
   with no visual cue that touching them would undo the verification. */
#kycGrid.is-locked input[type="file"],
#kycGrid.is-locked .np-dropzone{ display:none; }
.np-kyc-card__head{
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:.4rem;
  min-width:0;
}
.np-kyc-card__title{
  font-size:.8rem;
  font-weight:600;
  color:var(--np-ink);
  line-height:1.3;
}
.np-kyc-card__status{
  font-size:.68rem;
  color:var(--np-muted);
  white-space:nowrap;
  flex-shrink:0;
}
.np-kyc-card__input{ margin:0; }
.np-kyc-card__actions{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:.4rem;
  margin-top:auto;
  padding-top:.15rem;
}
.np-kyc-card__actions .np-btn{ min-height:26px; padding:.25rem .55rem; font-size:.7rem; }
.np-kyc-card__link{
  font-size:.72rem;
  font-weight:600;
  color: var(--nk-teal-700, #5A9495);
  text-decoration:none;
}
.np-kyc-card__link:hover{ text-decoration:underline; }
/* Locked (VERIFIED) cards: View/Download stay usable, but Replace/Remove
   route through the same "unlock to replace" confirmation as the banner
   button — never a silent destructive action on verified documents. */
#kycGrid.is-locked .js-kyc-replace,
#kycGrid.is-locked .js-kyc-remove{ opacity:.6; }
html[data-theme="dark"] .np-kyc-card__link{ color: var(--nk-teal-300, #B4D7D7); }
.np-grid-2{ display:grid; grid-template-columns: 1fr 1fr; gap: .85rem; }
@media (max-width: 599px){ .np-grid-2{ grid-template-columns: 1fr; } }
/* Belt-and-braces mobile stack for modal forms (Book appointment / walk-in,
   certificates, etc). Raised to 680px and scoped + !important so a two-column
   .np-grid-2 inside a modal body can never survive on a phone-width screen —
   on narrow viewports a shared 1fr/1fr track squeezes fields like Phone,
   Parent/guardian, and DOB down to an unreadably narrow column where typed
   values get visually clipped ("8454930…") even though nothing is actually
   wrong with the data. Full-width single-column fields are always legible,
   so below this width every modal grid just stacks. */
@media (max-width: 680px){
  .np-modal__body .np-grid-2{ grid-template-columns: 1fr !important; }
  .np-modal__body .np-grid-2 > .np-field{ grid-column: 1 !important; }
}
/* Notification Logs detail modal is a plain key/value readout, not a form —
   a 2-column grid here has no alignment benefit and, depending on how
   asymmetric each row's label/value content is, a shared 1fr/1fr track can
   size unevenly and squeeze one column to an unreadable width (seen live:
   a vaccination-reminder log's long unbroken template constant plus its
   "email [patientId]" recipient forced a track down to a sliver, so every
   value after it rendered one character per line and rows visually
   collided). Dropping the grid track algorithm entirely — not just
   collapsing it to one column — removes that whole failure class: each
   .np-field is already a block-level flex column, so a plain block
   container stacks them at full width with no track-sizing math at all.
   The Appointment field's leftover `grid-column: span 2` inline style is
   inert once this is a block container. */
#notifModal .np-grid-2{ display:block; }
#notifModal .np-grid-2 .np-field{ width:100%; }
.np-mut{ color: var(--np-muted); }
.np-ink{ color: var(--np-ink); }

.np-appt-row{
  display:flex; gap:.85rem; padding:.85rem 1rem;
  border-bottom: 1px solid var(--np-border);
  align-items:flex-start;
  cursor:pointer;
  transition: background .12s ease;
}
.np-appt-row:hover{ background:#F8FBFE; }
.np-appt-row__time{ width: 90px; flex-shrink:0; }
.np-appt-row__time-h{ font-weight:700; color: var(--np-ink); font-size:.92rem; }
.np-appt-row__time-d{ font-size:.75rem; color: var(--np-muted); }
.np-appt-row__body{ flex:1; min-width:0; }
.np-appt-row__name{ font-weight:600; color: var(--np-ink); }

.np-appt-row__assign{ font-size:.8rem; color:var(--np-muted); margin-top:.1rem; }
.np-appt-row__name, .np-appt-row__assign, .np-appt-row__meta{ overflow-wrap:anywhere; word-break:break-word; }
.np-appt-row__meta{ font-size:.78rem; color: var(--np-muted); margin-top:.15rem; line-height:1.45; }
/* Pharmacy Prescriptions medication list: one block per medicine instead of
   a single <br/>-joined line, so each line wraps independently on its own
   width — same non-clipping, non-truncating behavior as every other
   descriptive-text block in Admin/Doctor/Receptionist (see
   .np-appt-row__name/__assign/__meta above). */
.np-rx-med-line{ overflow-wrap:anywhere; word-break:break-word; white-space:normal; }
.np-rx-med-line + .np-rx-med-line{ margin-top:.1rem; }
.np-appt-row__right{ text-align:right; flex-shrink:0; }
/* On phones the fixed-width action column squeezed the text body and forced
   medication/detail lines to clip. Stack the row so content takes the full
   width and actions drop underneath, left-aligned and wrapping cleanly. */
@media (max-width:560px){
  .np-appt-row{ flex-direction:column; gap:.5rem; }
  .np-appt-row__right{ text-align:left; width:100%; display:flex; flex-wrap:wrap; gap:.4rem; align-items:center; }
}

.tab-pane.hidden{ display:none; }

/* Personalized dashboard welcome header — mirrors the doctor portal's
   .np-welcome tokens so Admin and Receptionist dashboards greet the user
   consistently with a live date/time. Kept compact so it never pushes the
   KPI cards below the fold on mobile. */
.np-welcome{
  display:flex; gap:.9rem; align-items:center; flex-wrap:wrap;
  padding:.8rem 1.05rem; margin:0 0 1rem;
  border-radius:16px;
  background:var(--nk-card);
  border:1px solid var(--np-border);
  box-shadow:0 1px 2px rgba(15,42,71,.04);
}
.np-welcome__main{ flex:1 1 220px; min-width:0; }
.np-welcome__eyebrow{ font-size:.72rem; font-weight:700; letter-spacing:.05em; color:var(--np-muted); text-transform:uppercase; }
.np-welcome__titlerow{ display:flex; align-items:center; gap:.55rem; flex-wrap:wrap; margin-top:.15rem; }
.np-welcome__title{ font-size:1.2rem; font-weight:700; margin:0; color:var(--np-ink); line-height:1.25; font-family:inherit; }
.np-welcome__pill{
  display:inline-flex; align-items:center; gap:.35rem;
  padding:.28rem .7rem; border-radius:999px;
  background:var(--nk-teal-50); border:1px solid var(--nk-teal-100);
  font-size:.76rem; font-weight:600; color:var(--nk-teal-700); white-space:nowrap;
}
html[data-theme="dark"] .np-welcome__pill{ background:rgba(137,188,189,.12); border-color:rgba(137,188,189,.28); color:#B4D7D7; }
.np-welcome__side{ flex:0 0 auto; margin-left:auto; display:flex; align-items:center; gap:.5rem; }
@media (max-width:560px){
  .np-welcome{ padding:.75rem .9rem; }
  .np-welcome__title{ font-size:1.05rem; }
  .np-welcome__side{ width:100%; margin-left:0; }
  .np-welcome__side .np-btn{ flex:1 1 auto; justify-content:center; }
}

/* Intentional bounded scroll container for card/row-based lists (patients,
   prescriptions, certificates, today's queue, recent bills). Without a bound
   these lists grew indefinitely and became unusable on large datasets and on
   mobile. Capped height with its own scroll keeps every module's list
   behaviour consistent and the surrounding page controls reachable. */
.np-scroll-list{
  max-height: 62vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
@media (max-width:640px){
  .np-scroll-list{ max-height: 70vh; }
}

.np-notif-row td.np-notif-error{ color:#B91C1C; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size:.78rem; }

.hidden{ display:none !important; }

/* Dark-mode theming for shared components (search, code blocks, --np-*
   variable remap) lives in /assets/neokids-theme.css, which loads after
   this file and is the single source of truth — see the "v3.3.1
   DEFINITIVE dark-mode consolidation" block there. Keeping a second,
   panel-local copy of those rules previously caused this file and
   theme.css to disagree on notification-modal code-block colors
   (var(--nk-surface) here vs the canonical #0B1519 there); the ID-scoped
   selector below made this file win, so the modal was silently a
   different shade of dark than every other code block. Scoped only to
   #notifModal to match that block's specificity so it doesn't drift
   again. */
html[data-theme="dark"] #notifModal .np-code-block,
html[data-theme="dark"] #notifModal pre{
  background: #0B1519 !important;
  border-color: var(--nk-border) !important;
  color: #C7E2E4 !important;
}
.np-empty{ text-align:center; padding:1.5rem .5rem; color:var(--np-muted); }
.np-empty__title{ color: var(--np-ink); font-weight:700; margin-bottom:.25rem; }
.np-empty__sub{ color: var(--np-muted); font-size:.85rem; }

.np-filterbar--appointments,
.np-filterbar--notifications{
  display:grid;
  grid-template-columns:repeat(4, minmax(0, 1fr));
  align-items:end;
  gap:.75rem;
  width:100%;
  max-width:100%;
}
.np-filterbar--appointments .np-filter-control,
.np-filterbar--notifications .np-filter-control{
  display:flex;
  flex-direction:column;
  gap:.35rem;
  min-width:0;
  max-width:100%;
}
.np-filterbar--appointments .np-filter-control--search,
.np-filterbar--notifications .np-filter-control--search{ grid-column:span 2; }
.np-filter-control__label{
  display:block;
  color:var(--np-muted);
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.035em;
  line-height:1.2;
}
.np-filterbar--appointments .np-search,
.np-filterbar--notifications .np-search{
  width:100%;
  min-width:0;
  max-width:100%;
}
.np-filterbar--appointments .np-select,
.np-filterbar--notifications .np-select,
.np-filterbar--appointments input[type="date"],
.np-filterbar--notifications input[type="date"]{
  box-sizing:border-box;
  display:block;
  inline-size:100% !important;
  min-inline-size:0 !important;
  max-inline-size:100% !important;
  min-height:42px;
  overflow:hidden;
  text-overflow:ellipsis;
}
.np-filterbar--appointments select,
.np-filterbar--notifications select{ appearance:auto; }
/* Native date fields previously read as plain text boxes and their calendar
   glyph sat flush against the right edge. Give them the same inner padding as
   other controls, keep the picker indicator inset from the edge, and show a
   pointer cursor so they clearly read as date pickers. */
.np-filterbar--appointments input[type="date"],
.np-filterbar--notifications input[type="date"],
.np-filterbar--toolbar input[type="date"]{
  padding:.5rem .7rem;
  cursor:pointer;
  color-scheme:light;
}
html[data-theme="dark"] .np-filterbar--appointments input[type="date"],
html[data-theme="dark"] .np-filterbar--notifications input[type="date"],
html[data-theme="dark"] .np-filterbar--toolbar input[type="date"]{ color-scheme:dark; }
.np-filterbar--appointments input[type="date"]::-webkit-calendar-picker-indicator,
.np-filterbar--notifications input[type="date"]::-webkit-calendar-picker-indicator,
.np-filterbar--toolbar input[type="date"]::-webkit-calendar-picker-indicator{
  cursor:pointer;
  margin-left:.35rem;
  opacity:.75;
}
.np-filterbar--appointments input[type="date"]::-webkit-calendar-picker-indicator:hover,
.np-filterbar--notifications input[type="date"]::-webkit-calendar-picker-indicator:hover,
.np-filterbar--toolbar input[type="date"]::-webkit-calendar-picker-indicator:hover{ opacity:1; }
.np-filter-actions{
  display:inline-flex;
  align-items:center;
  justify-content:flex-end;
  gap:.5rem;
  grid-column:1 / -1;
  min-width:0;
  flex-wrap:wrap;
}
#apptFilterChips,
#notifCounts{ max-width:100%; overflow:hidden; }
#apptFilterChips .np-chips,
#notifCounts{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:.5rem;
}
#apptFilterChips .np-chip{
  max-width:100%;
  min-width:0;
}
#apptFilterChips .np-chip > span{
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
#notifCounts .np-badge{ max-width:100%; white-space:normal; overflow-wrap:anywhere; }

@media (max-width:720px){
  .np-content{ padding:1rem .75rem 1.5rem; }
  /* Panel heads that pair a title/subtitle with a trailing control (e.g. the
     Pharmacy Prescriptions filter select) used to stay in one non-wrapping
     row, which squeezed the title/subtitle block down to whatever space the
     control's min-width left over — on a long subtitle that meant severe
     wrapping into a very cramped column. Wrap onto two rows on phones so
     the descriptive text always has the full width to lay out in, matching
     the rest of the app. */
  .np-panel__head{ padding:1rem 1rem .5rem; flex-wrap:wrap; }
  .np-panel__head > div:first-child{ min-width:0; flex:1 1 100%; }
  .np-panel__head > .np-select,
  .np-panel__head > .np-input{
    flex:0 0 auto;
    /* This is the actual bug: the base .np-select/.np-input rule sets
       width:100%. The desktop rule above resets that to width:auto so the
       control sizes to its content — this mobile rule only ever capped it
       with max-width:100%, so width:100% kept winning and each select
       still tried to claim the FULL row width. One select doing that is
       invisible; two side by side (Overall Clinic Revenue's month+year
       pickers, Revenue Reports' month+year+doctor+type filters) fight for
       the same full-width space and overflow the panel on phones — this
       is the drill-down/tooltip-adjacent bug that survived the earlier
       markup-only fix. Mirror the desktop reset here, and cap each at
       roughly half the row so a pair sits side by side instead of
       overflowing. */
    width:auto;
    min-width:0;
    max-width:calc(50% - .4rem);
  }
  .np-panel__body{ padding:.5rem 1rem 1rem; }
  .np-filterbar--appointments,
  .np-filterbar--notifications{ grid-template-columns:1fr; gap:.65rem; }
  .np-filterbar--appointments .np-filter-control--search,
  .np-filterbar--notifications .np-filter-control--search,
  .np-filter-actions{ grid-column:auto; }
  .np-filter-actions{
    display:inline-flex;
    justify-content:flex-end;
    width:100%;
  }

  #apptsView .np-table-wrap{
    overflow:visible;
    max-height:none;
    border:0;
    border-radius:0;
    background:transparent;
  }
  #apptsView .np-table,
  #apptsView .np-table tbody{ display:block; width:100%; min-width:0; }
  #apptsView .np-table thead{
    position:absolute;
    width:1px;height:1px;
    margin:-1px;padding:0;
    overflow:hidden;clip:rect(0 0 0 0);
    white-space:nowrap;border:0;
  }
  #apptsView .np-table tr{
    display:block;
    width:100%;
    box-sizing:border-box;
    margin:0 0 .75rem;
    padding:.9rem 1rem;
    background: var(--nk-card);
    border:1px solid var(--np-border);
    border-left-width:3px;
    border-radius:14px;
    box-shadow:var(--np-card-shadow);
  }
  #apptsView .np-table td[data-label]{
    display:grid;
    grid-template-columns:minmax(76px,.55fr) minmax(0,1.45fr);
    gap:.7rem;
    align-items:start;
    width:100%;
    min-width:0;
    padding:.52rem 0;
    text-align:left !important;
    border-bottom:1px dashed var(--np-border);
  }
  #apptsView .np-table td[data-label]::before{
    content:attr(data-label);
    color:var(--np-muted);
    font-size:.68rem;
    font-weight:700;
    letter-spacing:.045em;
    line-height:1.35;
    text-transform:uppercase;
  }
  #apptsView .np-table td[data-label] > *{
    min-width:0;
    max-width:100%;
    overflow-wrap:anywhere;
  }
  #apptsView .np-table td[data-label]:last-child{ border-bottom:0; }
  #apptsView .np-table td[data-label="Patient"],
  #apptsView .np-table td[data-label="Doctor"]{ grid-template-columns:1fr; gap:.2rem; }
  #apptsView .np-table td[data-label="Fee"] > b{ justify-self:end; font-size:1rem; }
  #apptsView .np-table td[colspan]{ display:block; padding:.5rem 0; text-align:center; border:0; }
  #apptsView .np-table tr:hover td{ background:transparent; }
  html[data-theme="dark"] #apptsView .np-table tr{ background:var(--nk-card) !important; border-color:var(--nk-border) !important; }

  /* .np-table--cards mobile transform lives in the shared
     assets/neokids-theme.css (loaded by every portal) so Doctor,
     Receptionist and Pharmacy tables can use it too, not just Admin. */

  #notifView .np-table-wrap{ border:0; background:transparent; }
  #notifView .np-table, #notifView .np-table tbody{ display:block; width:100%; min-width:0; }
  #notifView .np-table thead{ position:absolute; width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0; }
  #notifView .np-table tr.np-notif-row{ display:block; width:100%; box-sizing:border-box; margin:0 0 .75rem; padding:.9rem 1rem; }
  #notifView .np-table tr.np-notif-row td{
    display:grid;
    grid-template-columns:minmax(78px,.55fr) minmax(0,1.45fr);
    gap:.7rem;
    align-items:start;
    width:100%;
    min-width:0;
    padding:.48rem 0 !important;
    border:0 !important;
    text-align:left;
    overflow-wrap:anywhere;
  }
  #notifView .np-table tr.np-notif-row td::before{ min-width:0; content:attr(data-label); }
  #notifView .np-table tr.np-notif-row td.np-notif-error{ white-space:normal !important; overflow:visible !important; text-overflow:clip !important; }
  /* v3.3.2: badges inside the notif mobile card must NEVER stretch to fill the grid cell. */
  #notifView .np-table tr.np-notif-row td > .np-badge,
  #notifView .np-table tr.np-notif-row td span.np-badge{
    display:inline-flex !important;
    width:max-content !important;
    max-width:100% !important;
    justify-self:start !important;
    align-self:center !important;
    flex:0 0 auto !important;
    white-space:nowrap !important;
  }
  /* The status cell may contain two badges (status + direction). Wrap-friendly, hugging. */
  #notifView .np-table tr.np-notif-row td[data-label="Status"]{
    display:grid;
    grid-template-columns:minmax(78px,.55fr) minmax(0,1.45fr);
    align-items:center;
  }
  #notifView .np-table tr.np-notif-row td[data-label="Status"] > .np-badge + .np-badge{
    margin-left:.35rem;
  }
}
@media (min-width:721px) and (max-width:1023px){
  .np-filterbar--appointments,
  .np-filterbar--notifications{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .np-filterbar--appointments .np-filter-control--search,
  .np-filterbar--notifications .np-filter-control--search{ grid-column:1 / -1; }
}
@media (max-width:380px){
  .np-filter-actions{ grid-template-columns:1fr; }
}

.np-shell{ overflow:hidden; }
.np-main{
  min-width:0;
  min-height:0;
  height:100vh;
  height:100dvh;
  display:flex;
  flex-direction:column;
  overflow:hidden;
}

.np-header{
  position:sticky;
  top:0;
  z-index:42;
  background: var(--nk-card);
}
.np-header__inner{
  min-height:68px;
  align-items:center;
}
.np-header__title{ min-width:0; overflow:hidden; }
.np-header__page-title,
.np-header__page-subtitle{
  overflow:hidden;
  text-overflow:ellipsis;
}
#notifCounts,
#apptFilterChips{
  max-width:100%;
  min-width:0;
}
#notifCounts{
  display:flex;
  flex-wrap:wrap;
  gap:.5rem;
  overflow:hidden;
}
#apptFilterChips .np-chips{
  display:flex;
  flex-wrap:wrap;
  gap:.5rem;
  max-width:100%;
}
#apptFilterChips .np-chip,
#notifCounts .np-badge{
  max-width:100%;
  min-width:0;
}
#apptFilterChips .np-chip > span{
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
/* Root cause of "Apply/Clear stretched on Revenue/Settlements/Invoices":
   this was `display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr))`.
   auto-fit collapses unused track columns, so whenever the buttons landed
   alone on a wrapped row, they'd stretch to fill the *entire* row width
   (the classic auto-fit "lonely leftover item" bug) — mixing fixed-size
   buttons with fluid dropdowns in the same grid tracks was the wrong
   pattern. Flexbox fixes this at the source: selects are allowed to grow,
   the actions group never does, regardless of how items wrap. */
.np-filterbar--toolbar{
  display:flex;
  flex-wrap:wrap;
  gap:.75rem;
  align-items:end;
  width:100%;
}
.np-filterbar--toolbar > .np-select,
.np-filterbar--toolbar > input[type="date"],
.np-filterbar--toolbar > .np-search{
  flex: 1 1 160px;
  min-width: 140px;
  max-width: 100%;
}
.np-filterbar--toolbar > .np-btn,
.np-filterbar--toolbar > .np-filter-actions{
  flex: 0 0 auto;
  width: auto;
}
.np-filterbar--toolbar > .np-filter-actions{ margin-left: auto; }
.np-filterbar--appointments,
.np-filterbar--notifications{
  width:100%;
  max-width:100%;
}
.np-filterbar--appointments .np-search,
.np-filterbar--notifications .np-search,
.np-filterbar--appointments .np-select,
.np-filterbar--notifications .np-select,
.np-filterbar--appointments input[type="date"],
.np-filterbar--notifications input[type="date"]{
  width:100%;
  min-width:0;
}
.np-filterbar--appointments .np-filter-control,
.np-filterbar--notifications .np-filter-control{
  min-width:0;
}
.np-filter-actions{ align-items:stretch; }
.np-filter-actions .np-btn{ min-width:0; }
.np-table-wrap--responsive{
  overflow:auto;
  -webkit-overflow-scrolling:touch;
}
@media (max-width:1023px){
  body.np-drawer-open{ overflow:hidden; }
  .np-sidebar{
    position:fixed;
    left:0;
    top:0;
    bottom:0;
    width:min(280px, 82vw);
    max-width:82vw;
    /* v3.3.2: strictly above backdrop; isolate stacking; never inherit blur. */
    z-index:50;
    isolation:isolate;
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
    background: var(--nk-card);
    backdrop-filter:none;
    -webkit-backdrop-filter:none;
  }
  .np-backdrop{ z-index:44; }
  .np-sidebar.is-open{ pointer-events:auto; }
}
@media (max-width:720px){
  .np-content{ padding:1rem .85rem 1.5rem; }
  .np-panel__head{ padding:1rem; }
  .np-panel__body{ padding:.85rem 1rem 1rem; }
  .np-header__inner{
    gap:.75rem;
    padding:.75rem max(.9rem, env(safe-area-inset-right)) .75rem max(.9rem, env(safe-area-inset-left));
  }
  .np-header__page-title{
    font-size:1rem;
    line-height:1.15;
    white-space:nowrap;
  }
  .np-header__page-subtitle{
    font-size:.74rem;
    line-height:1.2;
    white-space:nowrap;
  }
  .np-profile{
    margin-left:auto;
    padding-right:max(0px, env(safe-area-inset-right));
  }
  .np-profile__trigger{
    padding:.35rem .45rem .35rem .35rem;
    border-radius:12px;
  }
  .np-profile__menu{
    right:0;
    max-width:min(280px, calc(100vw - 24px));
  }
  .np-filterbar--toolbar > .np-select,
  .np-filterbar--toolbar > input[type="date"]{ flex-basis: calc(50% - .4rem); }
  #settlementsView .np-table-wrap,
  #invoicesView .np-table-wrap,
  #revenueView .np-table-wrap,
  #notifView .np-table-wrap,
  #apptsView .np-table-wrap,
  #centresView .np-table-wrap,
  #receptionistsView .np-table-wrap,
  #pharmUsersView .np-table-wrap,
  #certsView .np-table-wrap,
  #pharmBillsView .np-table-wrap,
  #invView .np-table-wrap,
  #billsView .np-table-wrap,
  #recInvoicesView .np-table-wrap,
  #onlineInvoicesView .np-table-wrap,
  #auditView .np-table-wrap{
    overflow:visible;
    max-height:none;
    border:0;
    background:transparent;
  }
  #settlementsView .np-table,
  #settlementsView .np-table tbody,
  #invoicesView .np-table,
  #invoicesView .np-table tbody,
  #revenueView .np-table,
  #revenueView .np-table tbody,
  #centresView .np-table,
  #centresView .np-table tbody,
  #receptionistsView .np-table,
  #receptionistsView .np-table tbody,
  #pharmUsersView .np-table,
  #pharmUsersView .np-table tbody,
  #certsView .np-table,
  #certsView .np-table tbody,
  #pharmBillsView .np-table,
  #pharmBillsView .np-table tbody,
  #invView .np-table,
  #invView .np-table tbody,
  #billsView .np-table,
  #billsView .np-table tbody,
  #recInvoicesView .np-table,
  #onlineInvoicesView .np-table,
  #recInvoicesView .np-table tbody,
  #onlineInvoicesView .np-table tbody,
  #auditView .np-table,
  #auditView .np-table tbody{
    display:block;
    width:100%;
    min-width:0;
  }
  #settlementsView .np-table thead,
  #invoicesView .np-table thead,
  #revenueView .np-table thead,
  #centresView .np-table thead,
  #receptionistsView .np-table thead,
  #pharmUsersView .np-table thead,
  #certsView .np-table thead,
  #pharmBillsView .np-table thead,
  #invView .np-table thead,
  #billsView .np-table thead,
  #recInvoicesView .np-table thead,
  #onlineInvoicesView .np-table thead,
  #auditView .np-table thead{
    position:absolute;
    width:1px;
    height:1px;
    margin:-1px;
    overflow:hidden;
    clip:rect(0 0 0 0);
    white-space:nowrap;
    border:0;
  }
  #settlementsView .np-table tr,
  #invoicesView .np-table tr,
  #revenueView .np-table tr,
  #centresView .np-table tr,
  #receptionistsView .np-table tr,
  #pharmUsersView .np-table tr,
  #certsView .np-table tr,
  #pharmBillsView .np-table tr,
  #invView .np-table tr,
  #billsView .np-table tr,
  #recInvoicesView .np-table tr,
  #onlineInvoicesView .np-table tr,
  #auditView .np-table tr{
    display:block;
    width:100%;
    margin:0 0 .75rem;
    padding:.9rem 1rem;
    background: var(--nk-card);
    border:1px solid var(--np-border);
    border-radius:14px;
    box-shadow:var(--np-card-shadow);
  }
  #settlementsView .np-table td[data-label],
  #invoicesView .np-table td[data-label],
  #revenueView .np-table td[data-label],
  #centresView .np-table td[data-label],
  #receptionistsView .np-table td[data-label],
  #pharmUsersView .np-table td[data-label],
  #certsView .np-table td[data-label],
  #pharmBillsView .np-table td[data-label],
  #invView .np-table td[data-label],
  #billsView .np-table td[data-label],
  #recInvoicesView .np-table td[data-label],
  #onlineInvoicesView .np-table td[data-label],
  #auditView .np-table td[data-label]{
    display:grid;
    grid-template-columns:minmax(84px,.6fr) minmax(0,1.4fr);
    gap:.7rem;
    align-items:start;
    width:100%;
    min-width:0;
    padding:.55rem 0;
    border-bottom:1px dashed var(--np-border);
    text-align:left !important;
    overflow-wrap:anywhere;
  }
  #settlementsView .np-table td[data-label]::before,
  #invoicesView .np-table td[data-label]::before,
  #revenueView .np-table td[data-label]::before,
  #centresView .np-table td[data-label]::before,
  #receptionistsView .np-table td[data-label]::before,
  #pharmUsersView .np-table td[data-label]::before,
  #certsView .np-table td[data-label]::before,
  #pharmBillsView .np-table td[data-label]::before,
  #invView .np-table td[data-label]::before,
  #billsView .np-table td[data-label]::before,
  #recInvoicesView .np-table td[data-label]::before,
  #onlineInvoicesView .np-table td[data-label]::before,
  #auditView .np-table td[data-label]::before{
    content:attr(data-label);
    color:var(--np-muted);
    font-size:.68rem;
    font-weight:700;
    letter-spacing:.045em;
    text-transform:uppercase;
    line-height:1.35;
  }
  #settlementsView .np-table td[data-label]:last-child,
  #invoicesView .np-table td[data-label]:last-child,
  #revenueView .np-table td[data-label]:last-child,
  #centresView .np-table td[data-label]:last-child,
  #receptionistsView .np-table td[data-label]:last-child,
  #pharmUsersView .np-table td[data-label]:last-child,
  #certsView .np-table td[data-label]:last-child,
  #pharmBillsView .np-table td[data-label]:last-child,
  #invView .np-table td[data-label]:last-child,
  #billsView .np-table td[data-label]:last-child{ border-bottom:0; }
  #recInvoicesView .np-table td[data-label]:last-child,
  #onlineInvoicesView .np-table td[data-label]:last-child,
  #auditView .np-table td[data-label]:last-child{ border-bottom:0; }
  #settlementsView .np-table td[data-label="Doctor"],
  #invoicesView .np-table td[data-label="Doctor"],
  #recInvoicesView .np-table td[data-label="Doctor"],
  #onlineInvoicesView .np-table td[data-label="Doctor"]{ grid-template-columns:1fr; gap:.25rem; }
  #settlementsView .np-table td[data-label="Actions"],
  #invoicesView .np-table td[data-label="Actions"],
  #revenueView .np-table td[data-label="Actions"],
  #centresView .np-table td[data-label="Actions"],
  #receptionistsView .np-table td[data-label="Actions"],
  #pharmUsersView .np-table td[data-label="Actions"],
  #certsView .np-table td[data-label="Actions"],
  #pharmBillsView .np-table td[data-label="Actions"],
  #invView .np-table td[data-label="Actions"],
  #billsView .np-table td[data-label="Actions"]{ grid-template-columns:1fr; }
  #centresView .np-table td[data-label="Address"],
  #centresView .np-table td[data-label="Staff / Appts"],
  #receptionistsView .np-table td[data-label="Assignments (Doctor @ Clinic)"],
  #receptionistsView .np-table td[data-label="Permissions"],
  #pharmUsersView .np-table td[data-label="Responsible doctors"]{ grid-template-columns:1fr; gap:.25rem; }
  #settlementsView .np-table td[colspan],
  #invoicesView .np-table td[colspan],
  #revenueView .np-table td[colspan],
  #centresView .np-table td[colspan],
  #receptionistsView .np-table td[colspan],
  #pharmUsersView .np-table td[colspan],
  #certsView .np-table td[colspan],
  #pharmBillsView .np-table td[colspan],
  #invView .np-table td[colspan],
  #billsView .np-table td[colspan]{
    display:block;
    padding:.25rem 0;
    border:0;
    text-align:center;
  }
  #recInvoicesView .np-table td[colspan],
  #onlineInvoicesView .np-table td[colspan],
  #auditView .np-table td[colspan]{
    display:block;
    padding:.25rem 0;
    border:0;
    text-align:center;
  }
  #settlementsView .np-empty,
  #invoicesView .np-empty,
  #revenueView .np-empty,
  #centresView .np-empty,
  #receptionistsView .np-empty,
  #pharmUsersView .np-empty,
  #certsView .np-empty,
  #pharmBillsView .np-empty,
  #invView .np-empty,
  #billsView .np-empty{ padding:1.25rem .75rem; }
  #recInvoicesView .np-empty,
  #onlineInvoicesView .np-empty,
  #auditView .np-empty{ padding:1.25rem .75rem; }
}
@media (max-width:520px){
  .np-filterbar--toolbar > .np-select,
  .np-filterbar--toolbar > input[type="date"]{ flex-basis:100%; }
  .np-filterbar--toolbar > .np-filter-actions{ flex-basis:100%; margin-left:0; width:100%; }
  .np-filterbar--toolbar > .np-filter-actions > .np-btn{ flex:1 1 0; }
  .np-filterbar--appointments,
  .np-filterbar--notifications{ grid-template-columns:1fr; }
}
@media (max-width:420px){
  .np-header__inner{ min-height:60px; }
  .np-header__page-subtitle{ display:none; }
  .np-profile__trigger{ padding:.32rem; }
  .np-filter-actions{ grid-template-columns:1fr; }
}

.np-notif-template-select{
  padding-top: .55rem;
  padding-bottom: .55rem;
  line-height: 1.35;
  font-weight: 500;
  min-width: 260px;
}
.np-notif-template-select optgroup{
  font-weight: 700;
  font-style: normal;
  color: var(--np-primary-600);
  background: var(--nk-teal-50);
  padding: .25rem 0;
  letter-spacing: .02em;
  text-transform: uppercase;
  font-size: .78rem;
}
.np-notif-template-select option{
  font-weight: 500;
  color: var(--np-text);
  padding: .35rem .55rem;
  background: var(--nk-card);
}
.np-notif-template-select option:disabled{
  color: var(--np-muted);
  font-style: italic;
}
html[data-theme="dark"] .np-notif-template-select optgroup{
  background: rgba(255,255,255,.04);
  color: var(--np-primary);
}
html[data-theme="dark"] .np-notif-template-select option{
  background: transparent;
  color: #E6EEF7;
}

.np-uuid-card{
  margin: 0 0 1rem;
  padding: .7rem .8rem .8rem;
  border: 1px solid var(--np-border);
  border-radius: 12px;
  background: linear-gradient(180deg, #F8FBFD 0%, #F1F6FA 100%);
}
.np-uuid-card__label{
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--np-primary-600);
  margin-bottom: .4rem;
}
.np-uuid-card__label svg{ width: 14px; height: 14px; }
.np-uuid-card__row{
  display: flex;
  align-items: stretch;
  gap: .45rem;
}
.np-uuid-card__value{
  flex: 1;
  min-width: 0;
  padding: .5rem .65rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .82rem;
  color: var(--np-ink);
  background: var(--nk-card);
  border: 1px solid var(--np-border);
  border-radius: 8px;
  outline: none;
  cursor: text;
  user-select: all;
}
.np-uuid-card__value:focus{
  border-color: var(--np-primary);
  box-shadow: 0 0 0 3px rgba(137,188,189,.20);
}
.np-uuid-card__copy{
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .5rem .75rem;
  font-size: .78rem;
  font-weight: 600;
  color: var(--np-primary-600);
  background: var(--nk-card);
  border: 1px solid var(--np-border);
  border-radius: 8px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.np-uuid-card__copy svg{ width: 14px; height: 14px; }
.np-uuid-card__copy:hover{
  background: var(--np-mint);
  border-color: var(--np-primary);
}
.np-uuid-card__copy.is-copied{
  background: #E7F5EA;
  color: #16794A;
  border-color: #A7D7B4;
}
html[data-theme="dark"] .np-uuid-card__value{
  background: rgba(255,255,255,.05);
  color: #E6EEF7;
  border-color: rgba(255,255,255,.10);
}
html[data-theme="dark"] .np-uuid-card__copy{
  background: rgba(255,255,255,.04);
  color: var(--np-primary);
  border-color: rgba(255,255,255,.10);
}

html, body{ max-width:100%; overflow-x:hidden; }

@media (max-width:1023px){
  img, svg, video, canvas, iframe{ max-width:100%; height:auto; }
  .np-content, .np-panel, .np-panel__body, .np-panel__head{
    min-width:0;
    max-width:100%;
  }
  /* Root cause of clipped chart tooltips: setting only overflow-x here
     implicitly computed overflow-y to "auto" as well (per the CSS overflow
     spec), which cut off anything that renders above a panel's box — like
     the chart tooltip. Tables already scroll via .np-table-wrap, so this
     doesn't need to apply to every panel body, and we make overflow-y
     explicit so it can never silently clip content again. */
  .np-panel__body:has(.np-table-wrap){ overflow-x:auto; overflow-y:visible; }
  .np-panel__body > *{ min-width:0; }
  /* Explicit fallback (doesn't rely on :has() support) — the chart panel
     body must never clip vertically, since the tooltip renders above it. */
  #dashSecondGrid .np-panel__body{ overflow:visible; }
}

@media (max-width:640px){
  .np-modal{ padding:.5rem; align-items:flex-end; }
  .np-modal__panel{
    max-width:100%;
    width:100%;
    max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 1rem);
    max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 1rem);
    border-radius: 18px 18px 14px 14px;
  }
  .np-modal__head{ padding:.85rem 1rem; }
  .np-modal__body{ padding: 1rem; }
}

@media (max-width:640px){
  .np-drawer__panel{
    max-width:100%;
    width:100%;
    border-radius: 0;
  }
  .np-drawer__head{ padding:.85rem 1rem; }
  .np-drawer__body{ padding:.85rem 1rem 1rem; }
}

@media (max-width:640px){
  .np-profile__menu{
    right:0;
    max-width: calc(100vw - 24px);
    max-height: calc(100vh - 100px);
    max-height: calc(100dvh - 100px);
    overflow-y:auto;
  }
  .np-profile__meta{ display:none; }
}

@media (max-width:640px){
  /* Doctor name and clinic pill were hard single-line ellipsis at any
     width, so a longer doctor or clinic name got cut mid-word on a
     phone even though every card in the app now wraps freely. Let
     these two wrap onto a second line on phones instead of truncating
     — role/qualification stay single-line since they're short labels,
     not identifying information. */
  .np-doc-card__name{
    white-space:normal;
    overflow:visible;
    text-overflow:clip;
    display:-webkit-box;
    -webkit-line-clamp:2;
    -webkit-box-orient:vertical;
  }
  .np-doc-card__clinic{
    white-space:normal;
    overflow:visible;
    text-overflow:clip;
    max-width:100%;
  }
}

@media (max-width:420px){
  .np-doc-card{ padding:1rem .95rem .85rem; }
  .np-doc-card__actions{
    grid-template-columns: 1fr 1fr;
    gap:.35rem;
  }
  .np-doc-card__actions .np-btn{
    grid-column: span 1;
    font-size:.74rem;
    padding:.42rem .3rem;
  }
  .np-doc-card__actions .np-btn--icon{
    grid-column: 2 / 3;
    width:100%;
    justify-self:end;
  }
}

@media (max-width:360px){
  .np-kpi{ padding:.9rem 1rem; }
  .np-kpi__value{ font-size:1.4rem; }
}

@media (max-width:520px){
  .np-tabbar{
    width:100%;
    max-width:100%;
    overflow-x:auto;
    -webkit-overflow-scrolling:touch;
  }
  .np-tab{ white-space:nowrap; flex-shrink:0; }
}

@media (max-width:360px){
  .np-header__inner{ padding:.65rem .75rem; gap:.5rem; }
  .np-header__page-title{ font-size:.95rem; }
}

.np-btn{ max-width:100%; }
.np-search{ min-width:0; }

@media (max-width:640px){
  .np-notif-template-select{
    min-width: 0;
    width: 100%;
  }
}

@media (max-width:1023px){
  .np-table-wrap{ max-width:100%; -webkit-overflow-scrolling:touch; }
}

.np-shell, .np-main{ min-width:0; }

@media (max-width:380px){
  .np-grid-2{ grid-template-columns:1fr; }
}

/* ── Mobile card consistency pass ──────────────────────────────────────
   Every table-to-card view on phones (Settlements, Invoices, Revenue,
   Reception/Online Invoices, Centres, Receptionists, Pharmacy Users,
   Certificates, Pharmacy/Reception Bills, Audit, Appointments,
   Notifications — and by extension the Receptionist & Pharmacy portals,
   which load this same stylesheet) previously had two inconsistencies:

   1. Cells authored for a desktop table with an inline
      `white-space:nowrap` (mainly "Actions" cells holding 2-3 buttons)
      kept that nowrap on mobile too. On a card only ~300px wide, a
      nowrap run of buttons doesn't shrink — it forces the whole card
      to overflow sideways, which reads as "text getting cut off".
      Since author-stylesheet !important always beats a plain inline
      style, one rule here fixes it everywhere at once.

   2. Numeric columns (Amount, Total, Fee, TDS, Stock, etc.) are
      right-aligned in the desktop table via inline
      `style="text-align:right"`, but the shared mobile card rule forces
      every cell to `text-align:left !important` (so the field label and
      value line up on the left). That's correct for text fields but
      left numbers looking randomly mis-aligned next to the same numbers
      shown right-aligned elsewhere (e.g. the Fee column in Appointments,
      which already special-cases this). Detecting the desktop
      right-align via the inline style itself — rather than hard-coding
      every column name per view — re-applies right alignment
      consistently on every numeric cell, in every card, everywhere. */
@media (max-width:720px){
  .np-table td[data-label]{
    white-space:normal !important;
  }
  .np-table td[data-label][style*="text-align:right"],
  .np-table td[data-label][style*="text-align: right"]{
    text-align:right !important;
    justify-self:end;
  }
}
