/* ══════════════════════════════════════════════════════════════════
   DOMICARE — SKELETON / SHIMMER LOADING SYSTEM
   ══════════════════════════════════════════════════════════════════

   ONE shared placeholder language for every data-bound section that has to
   wait on the server: Patient, Practitioner and Admin.

   Design rules (deliberate, not decorative):
     • A skeleton stands in for content that is ALREADY KNOWN to be coming, so
       it mirrors the real card/row shape instead of showing a spinner. A card
       placeholder is a card; a list placeholder is a list.
     • Motion is subtle and slow (1.35s, low-contrast highlight). It reads as
       "working", never as a flashing banner.
     • `prefers-reduced-motion` keeps the placeholder SHAPE and removes the
       sweep — the layout is identical, only the animation stops.
     • A placeholder must be VISIBLE. The shape alone is the loading signal for
       users who ask for reduced motion, so the placeholder has to be legible
       from its FILL, not from its movement. The original tone (#e7ece9 on a
       #ffffff card) measured 1.21:1 and the sweep only reached 1.04:1, so the
       skeletons rendered correctly and still read as empty white cards. The
       shared tokens below are tuned to a measured ~1.9:1 fill and a ~1.7:1
       sweep band — plainly visible at a glance, still a calm soft-grey shape
       rather than a disabled control.
     • A skeleton zone never participates in hit-testing. It is a visual
       placeholder inside a content area; it is never an app-wide lock, never a
       full-viewport overlay, and it can never intercept a navigation tap.
     • Skeletons are announcement-safe: the animated blocks are aria-hidden and
       the zone exposes a polite status with the real loading label, so screen
       readers hear "Loading appointments", not a wall of empty boxes.

   There is no framework here and no JS is required to "start" a skeleton — the
   helper module only produces markup.
   ══════════════════════════════════════════════════════════════════ */

/* Shared placeholder tokens.

   FILL: #b3bfb9 is a calm sage-grey in the DomiCare neutral/mint family. On a
   white surface it measures ~1.9:1 — comfortably above the perceptibility floor
   the previous #e7ece9 (1.21:1) sat below, and deliberately well short of the
   4.5:1 that would make a placeholder read as a disabled control.

   SHINE: a near-white sweep over that fill measures a ~1.7:1 band, so the
   left-to-right movement is actually perceptible. The sweep is widened by the
   gradient below rather than sped up; the animation timing is unchanged. */
.skeleton {
  --sk-base: #b3bfb9;
  --sk-shine: rgba(255, 255, 255, 0.78);
  position: relative;
  display: block;
  overflow: hidden;
  background-color: var(--sk-base);
  border-radius: 8px;
}

.skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background-image: linear-gradient(90deg, transparent 0%, var(--sk-shine) 50%, transparent 100%);
  animation: skeleton-shimmer 1.35s ease-in-out infinite;
}

@keyframes skeleton-shimmer {
  to { transform: translateX(100%); }
}

/* Reduced motion: same geometry, no sweep. */
@media (prefers-reduced-motion: reduce) {
  .skeleton::after { animation: none; background-image: none; }
}

/* Surface-tuned placeholder tone. The default neutral is used outside a
   workspace shell (standalone screens); each shell tints it to its own surface
   so a skeleton never reads as a stray grey block.

   Both keep the SAME measured weight against their own white surface
   (~1.88–1.93:1), so Patient and Practitioner cannot drift apart in
   visibility — they differ only in hue, never in perceptibility.

   Admin renders NO structural skeletons, so it declares no skeleton tint. */
