/* ============================================================================
   Titan Fitness Club — UI States System  ·  ui-states.css
   Loading (skeleton) · Empty · Error · Toast · Retry

   INHERITS the platform's existing OKLCH token system. Every page already
   defines these in :root (and re-defines them per [data-theme] and on the
   cream landing surface), so this file adapts automatically — dark app,
   light app, and cream landing — with zero per-page config.

   Tokens consumed (with safe fallbacks):
     --bg2 --bg3  surface bands      --surface --surface-h  glass fills
     --border --border-h  hairlines  --text --text2 --text3  cream ink
     --red --red-h --red-gl  brand   --green --green-gl  --card-bg
     --sh-md --sh-lg  shadows        --t --t-fast  Titan easing
     --r radius      --fd display(Roca One)   --fb body(Outfit)
   ============================================================================ */

:root {
  /* shimmer derived from the same translucent surfaces the cards use */
  --tfs-skel-base:  var(--surface, oklch(100% 0 0 / .042));
  --tfs-skel-shine: var(--surface-h, oklch(100% 0 0 / .10));
  /* card chrome = the platform card recipe */
  --tfs-card-bg:     var(--card-bg, oklch(100% 0 0 / .04));
  --tfs-card-radius: 16px;     /* between --r (10) and modal radius; matches .mc family */
  --tfs-ease:        var(--t, .25s cubic-bezier(.22,1,.36,1));
  --tfs-fd:          var(--fd, 'Roca One','Impact','Arial Black',sans-serif);
  --tfs-fb:          var(--fb, 'Outfit','Helvetica Neue',Arial,sans-serif);
}

/* ============================================================================
   1 · SKELETON LOADING
   ============================================================================ */
.tfs-skeleton-wrap { display: grid; gap: 16px; width: 100%; animation: fadeIn .3s var(--tfs-ease) both; }
/* se o container pai já for um grid, o esqueleto/estado ocupa a linha toda */
.tfs-skeleton-wrap, .tfs-state { grid-column: 1 / -1; }
.tfs-skeleton-wrap[data-layout="grid"]  { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.tfs-skeleton-wrap[data-layout="stats"] { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

/* shimmering primitive */
.tfs-sk {
  position: relative; overflow: hidden;
  background: var(--tfs-skel-base);
  border-radius: 8px;
}
.tfs-sk::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent 0%, var(--tfs-skel-shine) 50%, transparent 100%);
  animation: tfs-shimmer 1.4s var(--tfs-ease) infinite;
}
@keyframes tfs-shimmer { 100% { transform: translateX(100%); } }

/* skeleton card = same glass/border/shadow as a real Titan card */
.tfs-sk-card {
  background: var(--tfs-card-bg);
  border: 1px solid var(--border, oklch(100% 0 0 / .09));
  border-radius: var(--tfs-card-radius);
  box-shadow: var(--sh-md, 0 4px 20px rgba(0,0,0,.45));
  padding: 18px;
  display: flex; flex-direction: column; gap: 13px;
}

.tfs-sk-thumb  { width: 100%; aspect-ratio: 16 / 10; border-radius: 12px; }
.tfs-sk-cover  { width: 100%; aspect-ratio: 3 / 4;  border-radius: 12px; }
.tfs-sk-avatar { width: 44px; height: 44px; border-radius: 50%; flex: 0 0 auto; }
.tfs-sk-line   { height: 12px; border-radius: 6px; }
.tfs-sk-line.lg{ height: 18px; } .tfs-sk-line.sm{ height: 9px; }
.tfs-sk-line.w90{width:90%;} .tfs-sk-line.w70{width:70%;} .tfs-sk-line.w50{width:50%;}
.tfs-sk-line.w40{width:40%;} .tfs-sk-line.w30{width:30%;}
.tfs-sk-badge  { width: 72px; height: 22px; border-radius: 999px; }
.tfs-sk-btn    { width: 100%; height: 42px; border-radius: 10px; margin-top: auto; }
.tfs-sk-row    { display: flex; align-items: center; gap: 12px; }
.tfs-sk-num    { width: 96px; height: 30px; border-radius: 8px; }
.tfs-sk-bars   { display: flex; align-items: flex-end; gap: 10px; height: 160px; padding-top: 8px; }
.tfs-sk-bars > .tfs-sk { flex: 1; border-radius: 6px 6px 0 0; }
.tfs-sk-table  { display: grid; gap: 10px; }
.tfs-sk-trow   { display: grid; grid-template-columns: 1.4fr 1fr 1fr .6fr; gap: 14px; align-items: center; }

/* ============================================================================
   2 · EMPTY  ·  3 · ERROR   (shared message-card chrome — like the upgrade modal body)
   ============================================================================ */
