/* Practeca — the design system. The only place values live.

   2026-09 REDESIGN. Rebuilt from the Tgsi redesign of this prototype.
   The rule that produced it: a DESIGN choice comes from the redesign, a
   LOGIC / feature / option choice stays as this prototype already had it.
   Class names are unchanged, so all seven surfaces inherit this at once.

   What the redesign changed, and why it reads as expensive:
   · The ground is paper (#F4F1EC), not off-white. Cards float on warmth.
   · Headings are LARGE and LIGHT — clamp(38→60px) at weight 500, not 30px
     at 700. Scale carries the authority; weight would only shout.
   · Cards get 20px radius and 27px padding. Air is the luxury.
   · Depth is one long, soft, low-opacity drop (…34px -22px), never a cloud.
   · Identity is a rounded SQUARE (a programme), state is a CIRCLE (a dot).
     Two shapes means you never have to read the colour to know which it is.
   · Exactly one dark gradient card per screen — the money panel. It is the
     jewel; everything else is white. Two would make it a pattern, not a
     moment.

   Type: Instrument Sans for everything human. IBM Plex Mono for machine
   identifiers only — file numbers, clock times, counts. Arabic keeps IBM
   Plex Sans Arabic; Instrument Sans has no Arabic coverage.

   ACCESSIBILITY NOTE (deliberate, single deviation from the redesign):
   the redesign's muted grey #8A8E87 is 3.33:1 on white, which fails AA for
   the 11.5px small-caps labels it was used on, and scripts/audit.mjs is
   green. The hue family is kept exactly; the TEXT step is darkened to
   #6A6E68 (5.2:1 on white, 4.6:1 on the ground). #8A8E87 survives as
   --n-400 for decorative non-text only. */

:root {
  /* ---- Neutral ramp — WARM PAPER. Never mix a cool grey into this. ---- */
  --n-0:  #FBF9F6;   /* sunk: input fill, hover well, inset panel */
  --n-25: #F4F1EC;   /* PAGE GROUND — paper, not off-white */
  --n-50: #EFECE6;   /* closed column, quiet chip, table head */
  --n-100:#E7E3DC;   /* THE HAIRLINE. does most of the work */
  --n-200:#D3CEC4;   /* dashed AI border, retired edge, "no programme" */
  --n-400:#8A8E87;   /* DECORATIVE ONLY — placeholder, icon, rule. never a label */
  --n-500:#6A6E68;   /* secondary text + every small-caps label (AA on both grounds) */
  --n-600:#5A605B;   /* nav label, pill text */
  --n-700:#4C544F;   /* body ink */
  --n-800:#16211F;   /* titles, headings — the redesign's ink */

  /* ---- Colour is spent, not sprinkled ---- */
  --teal:        #0F766E;  /* the only action colour */
  --teal-hover:  #0B4F49;
  /* The redesign expressed these as color-mix(in oklab, …). They are baked to
     static hex here on purpose: computed color-mix stays in oklab() form, which
     scripts/audit.mjs cannot parse (it read them as near-black and produced 12
     phantom contrast failures). Static hex also keeps the file:// prototype
     working in browsers without color-mix. Values are the exact oklab results. */
  --teal-100:    #EBF2F1;  /* accs */
  --teal-200:    #C6DAD7;  /* accb */
  --teal-deep:   #135852;  /* accd — text on a tint */
  --teal-quiet:  #4C8B84;  /* scheduled-but-not-actionable */

  /* The navigation rail is dark — the export's near-black, with its cream ink. */
  --rail-bg: #12211F;
  --rail-fg: #EFEBE3;

  --brass:    #A2814F;     /* money, and only money */
  --brass-lt: #D8C9AE;     /* a link inside the dark card */

  --rose:    #B07BA0;      /* maternal / pregnancy programme identity */
  --rose-50: #F7F1F5;
  --rose-200:#E4CFDE;
  --rose-700:#6E4463;

  --amber:    #A96A12;     /* warns */
  --amber-50: #FDF6EC;
  --amber-200:#EFE0C8;
  --amber-700:#7A4C0B;

  --red:      #B3261E;     /* danger */
  --red-50:   #FCF3F1;
  --red-200:  #EBD3CE;
  --red-700:  #7A1C16;

  --emerald:    #5F8F76;   /* done */
  --emerald-50: #F1F6F2;
  --emerald-200:#D2E3D7;
  --emerald-700:#3C6350;

  /* Programme identity — a rounded SQUARE, never a circle. Data-driven:
     a programme carries its colour, chrome never borrows one. */
  --prog-pregnancy: #B07BA0;
  --prog-postpartum:#7E8FB5;
  --prog-wellbaby:  #7FA08C;
  --prog-none:      #D3CEC4;

  /* Muted warm avatar hues — the only other place hue variety is allowed */
  --av-1:#B08968; --av-2:#8A7F6B; --av-3:#7A6A4F; --av-4:#3F6C96;

  /* ---- Depth: a hairline plus ONE long soft drop ---- */
  --e-subtle:  0 1px 1px rgba(22,33,31,.03);
  --e-card:    0 1px 2px rgba(22,33,31,.04), 0 14px 34px -22px rgba(22,33,31,.24);
  --e-raised:  0 1px 2px rgba(22,33,31,.05), 0 18px 40px -20px rgba(22,33,31,.30);
  --e-float:   0 12px 32px -12px rgba(22,33,31,.26);
  --e-overlay: 0 28px 64px -20px rgba(22,33,31,.34);

  --r-input: 14px;
  --r-card:  20px;
  --r-chip:  11px;   /* the soft-corner row / quiet button */
  --r-pill:  999px;
  --r-sq:    3px;    /* the programme square */

  --pad-card: 27px;
  --gap-zone: 20px;
  --w-sidebar: 15rem;
  --h-topbar: 3.5rem;
  --w-content: 1640px;
  --touch: 44px;

  --ease: cubic-bezier(.4, 0, .2, 1);
  --t-hover: 150ms;
  --t-panel: 200ms;
  --t-move:  300ms;

  /* The tail of each stack is spelled out on purpose. A stack that ends at
     system-ui gives the browser one candidate for a glyph our own faces do not
     carry (→ ← ↔ ≤ are all absent from Instrument Sans and IBM Plex), and a
     browser that narrows font fallback — Brave's fingerprint protection does —
     then draws a tofu box instead of falling through. Named faces it will use. */
  --font:      'Instrument Sans', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Segoe UI Symbol', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, 'Liberation Mono', monospace;
  --font-ar:   'IBM Plex Sans Arabic', 'Instrument Sans', 'Segoe UI', Tahoma, Arial, sans-serif;
}

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--n-25);
  color: var(--n-800);
  font-family: var(--font);
  font-size: 15.5px;
  line-height: 1.5;
  letter-spacing: -.005em;
  text-wrap: pretty;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--teal); text-decoration: none; }
