/* ==========================================================================
   Afrikyol Medipol — design system
   Palette approximated from medipolglobal.com. Swap the hex values here (only
   here) when the official Medipol brand guide arrives. See BRAND.md.
   ========================================================================== */

:root {
  /* Identity */
  --navy: #0B2C5B;
  --navy-deep: #071D3D;
  --blue: #0B63B0;
  --blue-hover: #0A5596;
  --blue-soft: #E8F1FA;
  --blue-line: #BFD6EC;

  /* Status */
  --teal: #0F9E9E;
  --teal-soft: #E4F5F5;
  --amber: #C77A0A;
  --amber-soft: #FDF3E3;
  --red: #B3261E;
  --red-soft: #FBEAE9;

  /* Neutrals */
  --grey-900: #16202E;
  --grey-600: #5A6676;
  --grey-400: #98A3B2;
  --grey-200: #DCE2E9;
  --grey-100: #F4F6F9;
  --white: #FFFFFF;

  /* Type */
  --font: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-ar: 'Tajawal', 'Inter', system-ui, sans-serif;
  --lh: 1.65;

  /* Space (4px scale) */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;

  /* Shape */
  --r-sm: 6px; --r: 10px; --r-lg: 16px; --r-full: 999px;
  --shadow: 0 1px 2px rgba(11,44,91,.06), 0 4px 16px rgba(11,44,91,.06);
  --shadow-lg: 0 2px 4px rgba(11,44,91,.08), 0 12px 32px rgba(11,44,91,.10);

  --wrap: 1160px;
  --nav-h: 68px;
}

/* Arabic: Tajawal needs more room to breathe */
html[lang="ar"] { --font: var(--font-ar); --lh: 1.9; }

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: var(--lh);
  color: var(--grey-900);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
}
img, svg, video { max-width: 100%; height: auto; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4 { margin: 0 0 var(--s4); line-height: 1.25; font-weight: 600; color: var(--navy); }
h1 { font-size: clamp(1.9rem, 4.2vw, 3rem); letter-spacing: -.02em; }
h2 { font-size: clamp(1.5rem, 2.8vw, 2.15rem); letter-spacing: -.01em; }
h3 { font-size: 1.2rem; }
p  { margin: 0 0 var(--s4); }
a  { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }
ul, ol { margin: 0 0 var(--s4); padding-inline-start: var(--s5); }
:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; border-radius: var(--r-sm); }

/* Never justify — hurts readability in every one of our four languages */
p, li { text-align: start; }

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.wrap { width: min(100% - 2 * var(--s5), var(--wrap)); margin-inline: auto; }
.section { padding-block: var(--s8); }
.section--tint { background: var(--grey-100); }
.section--medipol { background: var(--blue-soft); }
.section--navy { background: var(--navy); color: var(--white); }
.section--navy h1, .section--navy h2, .section--navy h3 { color: var(--white); }

.stack > * + * { margin-top: var(--s4); }
.grid { display: grid; gap: var(--s5); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.lead { font-size: 1.13rem; color: var(--grey-600); max-width: 62ch; }
.eyebrow {
  font-size: .8rem; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--blue); margin-bottom: var(--s2);
}
.section--navy .eyebrow { color: var(--blue-line); }
.muted { color: var(--grey-600); }
.small { font-size: .875rem; }
.center { text-align: center; }
.center .lead { margin-inline: auto; }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  padding: 13px var(--s5); border: 1px solid transparent; border-radius: var(--r);
  font-weight: 600; font-size: .97rem; cursor: pointer; text-decoration: none;
  transition: background .15s, border-color .15s, color .15s;
  min-height: 48px; /* touch target */
}
.btn:hover { text-decoration: none; }
.btn--primary { background: var(--blue); color: var(--white); }
.btn--primary:hover { background: var(--blue-hover); }
.btn--ghost { background: transparent; color: var(--blue); border-color: var(--blue-line); }
.btn--ghost:hover { background: var(--blue-soft); }
.btn--white { background: var(--white); color: var(--navy); }
.btn--white:hover { background: var(--grey-100); }
.btn--danger { background: var(--red); color: var(--white); }
.btn--block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .5; cursor: not-allowed; pointer-events: none;
}
.btn-row { display: flex; flex-wrap: wrap; gap: var(--s3); }

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.card {
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: var(--r-lg); padding: var(--s5); box-shadow: var(--shadow);
}
.card--flat { box-shadow: none; }
.card--link { transition: box-shadow .18s, transform .18s; }
.card--link:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.card__title { font-size: 1.08rem; margin-bottom: var(--s2); }
.card__meta { font-size: .875rem; color: var(--grey-600); }

