/* ═══════════════════════════════════════════════════════════════
   TEGO UI KIT — token layer 2 (Wave 0, Jul 2026)
   Single source of truth the views converge on. Loaded AFTER the
   base <style> in index.html. Wave 0 ships tokens + utilities with
   ZERO intended visual change — values map to what's already live.
   Rules of the road:
   - New/refactored view code uses these tokens, never raw hex.
   - Interactive or label text never below var(--fs-xs).
   - One green means "good" (--ok), one amber "caution" (--warn),
     one red "bad" (--danger), one blue "info". Brand greens are
     for brand, not for status.
   ═══════════════════════════════════════════════════════════════ */
:root{
  /* The CRM is a light-themed app (white cards, dark text). Pin the color-scheme to light
     so native controls (selects, date pickers, option lists) always render light to match —
     otherwise an OS in dark mode paints them dark-on-light and they read as broken "white/grey"
     boxes. (The estimator is the dark app and sets color-scheme:dark on its own root.) */
  color-scheme: light;
  /* spacing scale — replaces 128 ad-hoc padding values */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px; --s7:32px;

  /* type scale — replaces 66 ad-hoc font sizes */
  --fs-2xs:0.68rem;   /* chips, table micro-meta — display only, never interactive */
  --fs-xs:0.72rem;    /* labels, sublines — the floor for anything a user must read to act */
  --fs-sm:0.8rem;     /* secondary body, table cells */
  --fs-md:0.875rem;   /* body, buttons, fields */
  --fs-lg:1.05rem;    /* card titles, page subtitles */
  --fs-xl:1.3rem;     /* page titles */
  --fs-hero:1.6rem;   /* the one big number on a screen */

  /* semantic status — replaces ~30 status hexes (7 greens, 10 ambers, 3 reds…) */
  --ok:#0E9421;        --ok-soft:#E4F6E7;
  --warn:#B45309;      --warn-soft:#FEF3C7;
  --danger:#B91C1C;    --danger-soft:#FEE2E2;
  --info:#2563EB;      --info-soft:#E7EFFD;

  /* neutrals that pass AA at small sizes (replaces #94a3b8 ≈2.6:1 and friends) */
  --muted-strong:#5B6E62;   /* 5.4:1 on white — table headers, micro-labels */
  --placeholder:#7E8F83;    /* 4.6:1 — placeholder text that must survive sunlight */

  /* z scale — replaces 13 colliding literals */
  --z-nav:40; --z-panel:200; --z-modal:4000; --z-toast:9000; --z-top:12000;

  /* one modal scrim (green-family, matches the majority pattern) */
  --scrim:rgba(15,45,31,.48);
}