a:hover { color: var(--teal-hover); text-decoration: underline; text-underline-offset: 2px; }
button { font: inherit; color: inherit; }
::selection { background: rgba(15,118,110,.16); }
:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes soft { from { opacity: 0; } to { opacity: 1; } }

/* ---------- 3. Type — scale carries the authority, not weight ---------- */
.t-display {
  font-size: clamp(34px, 4.4vw, 56px); font-weight: 500;
  letter-spacing: -.028em; line-height: 1.05; color: var(--n-800);
}
.t-title   { font-size: 24px; font-weight: 500; letter-spacing: -.022em; line-height: 1.2; color: var(--n-800); }
.t-title-s { font-size: 18px; font-weight: 500; letter-spacing: -.018em; color: var(--n-800); }
.t-card    { font-size: 16px; font-weight: 500; letter-spacing: -.012em; color: var(--n-800); }
.t-body    { font-size: 15px; font-weight: 400; letter-spacing: -.005em; color: var(--n-700); }
.t-meta    { font-size: 14px; letter-spacing: 0; color: var(--n-500); }
.t-small   { font-size: 12.5px; letter-spacing: 0; color: var(--n-500); }
/* Section label. Wide caps, always --n-500, never --n-400. */
.t-label   {
  font-size: 11.5px; font-weight: 500; letter-spacing: .16em;
  text-transform: uppercase; color: var(--n-500); font-variant-numeric: tabular-nums;
}
/* The big number in a stat card or the dark panel */
.t-stat    { font-size: 31px; font-weight: 640; letter-spacing: -.015em; line-height: 1; color: var(--n-800); font-variant-numeric: tabular-nums; }
.t-num     { font-variant-numeric: tabular-nums; }
/* Machine identifiers ONLY — file numbers, clock times, counts */
.t-mono    { font-family: var(--font-mono); font-size: 13px; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
/* Placeholder is the ONLY text use of --n-400 */
.t-placeholder { color: var(--n-400); }

/* Arabic: swap the face, kill the tracking, open the leading. */
[dir="rtl"], [lang="ar"] { font-family: var(--font-ar); }
[dir="rtl"] *, [lang="ar"] * {
  font-family: var(--font-ar) !important;
  letter-spacing: normal !important;
  line-height: 1.65;
}
/* …except the identifier face, which stays mono in both directions —
   a file number is not language. */
[dir="rtl"] .t-mono, [lang="ar"] .t-mono { font-family: var(--font-mono) !important; }

/* ---------- 4. Surfaces ---------- */
.card {
  background: #fff;
  border: 1px solid var(--n-100);
  border-radius: var(--r-card);
  box-shadow: var(--e-card);
  padding: var(--pad-card);
}
.card--flush { padding: 0; overflow: hidden; }        /* for hairline lists */
.card--hoverable { transition: box-shadow var(--t-hover) var(--ease), border-color var(--t-hover) var(--ease); }
.card--hoverable:hover { box-shadow: var(--e-raised); border-color: var(--n-200); }
.card--retired { opacity: .55; }                       /* calm history, never absence */
.card--sunk { background: var(--n-0); box-shadow: none; }

/* THE JEWEL. One per screen, and only for money. */
.card--dark {
  background: linear-gradient(155deg, #12211F, #0A1413);
  border: 0; color: #EFEBE3; box-shadow: var(--e-card);
  border-radius: var(--r-card); padding: var(--pad-card);
}
.card--dark .t-label { color: #EFEBE3; opacity: .5; }
.card--dark .t-stat  { color: #EFEBE3; }
.card--dark a, .card--dark .link { color: var(--brass-lt); }
.card--dark .rule { height: 1px; background: rgba(255,255,255,.12); margin: 14px 0; }

/* Hairline list: rows separated by a rule, no zebra */
.rows > * + * { border-top: 1px solid var(--n-100); }
.row { display: flex; align-items: center; gap: 12px; padding: 14px var(--pad-card); min-height: var(--touch); }
.row--click { cursor: pointer; transition: background var(--t-hover) var(--ease); width: 100%; text-align: start; }
.row--click:hover { background: var(--n-0); }
/* The quiet, soft-cornered row used inside a panel (What needs you) */
.row--soft { padding: 9px 8px; border-radius: var(--r-chip); align-items: flex-start; gap: 10px; min-height: 0; }

/* ---------- 4b. Marks we draw — never a font character ----------
   Chevrons, ticks, crosses, boxes and flags used to be literal characters in
   the markup: "‹", "›", "✓", "✕", "☐". A character only appears if the
   face the browser lands on happens to carry it, and that bet loses often:
   ✓ ✕ ☐ are in none of our three webfonts and in none of Segoe UI either,
   and the back chevron drew as a tofu box (an outlined square with 20 39 in it,
   the codepoint of "‹") in a browser that narrows webfont fallback.

   So they are shapes now — one SVG mask painted in currentColor. They inherit
   colour, scale with font-size, mirror in RTL, and cannot go missing. Same
   Lucide geometry as the inline SVGs in shared.js, so the set stays one family.

   Usage:  <span class="i-mark i-check"></span>       — 1em, inherits colour
           <span class="chev"></span>                 — trailing row chevron
           <span class="backchev"></span>             — leading back chevron */
.i-mark {
  display: inline-block; flex: none;
  inline-size: 1em; block-size: 1em; vertical-align: -.14em;
  background: currentColor;
  -webkit-mask: var(--i) center / contain no-repeat;
          mask: var(--i) center / contain no-repeat;
}
/* Direction-aware marks mirror with the document, like .chev always has. */
[dir="rtl"] .i-flip { transform: scaleX(-1); }

.i-chev-start { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 18-6-6 6-6'/%3E%3C/svg%3E"); }
.i-chev-end   { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E"); }
.i-check      { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E"); }
.i-x          { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E"); }
.i-box        { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.9'%3E%3Crect width='17' height='17' x='3.5' y='3.5' rx='3'/%3E%3C/svg%3E"); }
.i-bulb       { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 14c.2-1 .7-1.7 1.5-2.5A5.6 5.6 0 0 0 18 8a6 6 0 0 0-12 0c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5'/%3E%3Cpath d='M9 18h6'/%3E%3Cpath d='M10 22h4'/%3E%3C/svg%3E"); }
.i-arrow-end  { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E"); }
.i-swap       { --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m8 3-4 4 4 4'/%3E%3Cpath d='M4 7h16'/%3E%3Cpath d='m16 21 4-4-4-4'/%3E%3Cpath d='M20 17H4'/%3E%3C/svg%3E"); }

/* The leading chevron on a "back to the list" button. Sits inside .btn, whose
   own 8px gap is the whole spacing — no margin of its own. */
.backchev {
  display: inline-block; flex: none;
  inline-size: 1.05em; block-size: 1.05em; vertical-align: -.14em;
  background: currentColor;
  -webkit-mask: var(--i) center / contain no-repeat;
          mask: var(--i) center / contain no-repeat;
  --i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 18-6-6 6-6'/%3E%3C/svg%3E");
}
[dir="rtl"] .backchev { transform: scaleX(-1); }

/* ---------- 5. Badges — STATE LIVES IN THE DOT ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  background: #fff; border: 1px solid var(--n-100); border-radius: var(--r-pill);
  padding: 3px 10px; box-shadow: var(--e-subtle);
  font-size: 12px; font-weight: 500; color: var(--n-600); white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--dot, var(--n-400)); flex: none; }
.badge--nodot::before { display: none; }
.badge[data-state="live"], .badge[data-state="booked"] { --dot: var(--teal); }
.badge[data-state="new"]      { --dot: var(--teal); }
.badge[data-state="waiting"], .badge[data-state="arrived"], .badge[data-state="warn"] { --dot: var(--amber); }
.badge[data-state="done"]     { --dot: var(--emerald); }
.badge[data-state="draft"], .badge[data-state="cancelled"] { --dot: var(--n-400); }
.badge[data-state="maternal"] { --dot: var(--rose); border-color: var(--rose-200); color: var(--rose-700); }
/* The two exceptions that earn a tinted fill */
.badge[data-state="danger"]  { background: var(--red-50);   border-color: var(--red-200);   color: var(--red-700);   --dot: var(--red); }
.badge[data-state="no-show"] { background: var(--amber-50); border-color: var(--amber-200); color: var(--amber-700); --dot: var(--amber); }
/* Micro-pill inside dense lists */
.micro { font-size: 11px; font-weight: 500; border-radius: var(--r-pill); padding: 2px 8px; border: 1px solid var(--n-100); white-space: nowrap; }
.micro--overdue { background: var(--red-50);     border-color: var(--red-200);     color: var(--red-700); }
.micro--due     { background: var(--amber-50);   border-color: var(--amber-200);   color: var(--amber-700); }
.micro--done    { background: var(--emerald-50); border-color: var(--emerald-200); color: var(--emerald-700); }

/* A bare dot for "coloured dot + one sentence" lines — STATE, so a circle */
.dot { width: 7px; height: 7px; border-radius: var(--r-pill); flex: none; background: var(--n-400); }
.dot--danger { background: var(--red); } .dot--warn { background: var(--amber); }
.dot--ok { background: var(--emerald); } .dot--teal { background: var(--teal); }
.dot--maternal { background: var(--rose); }

/* IDENTITY, so a rounded square. A programme is a thing, not a state. */
.sq { width: 9px; height: 9px; border-radius: var(--r-sq); flex: none; background: var(--prog-none); }
.sq--pregnancy  { background: var(--prog-pregnancy); }
.sq--postpartum { background: var(--prog-postpartum); }
.sq--wellbaby   { background: var(--prog-wellbaby); }

/* ---------- 6. Buttons — ONE saturated fill per screen ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  flex: none; white-space: nowrap;
  min-height: var(--touch); padding: 0 18px;
  border: 1px solid var(--n-100); border-radius: var(--r-input);
  background: #fff; color: var(--n-700);
  font-size: 14.5px; font-weight: 500; letter-spacing: -.005em;
  box-shadow: var(--e-subtle); cursor: pointer;
  transition: background var(--t-hover) var(--ease), border-color var(--t-hover) var(--ease);
}
.btn:hover { background: var(--n-0); border-color: var(--n-200); }
.btn--primary { background: var(--teal); border-color: var(--teal); color: #fff; box-shadow: 0 1px 2px rgba(22,33,31,.12); }
.btn--primary:hover { background: var(--teal-hover); border-color: var(--teal-hover); }
.btn--ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--n-600); }
.btn--ghost:hover { background: var(--n-0); border-color: transparent; }
/* The inline "Open board ›" affordance — a link that is really a button */
.btn--link { background: none; border: 0; box-shadow: none; min-height: 0; padding: 0; color: var(--teal); font-size: 13.5px; font-weight: 500; }
.btn--link:hover { background: none; text-decoration: underline; text-underline-offset: 2px; }
.btn--sm { min-height: 36px; padding: 0 14px; font-size: 13.5px; }
.btn--pill { border-radius: var(--r-pill); min-height: 34px; padding: 0 15px; font-size: 12.5px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---------- 7. Inputs ---------- */
.field {
  display: flex; align-items: center; gap: 9px;
  width: 100%; min-height: 44px; padding: 0 13px;
  background: var(--n-0); border: 1px solid var(--n-100); border-radius: var(--r-input);
  font-size: 15px; color: var(--n-700); font-family: inherit;
}
.field::placeholder, .field .t-placeholder { color: var(--n-400); }
.field:focus-within, .field:focus { border-color: var(--teal); background: #fff; outline: none; }
textarea.field { min-height: 120px; padding: 12px 13px; line-height: 1.6; resize: vertical; }
/* A time / file-number input carries the identifier face */
.field--mono { font-family: var(--font-mono); font-size: 13.5px; }

.segmented { display: inline-flex; gap: 3px; padding: 3px; background: var(--n-50); border: 1px solid var(--n-100); border-radius: var(--r-input); }
.segmented > button {
  min-height: 38px; padding: 0 16px; border: 0; border-radius: 11px; background: transparent;
  font-size: 13.5px; color: var(--n-500); cursor: pointer; transition: background var(--t-hover) var(--ease);
}
.segmented > button[aria-pressed="true"] { background: #fff; color: var(--n-800); font-weight: 500; box-shadow: 0 1px 2px rgba(22,33,31,.08); }

.chip {
  display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  min-height: 38px; padding: 0 15px;
  background: #fff; border: 1px solid var(--n-100); border-radius: var(--r-pill);
  font-size: 13.5px; font-weight: 500; color: var(--n-600); cursor: pointer;
}
.chip[aria-pressed="true"] { background: var(--teal-100); border-color: var(--teal-200); color: var(--teal-deep); }
.chip__n { font-family: var(--font-mono); font-size: 12px; color: var(--n-500); }

.switch { width: 36px; height: 20px; padding: 2px; border: 0; border-radius: var(--r-pill); background: var(--n-200); display: inline-flex; align-items: center; cursor: pointer; transition: background var(--t-hover) var(--ease); }
.switch > span { width: 16px; height: 16px; border-radius: var(--r-pill); background: #fff; box-shadow: 0 1px 2px rgba(22,33,31,.18); transition: transform var(--t-hover) var(--ease); }
.switch[aria-checked="true"] { background: var(--teal); }
.switch[aria-checked="true"] > span { transform: translateX(16px); }
[dir="rtl"] .switch[aria-checked="true"] > span { transform: translateX(-16px); }

/* ---------- 7b. Dropdown + date picker — the two menus the OS would draw ----------
   A native select menu and a native date-input calendar are painted by the
   operating system: Segoe blue on Windows, a different grey on macOS, a full
   sheet on Android. Neither can be styled, so on every surface they were the one
   thing that did not look like Practeca. Both are replaced here by a button + a
   popover built from the same materials as .inp — same 44px floor, same paper
   fill, same 14px radius, same teal focus edge — so a menu reads as part of the
   field it belongs to. The native control stays in the DOM, hidden, and still
   owns the value; the popover only writes to it and fires a change event. */

.dd, .dp { position: relative; display: block; width: 100%; }
/* The native control keeps the value and stays reachable, but never paints.
   Written at .inp's own specificity or higher — base.css loads after this file
   and its `select.inp` rule would otherwise win back width and padding. */
.dd > select, .dp > input, .dd > select.inp, .dp > input.inp {
  position: absolute; width: 1px; height: 1px; min-height: 0; padding: 0;
  margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  border: 0; opacity: 0; pointer-events: none;
}

/* The closed control — .inp, to the pixel */
.dd__btn, .dp__btn {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: var(--touch);
  padding: 10px 13px; cursor: pointer; text-align: start;
  background: var(--n-0); border: 1px solid var(--n-100); border-radius: var(--r-input);
  color: var(--n-700); font-size: 15px; font-family: inherit; letter-spacing: var(--tr-body);
  transition: border-color var(--t-hover) var(--ease), background var(--t-hover) var(--ease);
}
.dd__btn:hover, .dp__btn:hover { border-color: var(--n-200); }
.dd.is-open > .dd__btn, .dp.is-open > .dp__btn,
.dd__btn:focus-visible, .dp__btn:focus-visible { outline: none; border-color: var(--teal); background: #fff; }
.dd__btn:disabled, .dp__btn:disabled { opacity: .55; cursor: not-allowed; background: var(--n-50); }
.dd--sm .dd__btn, .dp--sm .dp__btn { min-height: 36px; padding: 6px 11px; font-size: 13.5px; gap: 8px; }

.dd__val, .dp__val { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dp__val { font-variant-numeric: tabular-nums; }
.dd__val--empty, .dp__val--empty { color: var(--n-400); }
.dd__chev, .dp__ic { flex: none; color: var(--n-400); }
.dd__chev { transition: transform var(--t-hover) var(--ease); }
.dd.is-open .dd__chev { transform: rotate(180deg); }
.dp.is-open .dp__ic, .dd.is-open .dd__chev { color: var(--teal); }

/* The popover. One shared shell, so a calendar and a select menu are one family. */
.dd__menu, .dp__pop {
  position: absolute; inset-inline-start: 0; inset-block-start: calc(100% + 6px); z-index: 120;
  background: #fff; border: 1px solid var(--n-100); border-radius: var(--r-input);
  box-shadow: var(--e-float); padding: 6px; display: none;
  animation: scale-fade-in var(--t-hover) var(--ease) both; transform-origin: top;
}
.dd.is-open > .dd__menu { display: flex; }
.dp.is-open > .dp__pop { display: block; }
/* Not enough room below: the menu opens upward and grows from its foot instead */
.dd--up > .dd__menu, .dp--up > .dp__pop {
  inset-block-start: auto; inset-block-end: calc(100% + 6px); transform-origin: bottom;
}
/* A menu opened inside a dialog has to clear the dialog */
.modal .dd__menu, .modal .dp__pop, .slideover .dd__menu, .slideover .dp__pop { z-index: 220; }

.dd__menu {
  flex-direction: column; gap: 2px;
  /* The menu sits inside a modal that is itself inset, so 86vw still spilled
     off a 390px screen. Leave room for the dialog's own margin. */
  min-width: 100%; width: max-content; max-width: 340px;
  max-height: 288px; overflow-y: auto; overscroll-behavior: contain;
}
/* An <optgroup> heading. enhanceSelects has always emitted these; nothing
   styled them until due items grew three groups of anchors. */
.dd__group {
  padding: 9px 10px 4px; font-size: 11.5px; font-weight: 500; letter-spacing: .16em;
  text-transform: uppercase; color: var(--n-500);
}
.dd__group:first-child { padding-block-start: 4px; }

.dd__it {
  display: flex; align-items: center; gap: 8px; width: 100%; flex: none;
  padding: 8px 10px; min-height: 36px; border: 0; border-radius: calc(var(--r-input) - 6px);
  background: none; cursor: pointer; text-align: start;
  font-size: 14px; font-family: inherit; color: var(--n-700); letter-spacing: var(--tr-body);
  transition: background var(--t-hover) var(--ease);
}
.dd__it > span { flex: 1; min-width: 0; }
.dd__it:hover, .dd__it.is-cursor { background: var(--n-25); color: var(--n-800); }
.dd__it[aria-selected="true"] { background: var(--teal-100); color: var(--teal-deep); font-weight: 500; }
.dd__it[disabled] { opacity: .4; cursor: not-allowed; background: none; }
.dd__tick { flex: none; opacity: 0; color: var(--teal); }
.dd__it[aria-selected="true"] .dd__tick { opacity: 1; }
.dd__group { padding: 9px 10px 4px; font-size: 11px; font-weight: 500; text-transform: uppercase;
  letter-spacing: .11em; color: var(--n-500); }

/* ---- The calendar ---- */
.dp__pop { width: 292px; padding: 10px; }
.dp__head { display: flex; align-items: center; gap: 4px; padding-block-end: 8px; }
.dp__title { flex: 1; text-align: center; font-size: 14px; font-weight: 500; color: var(--n-800); letter-spacing: var(--tr-card); }
.dp__nav {
  width: 32px; height: 32px; flex: none; border: 0; background: none; cursor: pointer;
  border-radius: calc(var(--r-input) - 6px); color: var(--n-500);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--t-hover) var(--ease), color var(--t-hover) var(--ease);
}
.dp__nav:hover { background: var(--n-25); color: var(--n-800); }
.dp__nav:disabled { opacity: .35; cursor: not-allowed; background: none; }
[dir="rtl"] .dp__nav svg { transform: scaleX(-1); }

.dp__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
/* Sat–Thu is the Egyptian working week, so Friday sits back rather than standing out */
.dp__wd { text-align: center; font-size: 10.5px; font-weight: 500; text-transform: uppercase;
  letter-spacing: .08em; color: var(--n-500); padding-block: 4px 6px; }
.dp__wd--off { color: var(--n-500); opacity: .75; }
.dp__d {
  aspect-ratio: 1; min-height: 34px; border: 0; background: none; cursor: pointer;
  border-radius: calc(var(--r-input) - 6px); font-family: inherit; font-size: 13.5px;
  color: var(--n-700); font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center; position: relative;
  transition: background var(--t-hover) var(--ease), color var(--t-hover) var(--ease);
}
.dp__d:hover:not(:disabled) { background: var(--n-25); color: var(--n-800); }
.dp__d--out { color: var(--n-500); opacity: .6; }   /* a day spilling in from the next month */
.dp__d--off { color: var(--n-500); }                /* Friday */
.dp__d--today::after { content: ""; position: absolute; inset-block-end: 5px; width: 4px; height: 4px;
  border-radius: var(--r-pill); background: var(--teal); }
.dp__d--sel { background: var(--teal); color: #fff; font-weight: 500; }
.dp__d--sel:hover:not(:disabled) { background: var(--teal-hover); color: #fff; }
.dp__d--sel.dp__d--today::after { background: #fff; }
.dp__d:disabled { opacity: .3; cursor: not-allowed; }
.dp__foot { display: flex; gap: 8px; padding-block-start: 8px; margin-block-start: 6px; border-block-start: 1px solid var(--n-50); }
.dp__foot button {
  flex: 1; min-height: 34px; border: 1px solid var(--n-100); border-radius: calc(var(--r-input) - 6px);
  background: #fff; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: 500; color: var(--n-600);
  transition: background var(--t-hover) var(--ease), border-color var(--t-hover) var(--ease);
}
.dp__foot button:hover { background: var(--n-0); border-color: var(--n-200); color: var(--n-800); }

/* Phones: a popover that would run off the screen becomes a bottom sheet instead */
@media (max-width: 560px) {
  .dd__menu, .dp__pop {
    position: fixed; inset-inline: 12px auto; inset-block-start: auto; inset-block-end: 12px;
    width: calc(100vw - 24px); max-width: none; transform-origin: bottom;
  }
  .dd__menu { max-height: 52vh; }
  /* A modal animates with transform, which makes it the containing block for
     position:fixed — so inside one, 100vw is not the viewport and the sheet
     ran off the dialog. Stretch it between the dialog's own edges instead. */
  .modal .dd__menu, .modal .dp__pop, .slideover .dd__menu, .slideover .dp__pop {
    inset-inline: 12px; width: auto;
  }
  /* as a sheet it is the active surface, so it clears the review chrome */
  .dd.is-open > .dd__menu, .dp.is-open > .dp__pop { z-index: 410; }
}

/* ---------- 8. Tinted notice cards ---------- */
.notice { display: flex; gap: 10px; align-items: flex-start; border-radius: var(--r-input); border: 1px solid; padding: 15px 16px; }
.notice--danger { background: var(--red-50);   border-color: var(--red-200);   color: var(--red-700); }
.notice--warn   { background: var(--amber-50); border-color: var(--amber-200); color: var(--amber-700); }
.notice__sub { color: currentColor; opacity: .75; font-size: 12.5px; margin-top: 5px; line-height: 1.5; }

/* Hint bar / product news — warm strip with a 3px leading border */
.hintbar {
  display: flex; align-items: center; gap: 10px;
  background: var(--n-0); border: 1px solid var(--n-100);
  border-inline-start: 3px solid var(--amber);
  border-radius: var(--r-chip); padding: 11px 15px; font-size: 14px; color: var(--n-600);
  box-shadow: var(--e-subtle);
}
.hintbar--news { border-inline-start-color: var(--teal); }
.hintbar__dismiss { margin-inline-start: auto; color: var(--n-400); border: 0; background: none; cursor: pointer; display: inline-flex; }
.tag-new { font-size: 10px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--teal-deep); background: var(--teal-100); border-radius: var(--r-pill); padding: 3px 9px; }

/* ---------- 9. AI surfaces — always visibly machine-written ---------- */
.ai { background: var(--n-0); border: 1px dashed var(--n-200); border-radius: var(--r-input); padding: 15px 16px; }
.ai__chip { display: inline-flex; align-items: center; gap: 6px; background: var(--n-50); border: 1px solid var(--n-100); border-radius: var(--r-pill); padding: 3px 10px; font-size: 11.5px; font-weight: 500; color: var(--n-500); white-space: nowrap; }
.ai__tag { font-size: 10px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--n-500); border: 1px solid var(--n-100); border-radius: var(--r-pill); padding: 2px 8px; }

/* ---------- 10. Slide-over (never a modal for booking) ---------- */
.slideover {
  position: fixed; inset-block: 0; inset-inline-end: 0; width: min(440px, 100vw);
  background: #fff; border-inline-start: 1px solid var(--n-100); box-shadow: var(--e-overlay);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform var(--t-panel) var(--ease);
  z-index: 40;
}
[dir="rtl"] .slideover { transform: translateX(-100%); }
/* Open state is a CLASS, not an attribute value — a consumer writing data-open="1"
   or data-open="" would silently get nothing. */
.slideover.is-open { transform: none; }
.slideover__head { display: flex; align-items: center; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--n-100); }
.slideover__body { flex: 1; min-height: 0; overflow: auto; padding: 16px 20px; display: flex; flex-direction: column; gap: 14px; }
.scrim { position: fixed; inset: 0; background: rgba(22,33,31,.22); opacity: 0; pointer-events: none; transition: opacity var(--t-panel) var(--ease); z-index: 30; }
.scrim.is-open { opacity: 1; pointer-events: auto; }

/* ---------- 11. Toast — Undo, not "Are you sure?" ---------- */
.toast {
  position: fixed; bottom: 20px; inset-inline-start: 50%; transform: translate(-50%, 12px);
  display: flex; align-items: center; gap: 14px;
  background: #12211F; color: #EFEBE3; border-radius: var(--r-input);
  padding: 13px 18px; box-shadow: var(--e-float); font-size: 14px;
  opacity: 0; pointer-events: none;
  transition: opacity var(--t-panel) var(--ease), transform var(--t-panel) var(--ease);
  z-index: 50;
}
.toast.is-open { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.toast__undo { color: var(--brass-lt); font-weight: 500; background: none; border: 0; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; font-size: 14px; }

/* ---------- 12. Empty + skeleton ---------- */
/* One sentence and one action. Never an illustration. */
.empty { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; padding: 22px 0; }
.empty__line { font-size: 15px; color: var(--n-500); }
.empty--dash { font-size: 16px; color: var(--n-400); padding: 6px 2px; }  /* an empty board column */

.skeleton { border-radius: 10px; background: linear-gradient(90deg, var(--n-50) 0%, var(--n-100) 50%, var(--n-50) 100%); background-size: 200% 100%; animation: sk 1.4s var(--ease) infinite; }
@keyframes sk { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ---------- 13. Chrome ---------- */
.app { display: flex; min-height: 100vh; }
.sidebar { width: var(--w-sidebar); flex: none; background: #fff; border-inline-end: 1px solid var(--n-100); padding: 18px 12px; display: flex; flex-direction: column; }
.nav__item { position: relative; display: flex; align-items: center; gap: 10px; min-height: var(--touch); padding: 0 11px; border: 1px solid transparent; border-radius: var(--r-chip); color: var(--n-600); font-size: 14.5px; font-weight: 500; overflow: hidden; }
.nav__item:hover { background: var(--n-0); }
.nav__item[aria-current="page"] { background: #fff; border-color: var(--n-100); box-shadow: var(--e-subtle); color: var(--n-800); }
.nav__item[aria-current="page"]::before { content: ""; position: absolute; inset-inline-start: 0; top: 10px; bottom: 10px; width: 3px; border-radius: 0 2px 2px 0; background: var(--teal); }
[dir="rtl"] .nav__item[aria-current="page"]::before { border-radius: 2px 0 0 2px; }
.nav__item[aria-current="page"] svg { color: var(--teal); }
.nav__count { margin-inline-start: auto; font-family: var(--font-mono); font-size: 11.5px; color: var(--n-500); background: var(--n-50); border: 1px solid var(--n-100); border-radius: var(--r-pill); padding: 1px 8px; }
.topbar { height: var(--h-topbar); flex: none; background: #fff; border-bottom: 1px solid var(--n-100); padding: 0 22px; display: flex; align-items: center; gap: 16px; }
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.page {
  padding: 44px 40px 72px; display: flex; flex-direction: column; gap: var(--gap-zone);
  max-width: var(--w-content); margin: 0 auto; width: 100%;
  animation: rise .32s var(--ease) both;
}
.avatar { display: flex; align-items: center; justify-content: center; flex: none; width: 38px; height: 38px; border-radius: var(--r-pill); background: var(--av-2); color: #fff; font-size: 13px; font-weight: 500; }
.avatar--teal { background: var(--teal); }
.avatar--maternal { background: var(--rose-50); border: 1px solid var(--rose-200); color: var(--rose-700); }

/* The page header: eyebrow, big title, one line of prose */
.pagehead { display: flex; align-items: flex-end; gap: 20px; flex-wrap: wrap; }
.pagehead__main { flex: 1; min-width: 260px; }
.pagehead__sub { margin: 10px 0 0; font-size: 16px; color: var(--n-700); max-width: 46ch; }
/* Stat tiles that sit beside the title */
.stat { padding: 13px 17px; border-radius: var(--r-input); background: #fff; border: 1px solid var(--n-100); min-width: 96px; }
.stat--accent { background: var(--teal-100); border-color: var(--teal-200); }
.stat--accent .t-stat { color: var(--teal-deep); }
.stat__k { font-size: 12.5px; color: var(--n-500); margin-top: 3px; }
.stat--accent .stat__k { color: var(--teal-deep); opacity: .8; }

/* ---------- 14. Responsive ---------- */
/* Laptop: the generous page padding is the first thing to go. */
@media (max-width: 1280px) {
  .page { padding: 32px 28px 56px; }
  :root { --pad-card: 22px; }
}
/* Tablet portrait: sidebar becomes a 72px icon rail. */
@media (max-width: 1024px) {
  :root { --w-sidebar: 72px; }
  .sidebar { padding: 16px 8px; align-items: center; }
  .sidebar .nav__label, .sidebar .t-label, .sidebar .brand__word, .nav__count { display: none; }
  .nav__item { justify-content: center; }
  .split { grid-template-columns: 1fr !important; }        /* every 2/3-col page zone stacks */
  .preview-panel { display: none; }                        /* becomes the bottom sheet */
  .fab { display: inline-flex; }
}
@media (max-width: 640px) {
  :root { --pad-card: 18px; --gap-zone: 14px; --r-card: 16px; }
  .page { padding: 20px 16px 48px; }
  .row { padding: 12px 16px; }
  .pagehead { gap: 14px; }
  .pagehead__sub { font-size: 15px; }
  .slideover { width: 100vw; }
  .table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}
.fab { display: none; position: fixed; inset-inline-end: 20px; bottom: 20px; min-height: 52px; padding: 0 22px; border: 0; border-radius: var(--r-pill); background: var(--teal); color: #fff; font-size: 14.5px; font-weight: 500; align-items: center; gap: 9px; box-shadow: var(--e-float); cursor: pointer; z-index: 45; }

.split { display: grid; gap: var(--gap-zone); align-items: start; }
.split--2-1 { grid-template-columns: minmax(0,2fr) minmax(0,1fr); }
.split--3 { grid-template-columns: 344px minmax(0,1fr) 392px; }
.grid-cards { display: grid; gap: var(--gap-zone); grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }

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