/* Two cards that carry a tone rather than a layout.

   `--caveat` is the honest-limits card: the medical disclaimer, "we cannot
   promise the slot", the delete-account warning. It lived in css/home.css,
   which none of its eleven users loads — so the disclaimer on the AI
   explanation, the one piece of styling on this site that is a legal
   requirement and not a decoration, was rendering as a plain white card.
   Third component today found in a stylesheet its users do not load. */
.card--caveat {
  background: var(--amber-soft);
  border-color: var(--amber-soft);
  border-inline-start: 4px solid var(--amber);
  box-shadow: none;
}
.card--caveat .card__title { color: var(--amber); }

/* `--ok` is the other end: it confirms something has actually happened. */
.card--ok {
  background: var(--teal-soft);
  border-color: var(--teal-soft);
  border-inline-start: 4px solid var(--teal);
  box-shadow: none;
}
.card--ok .card__title { color: var(--teal); }

/* Numbered steps — the funnel on the landing page, and "what we do for you"
   on the training page.

   The <ol> rules used to live in css/home.css, which only the landing page
   loads. Every other page got the numbered badge AND the browser's own list
   marker, so the training page counted to four twice. A component used by more
   than one page belongs here. */
.steps {
  list-style: none; padding: 0; margin: var(--s7) auto 0;
  display: grid; gap: var(--s4);
  grid-template-columns: 1fr; max-width: 940px;
}
@media (min-width: 760px) { .steps { grid-template-columns: 1fr 1fr; } }
.steps .card__title { margin-bottom: var(--s2); }

.step { position: relative; padding-inline-start: var(--s8); }
.step__n {
  position: absolute; inset-inline-start: 0; top: 0;
  width: var(--s6); height: var(--s6); border-radius: var(--r-full);
  background: var(--blue-soft); color: var(--blue);
  display: grid; place-items: center; font-weight: 700; font-size: .95rem;
  transition: background .2s, color .2s;
}
.steps .step { transition: box-shadow .2s, transform .2s, border-color .2s; }
.steps .step:hover {
  box-shadow: var(--shadow-lg); transform: translateY(-3px); border-color: var(--blue-line);
}
.steps .step:hover .step__n { background: var(--blue); color: var(--white); }

/* ---- Toolbar over a list --------------------------------------------------
   A search box and one or two <select>s above a filtered list: the patient's
   explanations, the press articles. Shared, so it lives here — it started in
   css/explanation.css and the news page does not load that file.
   -------------------------------------------------------------------------- */

.xbar {
  display: flex; align-items: flex-end; gap: var(--s4) var(--s5);
  flex-wrap: wrap; margin-bottom: var(--s5);
}
/* The selects share the row and shrink with it. Left to itself a <select> is
   as wide as its longest option — "Tunisie — الدارجة التونسية" — which pushed
   the whole dashboard sideways on a phone. */