/* ── Utilities the helpers emit (namespaced ui-*) ── */
.ui-scrim{position:fixed;inset:0;background:var(--scrim);z-index:var(--z-modal);display:flex;align-items:flex-start;justify-content:center;overflow:auto;padding:5vh 12px}
.ui-modal{background:var(--surface);border-radius:var(--radius);box-shadow:var(--shadow-lg);width:100%;max-width:520px;margin:auto 0;padding:var(--s5) var(--s5) var(--s4)}
.ui-modal:focus{outline:none}
.ui-modal-title{font-size:var(--fs-lg);font-weight:800;color:var(--ink);margin:0 0 var(--s2)}
.ui-modal-body{font-size:var(--fs-md);color:var(--ink-soft);line-height:1.5}
.ui-modal-actions{display:flex;gap:var(--s2);justify-content:flex-end;margin-top:var(--s5);flex-wrap:wrap}
.btn-danger{background:var(--danger);color:#fff;border:1px solid transparent}
.btn-danger:hover{background:#991B1B}
.ui-empty{padding:var(--s7) var(--s4);text-align:center;color:var(--muted);font-size:var(--fs-md);border:1px dashed var(--line);border-radius:var(--radius);background:var(--surface)}
.ui-empty .ui-empty-ico{font-size:1.6rem;display:block;margin-bottom:var(--s2)}
.ui-empty .ui-empty-cta{margin-top:var(--s3)}
.ui-chip{display:inline-flex;align-items:center;gap:4px;font-size:var(--fs-2xs);font-weight:700;padding:2px 9px;border-radius:999px;line-height:1.7;white-space:nowrap}
.ui-chip.t-ok{background:var(--ok-soft);color:var(--ok)}
.ui-chip.t-warn{background:var(--warn-soft);color:var(--warn)}
.ui-chip.t-danger{background:var(--danger-soft);color:var(--danger)}
.ui-chip.t-info{background:var(--info-soft);color:var(--info)}
.ui-chip.t-neutral{background:var(--line-soft);color:var(--ink-soft)}
.ui-chip.t-brand{background:var(--accent-lt);color:var(--brand)}
/* money/table helpers */
.ui-th{font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.05em;color:var(--muted-strong);font-weight:800;text-align:left;padding:6px 8px}
.ui-td-money{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
/* focusable list-row (replaces clickable divs/trs as they migrate) */
.ui-row{display:flex;align-items:center;gap:var(--s3);width:100%;text-align:left;background:none;border:none;font:inherit;color:inherit;cursor:pointer;padding:var(--s2) var(--s1);border-radius:8px}
.ui-row:hover{background:#F6FAF6}
.ui-row:focus-visible{outline:2px solid rgba(20,181,41,.55);outline-offset:2px}

/* ═══ Wave 2 — shell & navigation ═══ */
/* side links are real <button>s now — strip UA chrome, keep the .side-link look */
button.side-link{appearance:none;background:transparent;border:none;width:100%;font:inherit;text-align:left}
/* skip link: hidden until keyboard focus */
.skiplink{position:absolute;left:-9999px;top:0;z-index:600;background:var(--accent);color:#fff;font-weight:700;padding:10px 16px;border-radius:0 0 10px 0;text-decoration:none}
.skiplink:focus{left:0}
/* focused main region shouldn't draw a ring (it's a programmatic focus target) */
#view:focus{outline:none}

/* ═══ Wave 1 — app-wide field ergonomics ═══ */
/* Toasts must clear the mobile bottom bar, not sit under the thumb on it */
@media (max-width:940px){
  #toastWrap{bottom:calc(74px + env(safe-area-inset-bottom))}
}
/* Classless buttons (disposition tiles, inline toggles) get jobsite tap targets.
   .btn/.btn-sm already handled by the base layer; .stg-node & seg internals excluded
   because their geometry is meaningful. */
@media (pointer:coarse){
  #view button:not(.btn):not(.stg-node){min-height:44px}
  #view select:not(.field){min-height:40px}
}
/* View-switch fade only on REAL view switches (app.js adds .vfresh in renderActiveView);
   re-renders while typing no longer replay the animation = no flicker while searching. */
#view>*:first-child{animation:none}
#view.vfresh>*:first-child{animation:viewIn .22s var(--ease)}
@media (prefers-reduced-motion:reduce){ #view.vfresh>*:first-child{animation:none} }

/* ═══ Wave 7 — premium visual layer + canvass command center (Jul 2026) ═══
   Token layer 3. Two greens do all the talking: g-900 anchors, g-500 is spent
   only on wins/CTAs/live. Everything else is a green-biased neutral. No third
   hue exists in data-viz; --ok/--warn/--danger stay reserved for SYSTEM status
   (offline, save failures) and never appear in charts. */
:root{
  /* green ramp — brand endpoints, five working steps */
  --g-950:#052508; --g-900:#083C0E; --g-700:#0A5C13; --g-500:#14B529;
  --g-300:#7BDB8A; --g-150:#C8EFCE; --g-050:#E9F8EB;
  /* green-biased neutrals */
  --n-900:#14201A; --n-700:#3D4B42; --n-500:#64756B; --n-400:#8A9A90;
  --n-300:#B9C6BD; --n-200:#DDE4DE; --n-100:#EDF1EE; --n-050:#F7FAF7;
  /* disposition tokens (mirror DISPO_COLOR in canvass.js — Leaflet needs raw hex) */
  --cv-lead:#14B529; --cv-callback:#0A5C13; --cv-noanswer:#DDE4DE;
  --cv-notint:#5C6D63; --cv-dnk:#14201A; --cv-dq:#B9C6BD; --cv-sold:#083C0E;
  /* elevation — soft, low-spread, green-tinted; replaces harsh 1px borders */
  --shadow-sm:0 1px 2px rgba(8,60,14,.06);
  --shadow-md:0 2px 8px rgba(8,60,14,.08), 0 1px 2px rgba(8,60,14,.05);
  --shadow-lg:0 8px 28px rgba(8,60,14,.12), 0 2px 6px rgba(8,60,14,.06);
  /* radius family: 8 controls · 12 cards · 16 hero */
  --r-ctl:8px; --r-card:12px; --r-hero:16px;
  /* motion */
  --t-fast:150ms; --t-med:200ms; --t-draw:500ms;
  /* number heroes */
  --fs-num-lg:1.75rem;   /* KPI cards */
  --fs-num-hero:2.5rem;  /* the one number a homeowner stares at */
}

/* ── command-center filter bar ── */
.cv-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.cv-seg{display:inline-flex;background:var(--n-100);border-radius:10px;padding:3px;gap:2px}
.cv-seg button{border:none;background:transparent;color:var(--n-500);font:inherit;font-size:var(--fs-sm);
  font-weight:700;padding:8px 14px;min-height:38px;border-radius:8px;cursor:pointer;
  transition:background var(--t-fast) ease,color var(--t-fast) ease}
.cv-seg button.on{background:#fff;color:var(--n-900);box-shadow:var(--shadow-sm)}
.cv-live{display:inline-flex;align-items:center;gap:7px;font-size:var(--fs-xs);font-weight:800;color:var(--g-700);
  background:var(--g-050);border-radius:999px;padding:6px 12px}
.cv-live .dot{width:8px;height:8px;border-radius:50%;background:var(--g-500);animation:cvPulse 1.6s ease-in-out infinite}
@keyframes cvPulse{0%,100%{box-shadow:0 0 0 0 rgba(20,181,41,.45)}55%{box-shadow:0 0 0 6px rgba(20,181,41,0)}}

/* ── KPI cards ── */
.cv-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(146px,1fr));gap:10px;margin-bottom:12px}
.cv-kpi{background:#fff;border:1px solid var(--n-100);border-radius:var(--r-card);box-shadow:var(--shadow-sm);
  padding:14px 14px 10px;display:flex;flex-direction:column;gap:2px;min-height:106px;text-align:left;
  font:inherit;color:inherit;cursor:pointer;transition:box-shadow var(--t-fast) ease,transform var(--t-fast) ease}
.cv-kpi:hover{box-shadow:var(--shadow-md);transform:translateY(-1px)}
.cv-kpi:focus-visible{outline:2px solid rgba(20,181,41,.55);outline-offset:2px}
.cv-kpi .l{font-size:var(--fs-2xs);font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--n-500)}
.cv-kpi .v{font-size:var(--fs-num-lg);font-weight:800;letter-spacing:-.02em;color:var(--n-900);
  font-variant-numeric:tabular-nums;line-height:1.1}
.cv-kpi .v small{font-size:1rem;font-weight:750;color:var(--n-500)}
.cv-kpi .f{display:flex;align-items:flex-end;justify-content:space-between;gap:6px;margin-top:auto}
.cv-delta{font-size:var(--fs-2xs);font-weight:800;font-variant-numeric:tabular-nums;padding:2px 8px;border-radius:999px;white-space:nowrap}
.cv-delta.up{background:var(--g-050);color:var(--g-700)}
.cv-delta.dn{background:var(--n-100);color:var(--n-500)}

/* ── funnel ── */
.cv-funnel{display:grid;gap:0}
.cvf-row{display:grid;grid-template-columns:118px 1fr;align-items:center;gap:12px;min-height:46px}
.cvf-name{font-size:var(--fs-sm);font-weight:750;color:var(--n-700);text-align:right;line-height:1.2}
.cvf-name small{display:block;font-weight:500;color:var(--n-400);font-size:var(--fs-2xs)}
.cvf-wrap{position:relative;height:36px;background:var(--n-050);border-radius:8px;cursor:pointer}
.cvf-wrap:hover .cvf-fill{filter:brightness(1.05)}
.cvf-fill{position:absolute;inset:0 auto 0 0;border-radius:8px;transform-origin:left center;
  animation:cvGrow var(--t-draw) cubic-bezier(.2,.8,.2,1)}
@keyframes cvGrow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.cvf-n{position:absolute;top:50%;transform:translateY(-50%);font-size:1rem;font-weight:800;
  font-variant-numeric:tabular-nums;letter-spacing:-.01em;animation:cvFade .7s ease}
@keyframes cvFade{from{opacity:0}to{opacity:1}}
.cvf-join{grid-column:2;display:flex;align-items:center;gap:8px;height:20px;padding-left:20px}
.cvf-conv{font-size:var(--fs-sm);font-weight:800;font-variant-numeric:tabular-nums;color:var(--g-700)}
.cvf-conv small{font-weight:600;color:var(--n-400);font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.05em;margin-left:4px}
.cvf-tick{position:absolute;top:-4px;bottom:-4px;width:2px;background:var(--n-900);opacity:.45;border-radius:2px}

/* ── disposition mix ── */
.cv-mix{display:flex;height:30px;border-radius:8px;overflow:hidden;gap:2px}
.cv-mix>div{display:flex;align-items:center;justify-content:center;font-size:var(--fs-2xs);font-weight:800;
  font-variant-numeric:tabular-nums;min-width:0}
.cv-legend{display:flex;flex-wrap:wrap;gap:10px 14px;margin-top:10px;font-size:var(--fs-2xs);color:var(--n-700);font-weight:600}
.cv-legend .li{display:inline-flex;align-items:center;gap:5px}
.cv-legend .sw{width:10px;height:10px;border-radius:3px;flex:none;border:1px solid rgba(20,32,26,.12)}

/* ── heatmap ── */
.cv-heat{display:grid;gap:2px;font-variant-numeric:tabular-nums}
.cv-heat .hcell{aspect-ratio:auto;height:22px;border-radius:4px;position:relative}
.cv-heat .hlbl{font-size:var(--fs-2xs);color:var(--n-500);display:flex;align-items:center;justify-content:center;height:22px}
.cv-heat .hdot{position:absolute;top:2px;right:2px;width:5px;height:5px;border-radius:50%;background:var(--g-500)}

/* ── leaderboard ── */
.cv-lb{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
.cv-lb td{padding:9px 8px;border-top:1px solid var(--n-100)}
.cv-lb tr.rowbtn{cursor:pointer;transition:background var(--t-fast) ease}
.cv-lb tr.rowbtn:hover{background:var(--n-050)}
.cv-av{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;
  background:var(--g-050);color:var(--g-700);font-size:var(--fs-2xs);font-weight:800;flex:none}
.cv-rank{font-variant-numeric:tabular-nums;font-weight:800;color:var(--n-500);width:26px;display:inline-block}
.cv-move{font-size:var(--fs-2xs);font-weight:800}
.cv-move.up{color:var(--g-700)} .cv-move.dn{color:var(--n-400)}

/* ── dash cards & skeletons ── */
.cv-card{background:#fff;border:1px solid var(--n-100);border-radius:var(--r-card);box-shadow:var(--shadow-sm);padding:14px}
.cv-card .ct{font-size:var(--fs-sm);font-weight:800;color:var(--n-900);margin-bottom:10px;display:flex;align-items:center;gap:8px}
.cv-card .ct .sub{font-weight:600;color:var(--n-400);font-size:var(--fs-2xs)}
.cv-skel{border-radius:var(--r-card);background:linear-gradient(90deg,var(--n-100) 25%,var(--n-050) 45%,var(--n-100) 65%);
  background-size:200% 100%;animation:cvShimmer 1.2s linear infinite}
@keyframes cvShimmer{from{background-position:200% 0}to{background-position:-200% 0}}
@media (prefers-reduced-motion:reduce){
  .cvf-fill,.cvf-n,.cv-skel,.cv-live .dot{animation:none}
}

/* ── Wave 8: field-ops additions (live reps, route stops, goals, follow-ups) ── */
.cv-liveMark{width:34px;height:34px;border-radius:50%;background:var(--g-500);color:#052508;
  display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:800;
  border:3px solid #fff;box-shadow:0 0 0 0 rgba(20,181,41,.5);animation:cvLivePing 1.8s ease-out infinite}
@keyframes cvLivePing{0%{box-shadow:0 0 0 0 rgba(20,181,41,.5)}70%{box-shadow:0 0 0 14px rgba(20,181,41,0)}100%{box-shadow:0 0 0 0 rgba(20,181,41,0)}}
.cv-routeStop{width:24px;height:24px;border-radius:50%;background:var(--g-900);color:#fff;
  display:inline-flex;align-items:center;justify-content:center;font-size:0.72rem;font-weight:800;
  border:2.5px solid #fff;box-shadow:var(--shadow-md);font-variant-numeric:tabular-nums}
.cv-goal{display:block;height:5px;border-radius:99px;background:var(--n-100);overflow:hidden;margin-top:5px}
.cv-goal>span{display:block;height:100%;border-radius:99px;background:var(--g-500);transition:width .5s cubic-bezier(.2,.8,.2,1)}
.cv-goal>span.done{background:var(--g-700)}
.cv-goalTxt{font-size:var(--fs-2xs);color:var(--n-500);font-weight:700;font-variant-numeric:tabular-nums}
.cv-fu{display:flex;gap:8px;align-items:center;padding:7px 0;border-top:1px solid var(--n-100);font-size:var(--fs-sm)}
.cv-fu .due{font-size:var(--fs-2xs);font-weight:800;padding:2px 8px;border-radius:999px;white-space:nowrap;font-variant-numeric:tabular-nums}
.cv-fu .due.over{background:var(--warn-soft);color:var(--warn)}
.cv-fu .due.ok{background:var(--g-050);color:var(--g-700)}
.cv-fuChip{border:1px solid var(--n-200);background:#fff;border-radius:999px;padding:4px 10px;
  font-size:var(--fs-2xs);font-weight:800;color:var(--g-700);cursor:pointer;min-height:30px}
.cv-fuChip:hover{background:var(--g-050);border-color:var(--g-300)}
@media (prefers-reduced-motion:reduce){ .cv-liveMark{animation:none} }

/* ═══ First-run guided tour (tour.js) + uiTip help affordance (ui.js) ═══
   Additive, self-contained, token-driven. Nothing here affects any view
   until window.startTour() injects .tour-root, and it removes itself on
   finish/skip. Theme-aware via prefers-color-scheme. */
.tour-root{position:fixed;inset:0;z-index:var(--z-top,12000);
  /* the scrim itself is transparent; the spotlight paints the dim via box-shadow */
  animation:tourFade var(--t-fast,150ms) ease}
@keyframes tourFade{from{opacity:0}to{opacity:1}}
.tour-spot{position:fixed;border-radius:10px;pointer-events:none;
  box-shadow:0 0 0 9999px rgba(6,24,14,.62), 0 0 0 3px var(--g-500,#14B529);
  transition:top var(--t-med,200ms) var(--ease), left var(--t-med,200ms) var(--ease),
    width var(--t-med,200ms) var(--ease), height var(--t-med,200ms) var(--ease)}
.tour-tip{position:fixed;z-index:1;width:min(320px,calc(100vw - 24px));
  background:var(--surface,#fff);color:var(--ink,#15231B);
  border:1px solid var(--line,#E2EAE3);border-radius:var(--r-card,12px);
  box-shadow:var(--shadow-lg);padding:16px 16px 14px;outline:none}
.tour-tip:focus{outline:none}
.tour-step{font-size:var(--fs-2xs,0.68rem);font-weight:800;text-transform:uppercase;
  letter-spacing:.07em;color:var(--g-700,#0A5C13)}
.tour-title{font-size:var(--fs-lg,1.05rem);font-weight:800;color:var(--ink,#15231B);margin:4px 0 6px;line-height:1.2}
.tour-body{font-size:var(--fs-md,0.875rem);color:var(--ink-soft,#3E5247);line-height:1.5}
.tour-dots{display:flex;gap:6px;margin:12px 0 0}
.tour-dot{width:7px;height:7px;border-radius:50%;background:var(--n-200,#DDE4DE)}
.tour-dot.on{background:var(--g-500,#14B529)}
.tour-actions{display:flex;align-items:center;gap:8px;margin-top:14px}
.tour-spacer{flex:1}
.tour-skip{border:none;background:none;font:inherit;font-size:var(--fs-sm,0.8rem);font-weight:700;
  color:var(--muted,#6B7F73);cursor:pointer;padding:6px 4px;min-height:36px}
.tour-skip:hover{color:var(--ink,#15231B)}
.tour-btn{border:1px solid transparent;border-radius:var(--r-ctl,8px);font:inherit;
  font-size:var(--fs-sm,0.8rem);font-weight:700;cursor:pointer;padding:8px 14px;min-height:36px}
.tour-back{background:var(--surface,#fff);border-color:var(--line,#E2EAE3);color:var(--ink-soft,#3E5247)}
.tour-back:hover{border-color:var(--n-300,#B9C6BD)}
.tour-next{background:var(--g-500,#14B529);color:#fff;box-shadow:0 2px 6px rgba(20,181,41,.28)}
.tour-next:hover{background:var(--accent-dk,#0E9421)}
.tour-btn:focus-visible,.tour-skip:focus-visible{outline:2px solid rgba(20,181,41,.55);outline-offset:2px}
@media (pointer:coarse){ .tour-btn,.tour-skip{min-height:44px} }
@media (prefers-reduced-motion:reduce){ .tour-root,.tour-spot{animation:none;transition:none} }

/* uiTip: inline "?" pill + tap-to-show note */
.ui-tip{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;
  margin-left:5px;padding:0;border:1px solid var(--n-300,#B9C6BD);border-radius:50%;
  background:var(--n-050,#F7FAF7);color:var(--muted-strong,#5B6E62);
  font:inherit;font-size:0.66rem;font-weight:800;line-height:1;cursor:pointer;vertical-align:middle}
.ui-tip:hover{border-color:var(--g-500,#14B529);color:var(--g-700,#0A5C13)}
.ui-tip:focus-visible{outline:2px solid rgba(20,181,41,.55);outline-offset:2px}
.ui-tip-note{display:inline-block;margin-left:6px;max-width:min(260px,80vw);vertical-align:middle;
  background:var(--n-900,#14201A);color:#fff;border-radius:8px;padding:5px 9px;
  font-size:var(--fs-xs,0.72rem);font-weight:600;line-height:1.35;box-shadow:var(--shadow-md)}

/* Dark-scheme friendliness — the app currently ships light, but if a viewer
   forces dark we keep the tour card & tip note legible. */
@media (prefers-color-scheme:dark){
  .tour-tip{background:#14201A;color:#EDF1EE;border-color:#2A3A30}
  .tour-title{color:#EDF1EE}
  .tour-body{color:#B9C6BD}
  .tour-back{background:#1B2A22;border-color:#2A3A30;color:#DDE4DE}
  .ui-tip{background:#1B2A22;border-color:#3D4B42;color:#B9C6BD}
  .ui-tip-note{background:#052508}
}

/* ── long-list perf: skip rendering off-screen cards ──────────────────────────
   content-visibility:auto lets the browser skip layout/paint for cards scrolled
   out of view; contain-intrinsic-size:auto reserves each card's real height (kept
   once it has rendered once) so the scrollbar and scroll position stay stable.
   Pure progressive enhancement — engines without content-visibility (older
   Safari/Firefox) ignore it and render the list exactly as before. */
.long-list > .card,
.long-list > details{ content-visibility:auto; contain-intrinsic-size:auto 76px; }

/* P8 (audit): skeleton loading rows — used wherever a fetch would otherwise flash bare text */
@keyframes uiSkel{0%{background-position:-200px 0}100%{background-position:200px 0}}
.ui-skel{display:block;height:14px;border-radius:7px;margin:10px 0;
  background:linear-gradient(90deg,#eef2f0 25%,#e2ebe4 37%,#eef2f0 63%);
  background-size:400px 100%;animation:uiSkel 1.2s ease-in-out infinite}
.ui-skel.lg{height:22px}.ui-skel.w40{width:40%}.ui-skel.w60{width:60%}.ui-skel.w80{width:80%}
@media (prefers-reduced-motion:reduce){.ui-skel{animation:none}}