.tfs-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 14px;
  padding: clamp(32px, 6vw, 56px) 26px;
  background: var(--tfs-card-bg);
  border: 1px solid var(--border, oklch(100% 0 0 / .09));
  border-radius: var(--tfs-card-radius);
  box-shadow: var(--sh-lg, 0 10px 48px rgba(0,0,0,.5));
  color: var(--text, oklch(88% .014 72));
  animation: fadeUp .45s var(--tfs-ease) both;
  transition: transform var(--t,.25s) var(--tfs-ease),
              box-shadow var(--t,.25s) var(--tfs-ease),
              border-color var(--t,.25s) var(--tfs-ease);
}
/* hover = mesma linguagem dos cards .mc da plataforma: sobe + brilho vermelho */
.tfs-state:hover {
  transform: translateY(-4px);
  border-color: rgba(186,21,37,.45);
  box-shadow: 0 12px 32px rgba(186,21,37,.2), 0 0 0 1px rgba(186,21,37,.3),
              var(--sh-lg, 0 10px 48px rgba(0,0,0,.5));
}
.tfs-state__icon {
  width: 72px; height: 72px; display: grid; place-items: center; border-radius: 50%;
  color: var(--text2, oklch(68% .011 72));
  background: var(--surface, oklch(100% 0 0 / .042));
  border: 1px solid var(--border, oklch(100% 0 0 / .09));
  animation: tfs-float 3.6s var(--tfs-ease) infinite;
  transition: color var(--t,.25s) var(--tfs-ease), background var(--t,.25s) var(--tfs-ease),
              border-color var(--t,.25s) var(--tfs-ease), box-shadow var(--t,.25s) var(--tfs-ease);
}
.tfs-state__icon svg { width: 30px; height: 30px; }
/* emoji grande no lugar do ícone vetorial */
.tfs-state__icon.tfs-emoji { font-size: 38px; line-height: 1; }
/* o ícone reage ao hover do card: anel vermelho de brilho */
.tfs-state:hover .tfs-state__icon {
  background: var(--red-gl, oklch(42% .195 22 / .28));
  border-color: rgba(186,21,37,.5);
  box-shadow: 0 0 0 6px var(--red-gl, oklch(42% .195 22 / .28));
}
/* cada emoji tem a sua animação, combinando com o contexto */
.tfs-state__icon[data-anim="dumbbell"]{ animation: tfs-lift      1.7s var(--tfs-ease) infinite; } /* 🏋️ levanta */
.tfs-state__icon[data-anim="book"]    { animation: tfs-wiggle    2.6s var(--tfs-ease) infinite; } /* 📚 balança */
.tfs-state__icon[data-anim="calendar"]{ animation: tfs-wiggle    2.6s var(--tfs-ease) infinite; } /* 📅 */
.tfs-state__icon[data-anim="search"]  { animation: tfs-wiggle    2.6s var(--tfs-ease) infinite; } /* 🔍 */
.tfs-state__icon[data-anim="chart"]   { animation: tfs-bob       3s   var(--tfs-ease) infinite; } /* 📊 flutua */
.tfs-state__icon[data-anim="empty"]   { animation: tfs-bob       3.4s var(--tfs-ease) infinite; } /* 📭 */
.tfs-state__icon[data-anim="info"]    { animation: tfs-ring      2.6s var(--tfs-ease) infinite; } /* 🔔 toca */
.tfs-state__icon[data-anim="success"] { animation: tfs-celebrate 2s   var(--tfs-ease) infinite; } /* ✅ comemora */

@keyframes tfs-float { 0%,100%{ transform: translateY(0) scale(1); } 50%{ transform: translateY(-5px) scale(1.04); } }
@keyframes tfs-bob   { 0%,100%{ transform: translateY(0); } 50%{ transform: translateY(-6px); } }
@keyframes tfs-lift  { 0%,100%{ transform: translateY(0) scale(1); } 25%{ transform: translateY(-9px) scale(1.06); } 50%{ transform: translateY(0) scale(1); } }
@keyframes tfs-wiggle{ 0%,100%{ transform: rotate(0); } 25%{ transform: rotate(-9deg); } 75%{ transform: rotate(9deg); } }
@keyframes tfs-ring  { 0%,60%,100%{ transform: rotate(0); } 10%{ transform: rotate(16deg); } 20%{ transform: rotate(-13deg); } 30%{ transform: rotate(11deg); } 40%{ transform: rotate(-8deg); } 50%{ transform: rotate(4deg); } }
@keyframes tfs-celebrate { 0%,100%{ transform: scale(1) rotate(0); } 50%{ transform: scale(1.15) rotate(6deg); } }
@keyframes tfs-shake { 0%,100%{ transform: translateX(0); } 15%{ transform: translateX(-4px); } 30%{ transform: translateX(4px); } 45%{ transform: translateX(-3px); } 60%{ transform: translateX(3px); } 75%{ transform: translateX(-2px); } }