.xbar__f { display: grid; gap: 4px; margin: 0; min-width: 0; flex: 1 1 190px; }
.xbar__f label {
  font-size: .74rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; color: var(--grey-600);
}
.xbar__f select {
  appearance: none; -webkit-appearance: none;
  border: 1px solid var(--grey-200); background: var(--white);
  border-radius: var(--r-full); padding: 9px 40px 9px 16px;
  font: inherit; font-size: .9rem; font-weight: 500; color: var(--navy);
  cursor: pointer; width: 100%; min-width: 0;
  text-overflow: ellipsis;
  /* The chevron, drawn rather than fetched — one less request, and it mirrors
     with the rest of the layout because the padding is what positions it. */
  background-image: linear-gradient(45deg, transparent 50%, var(--grey-600) 50%),
                    linear-gradient(135deg, var(--grey-600) 50%, transparent 50%);
  background-position: calc(100% - 21px) 55%, calc(100% - 16px) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.xbar__f select:hover { border-color: var(--blue); }
.xbar__n { margin: 0 0 9px auto; color: var(--grey-600); font-size: .85rem; }

/* ---- Filter bar -----------------------------------------------------------
   Chips over a list: doctors by department, explanations by language, the
   language buttons in the patient's profile. This was in css/medipol.css, so
   on the dashboard — which does not load it — the chips rendered as bare
   browser buttons. Same reason as .steps above. */
.filters {
  display: flex; gap: var(--s2); flex-wrap: wrap;
  margin-bottom: var(--s5);
}
.filters button {
  border: 1px solid var(--grey-200); background: var(--white);
  border-radius: var(--r-full); padding: 7px 15px;
  font-size: .87rem; font-weight: 500; cursor: pointer; color: var(--grey-600);
}
.filters button:hover { border-color: var(--blue); color: var(--blue); }
.filters button[aria-pressed="true"] {
  background: var(--blue); border-color: var(--blue); color: var(--white);
}

/* Stat block — only ever holds a verified Medipol figure (see BRAND.md) */
.stat { text-align: center; }
.stat__n {
  font-size: clamp(1.8rem, 3.4vw, 2.6rem); font-weight: 700;
  color: var(--navy); line-height: 1.1; font-variant-numeric: tabular-nums;
}
.section--navy .stat__n { color: var(--white); }
.stat__l { font-size: .875rem; color: var(--grey-600); }
.section--navy .stat__l { color: var(--blue-line); }

/* --------------------------------------------------------------------------
   Badges & status
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex; align-items: center; gap: var(--s1);
  padding: 3px 10px; border-radius: var(--r-full);
  font-size: .78rem; font-weight: 600; white-space: nowrap;
}
.badge--info    { background: var(--blue-soft); color: var(--blue); }
.badge--ok      { background: var(--teal-soft); color: var(--teal); }
.badge--warn    { background: var(--amber-soft); color: var(--amber); }
.badge--danger  { background: var(--red-soft);  color: var(--red); }
.badge--neutral { background: var(--grey-100);  color: var(--grey-600); }

/* --------------------------------------------------------------------------
   The medical disclaimer — legally required, never hide or soften it.
   -------------------------------------------------------------------------- */

.disclaimer {
  display: flex; gap: var(--s3); align-items: flex-start;
  background: var(--amber-soft); border: 1px solid var(--amber);
  border-radius: var(--r); padding: var(--s4); margin-bottom: var(--s5);
  font-size: .92rem; color: var(--grey-900);
}
.disclaimer strong { color: var(--amber); }
.disclaimer__icon { flex: 0 0 auto; font-size: 1.2rem; line-height: 1.3; }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.field { margin-bottom: var(--s4); }
.field label { display: block; font-weight: 500; font-size: .92rem; margin-bottom: var(--s2); }
.field .hint { font-size: .84rem; color: var(--grey-600); margin-top: var(--s1); }
.field .error { font-size: .84rem; color: var(--red); margin-top: var(--s1); }

input[type="text"], input[type="email"], input[type="tel"], input[type="password"],
input[type="date"], input[type="number"], input[type="search"],
input[type="url"], select, textarea {
  width: 100%; padding: 12px var(--s3);
  border: 1px solid var(--grey-200); border-radius: var(--r);
  background: var(--white); min-height: 48px;
  transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(11,99,176,.14);
}
input[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--red); }
textarea { min-height: 130px; resize: vertical; line-height: var(--lh); }

/* ---- Country picker (js/countries.js) --------------------------------------
   A listbox rather than a <select>, because an <option> cannot hold an image
   and emoji flags render as the two-letter code on Windows.
   -------------------------------------------------------------------------- */

.cpick { position: relative; }

.cpick__btn {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: 10px var(--s3); min-height: 48px; cursor: pointer;
  border: 1px solid var(--grey-200); border-radius: var(--r);
  background: var(--white); text-align: start;
  transition: border-color .15s, box-shadow .15s;
}
.cpick__btn:hover { border-color: var(--blue); }
.cpick__btn[aria-expanded="true"] {
  border-color: var(--blue); box-shadow: 0 0 0 3px rgba(11,99,176,.14);
}
.cpick__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cpick__caret { color: var(--grey-400); flex: none; }