.patient-shell .skeleton { --sk-base: #b0beb7; --sk-shine: rgba(255, 255, 255, 0.78); }
.practitioner-shell .skeleton { --sk-base: #b4c0ba; --sk-shine: rgba(255, 255, 255, 0.78); }

/* Containers that used to hold a centred loading block but now host a
   full-width skeleton list keep their own layout without the legacy centring.

The base `.pmsg-loading` is a centred spinner box (`display: grid;
place-content: center; justify-items: center; padding: 40px 24px`). The
Messages skeleton is a FULL-WIDTH bounded workspace, so the centring box is
dropped while the element stays inside the real `.pmsg-workspace`, which is what
supplies the real bounded height. */
.pmsg-loading.pmsg-skeleton {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  margin: 0;
  padding: 0;
  width: 100%;
  /* `justify-items: center` from the base rule does not only centre a grid —
     in Chromium it also SHRINK-WRAPS block-level children to their max-content
     width, which collapsed the workspace box to 164px inside a 364px column.
     Reset the whole alignment box so the workspace fills its container. */
  justify-items: normal;
  place-content: normal;
  gap: 0;
  text-align: start;
}

/* The zone is the flex chain's middle link: it passes the REAL workspace's
   bounded height down to the placeholder box (rather than the placeholder
   asserting a height of its own, which the Messages page further clamps in JS to
   keep the composer above the mobile bottom dock). */
.pmsg-loading.pmsg-skeleton > .skeleton-zone {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
}

/* ─── Patient Messages workspace placeholder ──────────────────────
   Mirrors `.pmsg-workspace`: a bounded, bordered box that is a TWO-PANE
   workspace (330px conversation list beside a chat pane) and collapses to the
   list pane alone below 760px, with the list pane narrowing to 290px below
   900px — the SAME breakpoints the real Messages page uses, so the placeholder
   cannot reflow into a different geometry the moment conversations arrive. */

.skeleton-conv-workspace {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 20px;
  background: var(--p-surface, #ffffff);
  overflow: hidden;
}

.skeleton-conv-list-pane {
  display: flex;
  width: 330px;
  flex: 0 0 330px;
  flex-direction: column;
  border-right: 1px solid var(--p-border-soft, #eef2f0);
}

.skeleton-conv-list {
  display: grid;
  flex: 1;
  align-content: start;
  gap: 4px;
  padding: 10px;
  overflow: hidden;
}

/* Mirrors `.pmsg-conv-row` + its 42px circular avatar. The real row carries a
   transparent 1px border, which is what makes the avatar sit 23px inside the
   pane instead of 22px — reproduced here so the swap is pixel-exact. */
.skeleton-conv-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px;
  border: 1px solid transparent;
  border-radius: 14px;
}

.skeleton-conv-avatar {
  width: 42px;
  height: 42px;
  flex: 0 0 42px;
  border-radius: 50%;
}

.skeleton-conv-copy {
  display: grid;
  flex: 1 1 auto;
  min-width: 0;
  gap: 2px;
}

/* Mirrors `.pmsg-conv-head` — name line beside the time line. */
.skeleton-conv-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

/* Mirrors the real service pill (a short, low, fully rounded chip). */
.skeleton-conv-pill {
  width: 64px;
  height: 15px;
  border-radius: 999px;
}

/* Mirrors `.pmsg-list-foot`. */
.skeleton-conv-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 11px 16px;
  border-top: 1px solid var(--p-border-soft, #eef2f0);
}

/* Mirrors `.pmsg-chat-pane`. */
.skeleton-conv-chat-pane {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 14px;
  padding: 18px;
}

.skeleton-conv-chat-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--p-border-soft, #eef2f0);
}

.skeleton-conv-feed {
  display: grid;
  flex: 1;
  align-content: start;
  gap: 12px;
}

.skeleton-conv-composer {
  padding-top: 12px;
  border-top: 1px solid var(--p-border-soft, #eef2f0);
}

/* The real `.pmsg-workspace` already draws the workspace border and radius, so
   the placeholder box must not draw a second one inside it — that double border
   inset the list pane by 2px and made the placeholder 2px narrower than the
   real pane. */
.pmsg-loading.pmsg-skeleton .skeleton-conv-workspace {
  border: 0;
  border-radius: 0;
}

@media (max-width: 900px) {
  .skeleton-conv-list-pane { width: 290px; flex-basis: 290px; }
}

@media (max-width: 760px) {
  .skeleton-conv-list-pane { width: 100%; flex-basis: 100%; border-right: 0; }
  .skeleton-conv-chat-pane { display: none; }
}

/* ─── Zone wrapper ─────────────────────────────────────────────── */

/* The zone owns NO pointer events. Skeletons are placeholders, so a stray tap
   inside one must never be swallowed — and, critically, a skeleton can never
   cover or block the application navigation (it is scoped to its own content
   area and has no overlay). */
.skeleton-zone { pointer-events: none; }

/* ─── Primitives ───────────────────────────────────────────────── */

.skeleton-line { height: 11px; border-radius: 6px; }
.skeleton-line-title { width: 54%; height: 15px; border-radius: 7px; }
.skeleton-line-90 { width: 90%; }
.skeleton-line-80 { width: 80%; }
.skeleton-line-70 { width: 70%; }
.skeleton-line-60 { width: 60%; }
.skeleton-line-40 { width: 40%; }

/* Stat/number stand-in for summary cards. */
.skeleton-line-stat { width: 42%; height: 20px; border-radius: 8px; }

.skeleton-pill { width: 84px; height: 22px; border-radius: 999px; }
.skeleton-avatar { width: 40px; height: 40px; border-radius: 50%; flex: 0 0 auto; }
.skeleton-avatar-sm { width: 32px; height: 32px; border-radius: 50%; flex: 0 0 auto; }
.skeleton-chip { width: 46px; height: 46px; border-radius: 12px; flex: 0 0 auto; }

/* ─── Composed blocks ──────────────────────────────────────────── */

.skeleton-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.skeleton-row-body {
  display: grid;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
}

.skeleton-lines { display: grid; gap: 9px; }

.skeleton-card {
  display: grid;
  gap: 11px;
  padding: 16px;
  border: 1px solid var(--p-border, var(--pc-border-soft, var(--admin-border, #e5e9e7)));
  border-radius: 16px;
  background: var(--p-surface, var(--pc-surface, var(--admin-surface-lowest, #ffffff)));
}

.skeleton-card-sm { padding: 13px; gap: 9px; border-radius: 14px; }

.skeleton-list { display: grid; gap: 12px; }

.skeleton-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 820px) {
  .skeleton-grid-services { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .skeleton-grid-summary { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Service-card placeholder — deliberately the same silhouette as the real
   service card (icon, title, one line of copy) so the swap is not a reflow. */
.skeleton-service-card {
  display: grid;
  gap: 11px;
  padding: 16px 18px;
  min-height: 132px;
  align-content: start;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 16px;
  background: var(--p-surface, #ffffff);
}

.skeleton-appointment-card {
  display: flex;
  gap: 14px;
  align-items: center;
  padding: 16px;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 16px;
  background: var(--p-surface, #ffffff);
}

/* ─── Patient Appointments placeholder ─────────────────────────── */

/* Mirrors `.appt-live` — the live/current appointment highlight card. */
.skeleton-live-card {
  display: grid;
  gap: 14px;
  padding: 20px;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 20px;
  background: var(--p-surface, #ffffff);
}

.skeleton-live-body {
  display: flex;
  align-items: center;
  gap: 14px;
}

.skeleton-live-actions {
  display: flex;
  gap: 10px;
}

/* Mirrors `.appt-visit-grid`: ONE column, becoming two at exactly the same
   560px breakpoint the real visit grid uses. A different value here would make
   the placeholders reflow the moment the appointments arrive. */
.skeleton-visit-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin-top: 16px;
}

@media (min-width: 560px) {
  .skeleton-visit-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Mirrors `.appt-visit-card`: 20px padding, 20px radius, column flow. */
.skeleton-visit-card {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 20px;
  background: var(--p-surface, #ffffff);
}

.skeleton-visit-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.skeleton-visit-title {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  min-width: 0;
  flex: 1 1 auto;
}

.skeleton-visit-facts { display: grid; gap: 8px; }

/* ─── Patient Clinical Records placeholder ─────────────────────── */

/* Mirrors `.prec-card`: a substantial card, not three generic lines. */
.skeleton-record-card {
  display: grid;
  gap: 14px;
  padding: 20px 20px 16px;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 20px;
  background: var(--p-surface, #ffffff);
}

.skeleton-record-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 20px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--p-border-soft, #eef2f0);
}

.skeleton-record-title {
  display: flex;
  align-items: center;
  gap: 13px;
  min-width: 0;
  flex: 1 1 auto;
}

/* Mirrors the real record's 46px service icon block. */
.skeleton-record-icon {
  width: 46px;
  height: 46px;
  flex: 0 0 auto;
  border-radius: 12px;
}

.skeleton-record-prac {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.skeleton-record-body { display: grid; gap: 9px; }

.skeleton-record-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--p-border-soft, #eef2f0);
}

/* ─── Patient Profile placeholder ──────────────────────────────── */

/* Mirrors `.ppro-hero`: avatar + name/chip + contact lines + edit action. */
.skeleton-profile-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 22px;
  padding: 24px 26px;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 20px;
  background: var(--p-surface, #ffffff);
}

.skeleton-profile-avatar {
  width: 78px;
  height: 78px;
  flex: 0 0 78px;
  border-radius: 22px;
}

.skeleton-profile-copy {
  min-width: 220px;
  flex: 1 1 320px;
  display: grid;
  gap: 10px;
}

.skeleton-profile-name {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.skeleton-profile-lines { display: grid; gap: 8px; }

.skeleton-profile-action {
  width: 132px;
  min-height: 40px;
  border-radius: 11px;
}

/* Mirrors `.ppro-card` inside `.ppro-sections`. */
.skeleton-profile-card {
  display: grid;
  gap: 14px;
  margin-top: 18px;
  padding: 22px;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 20px;
  background: var(--p-surface, #ffffff);
}

/* Mirrors `.ppro-tile-grid`. */
.skeleton-tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
}

/* Mirrors `.ppro-tile`. */
.skeleton-tile {
  display: grid;
  gap: 8px;
  padding: 14px 15px;
  border: 1px solid var(--p-border-soft, #eef2f0);
  border-radius: 13px;
  background: var(--p-mint-50, #f4faf7);
}

/* Mirrors `.ppro-people-list`. */
.skeleton-people-list { display: grid; gap: 10px; margin-top: 18px; }

.skeleton-person-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--p-border, #e5e9e7);
  border-radius: 14px;
  background: var(--p-surface, #ffffff);
}

/* Profile follows the real page's own responsive rules. */
@media (max-width: 700px) {
  .skeleton-profile-hero { padding: 20px 18px; }
  .skeleton-profile-avatar { width: 62px; height: 62px; flex-basis: 62px; border-radius: 18px; }
  .skeleton-profile-card { padding: 18px 16px 20px; }
}

/* Records follow the real card's narrow-screen padding/stacking. */
@media (max-width: 560px) {
  .skeleton-record-card { padding: 17px 16px 14px; }
  .skeleton-record-top { align-items: flex-start; flex-direction: column; }
  .skeleton-record-foot { flex-direction: column; align-items: stretch; }
}

/* ─── Practitioner Home bento placeholder ────────────────────────
   Mirrors `.op-home` / `.op-bento` / `.op-card` geometry and the real
   breakpoints: the metric strip is 4-up and drops to 2-up at 1059px, and the
   pair rows stack to a single column and become 2-up at 768px. */

.skeleton-op-home { display: flex; flex-direction: column; gap: 20px; min-width: 0; }

.skeleton-op-card {
  display: block;
  min-width: 0;
  padding: 20px 22px;
  border: 1px solid var(--pc-border, #e2e8e4);
  border-radius: 18px;
  background: var(--pc-surface, #ffffff);
}

.skeleton-op-hero { display: flex; flex-direction: column; }

.skeleton-op-hero-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
}

.skeleton-op-hero-copy { display: grid; gap: 10px; min-width: 220px; flex: 1 1 320px; }

.skeleton-op-hero-control {
  display: grid;
  gap: 10px;
  min-width: 190px;
  padding: 14px 16px;
  border: 1px solid var(--pc-border, #e2e8e4);
  border-radius: 14px;
  background: var(--pc-mint-50, #f4faf7);
}

.skeleton-op-hero-metrics {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid rgba(190, 201, 192, 0.35);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
}

.skeleton-op-metric { display: flex; align-items: center; gap: 10px; min-width: 0; }
.skeleton-op-metric .skeleton-chip { flex: 0 0 auto; }

.skeleton-op-bento { display: flex; flex-direction: column; gap: 20px; align-items: start; min-width: 0; }
.skeleton-op-bento-full { width: 100%; }

.skeleton-op-bento-pair {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  width: 100%;
  align-items: start;
}

.skeleton-op-bento-pair > .skeleton-op-card { width: 100%; }

.skeleton-op-card-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.skeleton-op-offers { display: flex; flex-direction: column; gap: 14px; }

.skeleton-op-offer {
  display: grid;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--pc-border, #e2e8e4);
  border-radius: 14px;
  background: rgba(227, 249, 234, 0.35);
}

.skeleton-op-offer-top { display: flex; align-items: center; gap: 10px; }
.skeleton-op-offer-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }

.skeleton-op-sched-list { display: grid; gap: 12px; }
.skeleton-op-sched-row { display: flex; align-items: center; gap: 12px; }
.skeleton-op-sched-row .skeleton-row-body { flex: 1 1 auto; }
.skeleton-op-rail-body { display: grid; gap: 12px; }

/* ─── Practitioner Home bento responsive ─────────────────────────
   IDENTICAL to the real page: `.op-bento-pair` becomes 2-up at 768px,
   `.op-offer-grid` 3-up at 640px, and the hero metric strip drops to 2-up at
   1059px. Opportunity dossier placeholders were removed with the policy change
   (Practitioner secondary routes now use the shared normal loading state). */
@media (min-width: 640px) {
  .skeleton-op-offer-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 768px) {
  .skeleton-op-bento-pair { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 1059px) {
  .skeleton-op-hero-main { flex-direction: column; align-items: stretch; gap: 18px; }
  .skeleton-op-hero-control { min-width: 0; width: 100%; }
  .skeleton-op-hero-metrics { grid-template-columns: repeat(2, 1fr); }
}

/* Definition-list placeholder — STILL USED by the Practitioner main-page
   profile/workspace skeleton. Admin no longer renders skeleton detail blocks,
   so the admin-only detail/grid/checklist/timeline shapes were removed. */
.skeleton-dl { display: grid; gap: 0; }
.skeleton-dl-row {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 18px;
  padding: 13px 0;
  border-bottom: 1px solid var(--admin-border-subtle, #eef2f0);
}

@media (max-width: 768px) {
  .skeleton-dl-row { grid-template-columns: 120px 1fr; gap: 12px; }
}

@media (max-width: 560px) {
  .skeleton-op-card { padding: 18px 16px; }
}

/* Practitioner upcoming grid is 2-up from 720px, matching `.op-upcoming-grid`. */
@media (max-width: 719px) {
  .skeleton-op-upcoming-grid { grid-template-columns: 1fr; }
}

/* ─── Practitioner Profile placeholder ──────────────────────────
   The OUTER scaffold is the real page's own markup: the builder emits
   `.practitioner-workspace.practitioner-profile-page` containing real
   `.practitioner-card` sections, so card padding (22px 24px), radius, border,
   the 18px column gap and the section ORDER come from
   `practitioner-pages.css` and cannot drift. These rules only shape the
   INNER placeholder blocks to the real controls' geometry:

     • `.skeleton-ppro-heading`   ← the real `<h2>` (margin 0 0 16px, 12px
       bottom padding, 1px bottom border, 1.06rem/800)
     • `.skeleton-dl`             ← the real `.practitioner-dl`
       (minmax(150px,auto) 1fr, 9px row padding)
     • `.skeleton-ppro-offerings` ← `.practitioner-offering-list` (2-up ≥768px)
     • `.skeleton-ppro-input`     ← `.practitioner-input` (min-height 44px)
     • `.skeleton-ppro-btn`       ← `.practitioner-btn` (min-height 42px) */

.skeleton-ppro-title {
  width: 240px;
  max-width: 60%;
  height: 30px;
  border-radius: 8px;
}

/* Mirrors the real `<h2>` exactly: 16px gap below, 12px bottom padding and a
   1px bottom rule, so the underlined section headings line up. */
.skeleton-ppro-hd {
  margin: 0 0 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--pc-border-soft, #e2e9e4);
}

.skeleton-ppro-heading {
  display: block;
  width: 168px;
  max-width: 70%;
  height: 17px;
  border-radius: 7px;
}

.skeleton-ppro-offerings {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: 4px;
}

/* Mirrors `.practitioner-offering`: 16px padding, 12px radius, 12px gap. */
.skeleton-ppro-offering {
  display: grid;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--pc-border, #bec9c0);
  border-radius: 12px;
  background: var(--pc-surface, #ffffff);
}

.skeleton-ppro-offering-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.skeleton-ppro-offering-head .skeleton-line { flex: 1 1 auto; }

.skeleton-ppro-toggle { display: flex; align-items: center; }
.skeleton-ppro-toggle .skeleton-line { width: 55%; }

/* Mirrors `.practitioner-form-field` (label above a 44px control). */
.skeleton-ppro-field { display: grid; gap: 7px; }

.skeleton-ppro-input {
  display: block;
  width: 100%;
  height: 44px;
  border-radius: 10px;
}

/* Mirrors `.practitioner-btn` (min-height 42px, 10px radius). */
.skeleton-ppro-btn {
  width: 132px;
  height: 42px;
  border-radius: 10px;
}

.skeleton-ppro-btn-primary { width: 168px; }

.skeleton-ppro-form { display: grid; gap: 16px; }

/* Mirrors `.practitioner-availability-row` (label/description beside the switch). */
.skeleton-ppro-availability {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

/* Mirrors `.practitioner-toggle-track` (46×26). */
.skeleton-ppro-switch {
  width: 46px;
  height: 26px;
  flex: 0 0 46px;
  border-radius: 999px;
}

@media (min-width: 768px) {
  .skeleton-ppro-offerings { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* The real profile card tightens its padding below 700px. */
@media (max-width: 700px) {
  .skeleton-ppro-availability { align-items: flex-start; flex-direction: column; }
}

/* ─── Practitioner workspace / records placeholders ──────────────
   Mirrors `.practitioner-card`, `.practitioner-service-list` and
   `.practitioner-record-card` so the wait previews the real card stack instead
   of a generic three-line card. */

.skeleton-prac-cards { display: flex; flex-direction: column; gap: 18px; min-width: 0; }

.skeleton-prac-card {
  display: grid;
  gap: 14px;
  padding: 22px;
  border: 1px solid var(--prac-border, #e2e8e4);
  border-radius: 18px;
  background: var(--prac-surface, #ffffff);
}

.skeleton-service-rows { display: grid; gap: 10px; }

.skeleton-service-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--prac-border-subtle, #eef2f0);
  border-radius: 12px;
}

.skeleton-service-row .skeleton-row-body { flex: 1 1 auto; }

.skeleton-prac-records { display: grid; gap: 16px; }

.skeleton-prac-record-card {
  display: grid;
  gap: 12px;
  padding: 20px 22px;
  border: 1px solid var(--prac-border, #e2e8e4);
  border-radius: 16px;
  background: var(--prac-surface, #ffffff);
}

.skeleton-prac-record-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

@media (max-width: 560px) {
  .skeleton-prac-card { padding: 18px 16px; }
  .skeleton-prac-record-card { padding: 17px 16px; }
}

/* ─── Practitioner appointments placeholder ──────────────────────
   Mirrors `.op-appt`: header, status tabs, active-care card, upcoming grid and
   completed ledger. `.skeleton-op-upcoming-grid` uses the same 2-column
   breakpoint as the real `.op-upcoming-grid`. */

.skeleton-op-appt { display: flex; flex-direction: column; gap: 20px; min-height: 60vh; }

.skeleton-op-appt-active-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.skeleton-op-appt-active-body { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.skeleton-op-appt-active-body .skeleton-row-body { flex: 1 1 240px; }
.skeleton-op-appt-actions { display: flex; gap: 10px; }

.skeleton-op-upcoming-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }

.skeleton-op-upcoming {
  display: grid;
  gap: 10px;
  padding: 18px;
  border: 1px solid var(--prac-border, #e2e8e4);
  border-radius: 16px;
  background: var(--prac-surface, #ffffff);
}

.skeleton-op-upcoming-top { display: flex; align-items: center; gap: 12px; }
.skeleton-op-upcoming-top .skeleton-row-body { flex: 1 1 auto; }
.skeleton-op-upcoming-meta { display: flex; flex-wrap: wrap; gap: 10px; }

.skeleton-op-ledger { display: grid; gap: 0; }
.skeleton-op-ledger-row {
  display: grid;
  grid-template-columns: 2fr 1.4fr 1fr;
  gap: 16px;
  align-items: center;
  padding: 14px 16px;
  border-bottom: 1px solid var(--prac-border-subtle, #eef2f0);
}

@media (min-width: 720px) {
  .skeleton-op-upcoming-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 767px) {
  .skeleton-op-ledger-row { grid-template-columns: 1fr; gap: 8px; }
}

/* ─── Practitioner messages placeholder ──────────────────────────
   Mirrors `.practitioner-message-card`: name + time header, service line,
   preview line. */

.skeleton-pmsg-list { display: grid; gap: 12px; }

.skeleton-pmsg-card {
  display: grid;
  gap: 9px;
  padding: 16px 18px;
  border: 1px solid var(--prac-border, #e2e8e4);
  border-radius: 14px;
  background: var(--prac-surface, #ffffff);
}

.skeleton-pmsg-hd { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