.tfs-state__title {
  font-family: var(--tfs-fd);
  font-size: clamp(1.05rem, 2.4vw, 1.3rem); font-weight: 400; letter-spacing: -.01em; margin: 2px 0 0;
}
.tfs-state__msg {
  font-family: var(--tfs-fb); font-size: .95rem; line-height: 1.55;
  color: var(--text2, oklch(68% .011 72)); max-width: 42ch; margin: 0;
}

/* error accent — uses --red just like .cat-tab.active / primary actions */
.tfs-state--error .tfs-state__icon {
  color: var(--red, oklch(42% .195 22));
  background: var(--red-gl, oklch(42% .195 22 / .28));
  border-color: var(--red, oklch(42% .195 22));
  animation: tfs-shake 2.2s var(--tfs-ease) infinite, tfs-alert 2.4s var(--tfs-ease) infinite;
}
/* ícone de erro "pulsa" um anel vermelho chamando atenção */
@keyframes tfs-alert {
  0%   { box-shadow: 0 0 0 0   var(--red-gl, oklch(42% .195 22 / .28)); }
  70%  { box-shadow: 0 0 0 12px transparent; }
  100% { box-shadow: 0 0 0 0   transparent; }
}

/* buttons — mirror the platform's red primary + ghost surface buttons */
.tfs-btn {
  font-family: var(--tfs-fb); font-weight: 600; font-size: .9rem;
  padding: 11px 22px; border-radius: var(--r, 10px); border: 1px solid transparent;
  cursor: pointer; display: inline-flex; align-items: center; gap: 9px;
  transition: transform var(--t-fast,.15s) var(--tfs-ease), filter var(--t,.25s) var(--tfs-ease), background var(--t,.25s) var(--tfs-ease);
}
.tfs-btn:active { transform: scale(.97); }
.tfs-btn--primary {
  background: var(--red, oklch(42% .195 22)); color: #fff;
  box-shadow: var(--sh-red, 0 4px 24px oklch(42% .195 22 / .28));
}
.tfs-btn--primary:hover { background: var(--red-h, oklch(36% .185 22)); transform: translateY(-1px); }
.tfs-btn--ghost {
  background: var(--surface, oklch(100% 0 0 / .042));
  border-color: var(--border, oklch(100% 0 0 / .09)); color: var(--text, oklch(88% .014 72));
}
.tfs-btn--ghost:hover { background: var(--surface-h, oklch(100% 0 0 / .082)); border-color: var(--border-h, oklch(100% 0 0 / .22)); }
.tfs-btn svg { width: 16px; height: 16px; }
.tfs-btn[data-spinning] { pointer-events: none; opacity: .8; }
.tfs-btn[data-spinning] svg { animation: tfs-spin .8s linear infinite; }
@keyframes tfs-spin { to { transform: rotate(360deg); } }

/* ============================================================================
   4 · TOAST  (visual language aligned with ebooks.html .toast: accent rail + icon)
   ============================================================================ */
.tfs-toast-host {
  position: fixed; z-index: 9999; top: 18px; right: 18px;
  display: flex; flex-direction: column; gap: 12px;
  width: min(380px, calc(100vw - 32px)); pointer-events: none;
}
@media (max-width: 560px) { .tfs-toast-host { top: auto; bottom: 16px; right: 16px; left: 16px; width: auto; } }

.tfs-toast {
  pointer-events: auto; position: relative;
  display: grid; grid-template-columns: auto 1fr auto; gap: 13px; align-items: start;
  padding: 15px 16px; border-radius: 12px;
  background: var(--bg3, oklch(14.5% .03 248));
  border: 1px solid var(--border-h, oklch(100% 0 0 / .22));
  box-shadow: var(--sh-lg, 0 10px 48px rgba(0,0,0,.5));
  color: var(--text, oklch(88% .014 72)); overflow: hidden;
  transform: translateX(120%); opacity: 0;
  animation: tfs-toast-in .5s var(--tfs-ease) forwards;
}
@media (max-width: 560px) { .tfs-toast { transform: translateY(120%); animation-name: tfs-toast-in-m; } }
.tfs-toast.tfs-toast--out { animation: tfs-toast-out .35s var(--tfs-ease) forwards; }
@keyframes tfs-toast-in   { to { transform: translateX(0); opacity: 1; } }
@keyframes tfs-toast-in-m { to { transform: translateY(0); opacity: 1; } }
@keyframes tfs-toast-out  { to { transform: translateX(120%); opacity: 0; } }