.cpick__flag {
  width: 26px; height: 18px; flex: none; object-fit: cover;
  border-radius: 3px; box-shadow: 0 0 0 1px rgba(0,0,0,.10);
}
.cpick__flag--none { background: var(--grey-100); box-shadow: 0 0 0 1px var(--grey-200); }

.cpick__pop {
  position: absolute; z-index: 300; inset-inline: 0; top: calc(100% + 4px);
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: var(--r); box-shadow: var(--shadow-lg);
  padding: var(--s2);
}
.cpick__pop[hidden] { display: none; }
.cpick__q { margin-bottom: var(--s2); min-height: 42px; }

.cpick__list {
  list-style: none; margin: 0; padding: 0;
  max-height: 46vh; overflow-y: auto; overscroll-behavior: contain;
}
.cpick__group {
  padding: var(--s3) var(--s3) var(--s2);
  font-size: .74rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--grey-400);
}
.cpick__group[hidden] { display: none; }
.cpick__list li[hidden] { display: none; }

.cpick__opt {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: 9px var(--s3); border: 0; border-radius: var(--r-sm);
  background: none; cursor: pointer; text-align: start;
  font: inherit; font-size: .95rem; color: var(--grey-900);
}
.cpick__opt img { width: 24px; height: 17px; flex: none; object-fit: cover;
                  border-radius: 2px; box-shadow: 0 0 0 1px rgba(0,0,0,.10); }
.cpick__opt:hover, .cpick__opt:focus-visible { background: var(--blue-soft); outline: none; }
.cpick__opt[aria-selected="true"] { background: var(--blue-soft); font-weight: 600; color: var(--blue); }
.cpick__opt--other { color: var(--grey-600); }
.cpick__none { padding: var(--s4); margin: 0; color: var(--grey-600); font-size: .92rem; }
.cpick__none[hidden] { display: none; }

/* The "Other country" box, revealed under the picker. */
.country__free { margin-top: var(--s2); }
.country__free[hidden] { display: none; }

/* Consent checkbox — the label is long by necessity, so give it room and
   keep the whole block clickable. */
.consent {
  display: flex; gap: var(--s3); align-items: flex-start;
  font-size: .92rem; line-height: 1.6; cursor: pointer;
}
.consent input[type="checkbox"] {
  flex: 0 0 auto; width: 20px; height: 20px; margin-top: 2px;
  accent-color: var(--blue); cursor: pointer;
}