.tfs-toast::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--_accent, var(--text2)); }
.tfs-toast--success { --_accent: var(--green, oklch(57% .17 145)); }
.tfs-toast--error   { --_accent: var(--red,   oklch(42% .195 22)); }
.tfs-toast--warning { --_accent: #f59e0b; }
.tfs-toast--info    { --_accent: #3b82f6; }

.tfs-toast__icon {
  width: 34px; height: 34px; display: grid; place-items: center; border-radius: 9px;
  color: var(--_accent); background: color-mix(in oklch, var(--_accent) 18%, transparent);
  animation: tfs-pop .5s var(--tfs-ease) .12s both;
}
.tfs-toast__icon svg { width: 18px; height: 18px; }
.tfs-toast__icon.tfs-emoji { font-size: 19px; line-height: 1; }
/* ícone do toast "estoura" pra dentro quando o aviso entra */
@keyframes tfs-pop { 0%{ transform: scale(.3); opacity: 0; } 60%{ transform: scale(1.15); } 100%{ transform: scale(1); opacity: 1; } }
.tfs-toast__body  { min-width: 0; }
.tfs-toast__title { font-family: var(--tfs-fb); font-weight: 700; font-size: .9rem; margin: 1px 0 2px; }
.tfs-toast__msg   { font-family: var(--tfs-fb); font-size: .85rem; line-height: 1.45; color: var(--text2, oklch(68% .011 72)); word-wrap: break-word; }
.tfs-toast__action{ margin-top: 8px; background: none; border: none; padding: 0; font-family: var(--tfs-fb); font-weight: 700; font-size: .83rem; color: var(--_accent); cursor: pointer; }
.tfs-toast__action:hover { text-decoration: underline; }
.tfs-toast__close { background: none; border: none; cursor: pointer; color: var(--text3, oklch(48% .008 72)); padding: 2px; line-height: 0; transition: color var(--t,.25s) var(--tfs-ease); }
.tfs-toast__close:hover { color: var(--text, oklch(88% .014 72)); }
.tfs-toast__close svg { width: 16px; height: 16px; }
.tfs-toast__bar { position: absolute; left: 0; bottom: 0; height: 2px; width: 100%; background: var(--_accent); transform-origin: left; animation: tfs-toast-bar linear forwards; opacity: .7; }
@keyframes tfs-toast-bar { from { transform: scaleX(1); } to { transform: scaleX(0); } }

/* ============================================================================
   6 · EMOJI ANIMATOR  (anima emojis decorativos — admin)
   ============================================================================ */
/* sem will-change: em telas pequenas há dezenas de emojis; criar uma camada GPU
   por emoji pesaria no celular. transforms contínuos já são suaves sem isso. */
.tfs-emo { display: inline-block; transform-origin: center; }
.tfs-emo--float     { animation: tfs-float     3.4s var(--tfs-ease) infinite; }
.tfs-emo--bob       { animation: tfs-bob       3s   var(--tfs-ease) infinite; }
.tfs-emo--lift      { animation: tfs-lift      1.9s var(--tfs-ease) infinite; }
.tfs-emo--wiggle    { animation: tfs-wiggle    2.6s var(--tfs-ease) infinite; }
.tfs-emo--ring      { animation: tfs-ring      2.8s var(--tfs-ease) infinite; transform-origin: top center; }
.tfs-emo--celebrate { animation: tfs-celebrate 2.2s var(--tfs-ease) infinite; }
.tfs-emo--shake     { animation: tfs-shake     2.6s var(--tfs-ease) infinite; }
.tfs-emo--pulse     { animation: tfs-epulse    2.4s var(--tfs-ease) infinite; }
.tfs-emo--flip      { animation: tfs-flip      2.6s var(--tfs-ease) infinite; }
.tfs-emo--spin      { animation: tfs-spin      2.4s linear            infinite; }
@keyframes tfs-epulse { 0%,100%{ transform: scale(1); } 50%{ transform: scale(1.18); } }
@keyframes tfs-flip   { 0%,100%{ transform: rotateY(0); } 50%{ transform: rotateY(180deg); } }

/* ============================================================================
   5 · REDUCED MOTION  (PRODUCT: "não abusar de animações")
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  .tfs-sk::after, .tfs-state__icon, .tfs-toast__bar,
  .tfs-state__icon svg *, .tfs-toast__icon { animation: none !important; }
  .tfs-state__icon svg * { stroke-dashoffset: 0 !important; }
  .tfs-state, .tfs-toast, .tfs-skeleton-wrap { animation-duration: .001s; }
  .tfs-state:hover { transform: none; }
  .tfs-toast { transform: none; opacity: 1; }
  .tfs-emo { animation: none !important; }
}