/* Dropzone for medical documents */
.drop {
  border: 2px dashed var(--blue-line); border-radius: var(--r-lg);
  background: var(--blue-soft); padding: var(--s7) var(--s5);
  text-align: center; cursor: pointer; transition: border-color .15s, background .15s;
}
.drop:hover, .drop.is-over { border-color: var(--blue); background: #DCEAF7; }
.drop input[type="file"] { display: none; }
/* --------------------------------------------------------------------------
   Directory layout — categories on a rail, cards beside them.

   Lives here rather than in medipol.css because three different things use it
   now: the 1047-doctor list, the 117 patient stories and the 58 group films.
   In every case the same constraint applies — every card carries an image, so
   only the selected category is ever in the DOM, capped, with an explicit
   "show more". A thousand thumbnails in one document is not a slow page on the
   connections our patients are on; it is a broken one.

   Below 900 px the rail becomes a scrolling row above the grid: a column of
   28 departments you must scroll past to reach the videos is worse than no
   filter at all.
   -------------------------------------------------------------------------- */

.dirwrap { display: grid; gap: var(--s5); align-items: start; }
@media (min-width: 900px) { .dirwrap { grid-template-columns: 268px minmax(0, 1fr); } }

/* ⚠ A grid item defaults to `min-width: auto`, which means it refuses to be
   narrower than its content. The category rail is a flex row of 28 chips, so
   on a phone that item became ~2000 px wide and took THE WHOLE PAGE with it:
   the nav, the headings and the footer all scrolled sideways. This one line is
   the fix, and it is why the page body must never scroll horizontally. */
.dirwrap > * { min-width: 0; }

.dirside {
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: var(--r-lg); padding: var(--s3);
}
@media (min-width: 900px) {
  .dirside {
    position: sticky; top: calc(var(--nav-h) + var(--s4));
    max-height: calc(100dvh - var(--nav-h) - var(--s7)); overflow-y: auto;
  }
}
.dirside__search { margin-bottom: var(--s3); }
.dirside__search input { min-height: 42px; font-size: .92rem; }

.dircats { list-style: none; margin: 0; padding: 0; }
.dircats button {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  width: 100%; border: 0; background: none; cursor: pointer; text-align: start;
  padding: 9px var(--s3); border-radius: var(--r-sm);
  font-size: .9rem; color: var(--grey-900); line-height: 1.3;
}
.dircats button:hover { background: var(--grey-100); }
.dircats button[aria-current="true"] {
  background: var(--blue); color: var(--white); font-weight: 600;
}
.dircats .n { font-size: .78rem; opacity: .65; font-variant-numeric: tabular-nums; }
.dircats button[aria-current="true"] .n { opacity: .85; }

/* On a phone the rail becomes one scrolling line of chips ABOVE the grid.
   Only that line moves — the page underneath stays still, which is the whole
   point: a category strip that drags the page sideways is worse than no
   filter at all. */
@media (max-width: 899px) {
  .dirside { padding: var(--s2); max-width: 100%; overflow: hidden; }
  .dircats {
    display: flex; gap: var(--s2);
    overflow-x: auto; overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
    scroll-snap-type: x proximity;
  }
  .dircats::-webkit-scrollbar { display: none; }
  .dircats li { flex: 0 0 auto; scroll-snap-align: start; }
  .dircats button { border-radius: var(--r-full); white-space: nowrap; }
}

.dirbar {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap; margin-bottom: var(--s4);
}
.dirbar h2, .dirbar h3 { margin: 0; font-size: 1.15rem; }
/* Compteur + tri, groupés à droite de la barre : le tri est un réglage de la
   liste, il se lit au-dessus d'elle et non dans la colonne des services. */
.dirbar__end { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.dirbar__end select { min-height: 38px; font-size: .88rem; padding-block: 4px; }

/* --------------------------------------------------------------------------
   Toasts (never use alert())
   -------------------------------------------------------------------------- */

.toasts {
  position: fixed; inset-block-end: var(--s5); inset-inline: var(--s5) auto;
  z-index: 900; display: flex; flex-direction: column; gap: var(--s2);
}
.toast {
  background: var(--navy); color: var(--white);
  padding: var(--s3) var(--s5); border-radius: var(--r);
  box-shadow: var(--shadow-lg); font-size: .92rem; max-width: 380px;
  animation: toast-in .2s ease-out;
}
.toast--ok    { background: var(--teal); }
.toast--error { background: var(--red); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */

.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.spinner {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35); border-top-color: currentColor;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Wide content must scroll in its own box — the page body never scrolls sideways */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ==========================================================================
   Motion. The site was correct and completely still — "almost dead", which is
   a fair description of a page where nothing acknowledges that you arrived.
   The vocabulary below is the one mimitamie uses, adapted: same directional
   reveals, same delay ladder, longer and softer easing, smaller travel.

   Rule unchanged: motion guides the eye or confirms an action. This is a
   hospital, and a frightened patient must never feel a page bouncing at them.
   Everything here is off under prefers-reduced-motion.

     .reveal     rises from below      (default, and the safest)
     .reveal-l   arrives from the start edge   — hero copy, text columns
     .reveal-r   arrives from the end edge     — hero film, images
     .reveal-z   scales up gently              — media, carousels, cards
     .d1 … .d6   stagger a block by 0.1s steps

   All four use logical direction, so .reveal-l comes from the right in Arabic
   without a second rule.
   ========================================================================== */

.reveal, .reveal-l, .reveal-r, .reveal-z {
  opacity: 0;
  transition: opacity .8s cubic-bezier(.22,.61,.36,1),
              transform .8s cubic-bezier(.22,.61,.36,1);
  will-change: opacity, transform;
}
.reveal   { transform: translateY(26px); }
.reveal-l { transform: translateX(calc(-34px * var(--dir, 1))); }
.reveal-r { transform: translateX(calc(34px * var(--dir, 1))); }
.reveal-z { transform: scale(.94); }

html[dir="rtl"] { --dir: -1; }

.reveal.is-in, .reveal-l.is-in, .reveal-r.is-in, .reveal-z.is-in {
  opacity: 1; transform: none;
}

.d1 { transition-delay: .10s; } .d2 { transition-delay: .20s; }
.d3 { transition-delay: .30s; } .d4 { transition-delay: .40s; }
.d5 { transition-delay: .50s; } .d6 { transition-delay: .60s; }

/* Children stagger, so a grid arrives in sequence rather than all at once.
   Ten steps rather than six: the doctor grid and the step list are longer than
   they were when this was written, and the tail used to land flat. */
.reveal.is-in > *, .reveal-z.is-in > * {
  animation: rise .6s cubic-bezier(.22,.61,.36,1) backwards;
}
.reveal.is-in > *:nth-child(1),  .reveal-z.is-in > *:nth-child(1)  { animation-delay: .04s; }
.reveal.is-in > *:nth-child(2),  .reveal-z.is-in > *:nth-child(2)  { animation-delay: .10s; }
.reveal.is-in > *:nth-child(3),  .reveal-z.is-in > *:nth-child(3)  { animation-delay: .16s; }
.reveal.is-in > *:nth-child(4),  .reveal-z.is-in > *:nth-child(4)  { animation-delay: .22s; }
.reveal.is-in > *:nth-child(5),  .reveal-z.is-in > *:nth-child(5)  { animation-delay: .28s; }
.reveal.is-in > *:nth-child(6),  .reveal-z.is-in > *:nth-child(6)  { animation-delay: .34s; }
.reveal.is-in > *:nth-child(7),  .reveal-z.is-in > *:nth-child(7)  { animation-delay: .40s; }
.reveal.is-in > *:nth-child(8),  .reveal-z.is-in > *:nth-child(8)  { animation-delay: .46s; }
.reveal.is-in > *:nth-child(9),  .reveal-z.is-in > *:nth-child(9)  { animation-delay: .52s; }
.reveal.is-in > *:nth-child(10), .reveal-z.is-in > *:nth-child(10) { animation-delay: .58s; }
@keyframes rise { from { opacity: 0; transform: translateY(18px); } }

/* The ornamental half of the motion layer — heading underlines, card lifts,
   button physics and the drifting footer light — lives in css/depth.css, which
   is loaded after this file on every page. It belongs there: removing it leaves
   a still but complete site. The reveals above cannot move, because an element
   that starts at opacity 0 needs something to turn it on. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .reveal, .reveal-l, .reveal-r, .reveal-z { opacity: 1; transform: none; }
  .section h2::after, .mhead h2::after { width: 64px; transition: none; }
  html { scroll-behavior: auto; }
}
.hint--ok { color: var(--teal); font-weight: 500; }

/* --------------------------------------------------------------------------
   .flow — a short left-to-right path, boxes joined by an arrow.

   Written for the funding page ("where does the money go": donor → platform →
   Medipol's own account) but it lives HERE, not in app.css, because a numbered
   path is the most reusable shape on this site and rule 23 exists because four
   components were already lost to a page-specific stylesheet.

   The arrow is a ::after on each step except the last, drawn with logical
   properties so Arabic flips it without a second rule. Below 640 px the row
   becomes a column and the arrow rotates to point down.
   -------------------------------------------------------------------------- */

.flow {
  list-style: none; margin: var(--s5) 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s6);
}

.flow__step {
  position: relative;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: var(--r); padding: var(--s4);
}

/* The last box is where the money stops. Say so with the border, not a label. */
.flow__step--end { border-color: var(--teal); box-shadow: 0 0 0 1px var(--teal) inset; }

.flow__n {
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--blue-soft); color: var(--blue);
  font-size: .72rem; font-weight: 700; margin-bottom: var(--s2);
}
.flow__step--end .flow__n { background: var(--teal); color: var(--white); }

.flow__step:not(:last-child)::after {
  content: '›';
  position: absolute; inset-inline-end: calc(var(--s6) * -1);
  top: 50%; translate: 0 -50%;
  width: var(--s6); text-align: center;
  color: var(--grey-400); font-size: 1.5rem; line-height: 1;
}
/* '›' is a directional glyph: in RTL the browser mirrors the layout but not
   the character, so swap it for its mirror rather than rotating a box. */
[dir="rtl"] .flow__step:not(:last-child)::after { content: '‹'; }

@media (max-width: 640px) {
  .flow { grid-template-columns: 1fr; gap: var(--s5); }
  .flow__step:not(:last-child)::after {
    content: '⌄'; inset-inline-end: auto; inset-inline-start: 50%;
    top: auto; bottom: calc(var(--s5) * -1); translate: -50% 0;
    width: auto; font-size: 1.1rem;
  }
  [dir="rtl"] .flow__step:not(:last-child)::after { content: '⌄'; }
}

/* --------------------------------------------------------------------------
   .aptcal — the appointment day strip and hour grid.

   Used by rendez-vous.html AND by the block on index.html, so it lives here
   and not in home.css (rule 23).

   Deliberately NOT styled like a hospital booking widget: no slot is drawn as
   "taken", because we cannot read Medipol's diary and a half-greyed grid would
   read as confirmed availability. The only disabled slots are hours that have
   already passed today, which is a fact we do know.
   -------------------------------------------------------------------------- */

.aptcal { border: 1px solid var(--grey-200); border-radius: var(--r); padding: var(--s4); }

.aptcal__days {
  display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap;
}
.aptcal__strip { display: flex; gap: var(--s2); flex: 1 1 auto; min-width: 0; }

.aptcal__nav {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--grey-200); background: var(--white);
  color: var(--grey-900); font-size: 1.2rem; line-height: 1; cursor: pointer;
}
.aptcal__nav:hover:not(:disabled) { border-color: var(--blue); color: var(--blue); }
.aptcal__nav:disabled { opacity: .35; cursor: default; }

.aptcal__day {
  flex: 1 1 0; min-width: 0; display: grid; gap: 1px; justify-items: center;
  padding: var(--s2) var(--s1); cursor: pointer;
  border: 1px solid transparent; border-bottom: 2px solid var(--grey-200);
  background: none; border-radius: var(--r-sm) var(--r-sm) 0 0;
}
.aptcal__day:hover { background: var(--grey-100); }
.aptcal__day[aria-pressed="true"] {
  border-bottom-color: var(--blue); background: var(--blue-soft);
}
.aptcal__dow { font-size: .74rem; color: var(--grey-500); text-transform: capitalize; }
.aptcal__num { font-weight: 700; font-size: .9rem; color: var(--grey-900); }
.aptcal__day[aria-pressed="true"] .aptcal__num { color: var(--blue); }

.aptcal__pick {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: var(--s2);
  font-size: .78rem; color: var(--grey-500);
}
.aptcal__pick input { padding: 5px var(--s2); font-size: .8rem; }

/* Five per row, centred. Nineteen slots land as 5·5·5·4 — a shape you read in
   one glance, where auto-fill gave a different column count at every width. */
.aptcal__slots {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--s2); margin-top: var(--s4);
  max-width: 520px; margin-inline: auto;
}
.aptcal__slot {
  padding: 9px var(--s2); cursor: pointer; font-size: .88rem; font-weight: 600;
  border: 1px solid var(--grey-200); border-radius: var(--r-sm);
  background: var(--white); color: var(--grey-900);
}
.aptcal__slot:hover:not(:disabled) { border-color: var(--blue); color: var(--blue); }
.aptcal__slot[aria-pressed="true"] {
  background: var(--blue); border-color: var(--blue); color: var(--white);
}
/* Only ever an hour that has already gone by today. */
.aptcal__slot:disabled { opacity: .4; cursor: default; text-decoration: line-through; }

@media (max-width: 560px) {
  .aptcal__pick { width: 100%; justify-content: space-between; }
  .aptcal__slots { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
