/*
 * cam4.xxx - hoja de estilos unica del port PHP (sin build, R-CSS-1..5).
 *
 * Sustituye a app/globals.css + tailwind.config.ts + las utilidades Tailwind y los componentes
 * shadcn/ui que usaban los TSX (button, badge, card, sheet, separator, alert, toast,
 * scroll-area, aspect-ratio). Los selectores son las clases BEM que emiten las plantillas de
 * php/templates y los nodos que crea public/assets/js/app.js (CONTRACTS.md, secciones E y F).
 *
 * Breakpoints Tailwind (R-CSS-2): sm 640px, md 768px, lg 1024px, xl 1280px, 2xl 1536px.
 * Equivalencias de utilidades (R-CSS-4): text-xs .75rem/1rem, text-sm .875rem/1.25rem,
 * text-base 1rem/1.5rem, text-lg 1.125rem/1.75rem, text-xl 1.25rem/1.75rem,
 * text-2xl 1.5rem/2rem, text-4xl 2.25rem/2.5rem, text-6xl 3.75rem/1;
 * rounded-md = calc(var(--radius) - 2px), rounded-lg = var(--radius).
 */

/* ------------------------------------------------------------------------------------------
 * 1. Tokens (R-CSS-1). Valores HSL copiados 1:1 de app/globals.css.
 * ---------------------------------------------------------------------------------------- */

:root {
  --foreground-rgb: 0, 0, 0;
  --background-start-rgb: 214, 219, 220;
  --background-end-rgb: 255, 255, 255;
}

@media (prefers-color-scheme: dark) {
  :root {
    --foreground-rgb: 255, 255, 255;
    --background-start-rgb: 0, 0, 0;
    --background-end-rgb: 0, 0, 0;
  }
}

:root {
  --background: 0 0% 100%;
  --foreground: 0 0% 0%;
  --card: 0 0% 100%;
  --card-foreground: 0 0% 0%;
  --popover: 0 0% 100%;
  --popover-foreground: 0 0% 0%;
  --primary: 14 97% 55%;
  --primary-foreground: 0 0% 98%;
  --secondary: 266 59% 34%;
  --secondary-foreground: 0 0% 98%;
  --muted: 0 0% 96.1%;
  --muted-foreground: 0 0% 50%;
  --accent: 189 100% 56%;
  --accent-foreground: 0 0% 9%;
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 0 0% 98%;
  --border: 0 0% 89.8%;
  --input: 0 0% 89.8%;
  --ring: 347 81% 59%;
  --radius: 0.5rem;

  /* Literal inline del aside de las paginas de listado (style backgroundColor, G-56). */
  --sidebar-bg: #C0C2C1;

  /* Altura real de la cabecera: barra h-12 (3rem) + nav py-1 (0.5rem) + enlaces h-9 (2.25rem)
     + border-b (1px); en md los enlaces son h-10 (2.5rem). En rem y no en px para que escale con
     la fuente raiz como el original (93px/97px solo con raiz de 16px; G-58, R-CSS-4, T-59). */
  --header-height: calc(3rem + 0.5rem + 2.25rem + 1px);

  /* Sombras de Tailwind. */
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);

  /* transition-colors / transition-all de Tailwind. */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

@media (min-width: 768px) {
  :root {
    --header-height: calc(3rem + 0.5rem + 2.5rem + 1px);
  }
}

/* Tema oscuro: definido pero nunca activo (darkMode: class, nadie anade .dark; S-05). */
.dark {
  --background: 230 14% 10%;
  --foreground: 0 0% 98%;
  --card: 230 14% 13%;
  --card-foreground: 0 0% 98%;
  --popover: 230 14% 13%;
  --popover-foreground: 0 0% 98%;
  --primary: 14 97% 55%;
  --primary-foreground: 0 0% 9%;
  --secondary: 266 59% 34%;
  --secondary-foreground: 0 0% 98%;
  --muted: 230 14% 16%;
  --muted-foreground: 0 0% 63.9%;
  --accent: 189 100% 56%;
  --accent-foreground: 0 0% 9%;
  --destructive: 0 62.8% 30.6%;
  --destructive-foreground: 0 0% 98%;
  --border: 230 14% 18%;
  --input: 230 14% 18%;
  --ring: 347 81% 59%;
}

/* ------------------------------------------------------------------------------------------
 * 2. Base: equivalente al preflight de Tailwind (@tailwind base) + capa base de globals.css.
 * ---------------------------------------------------------------------------------------- */

*,
::before,
::after {
  box-sizing: border-box;
  border-width: 0;
  border-style: solid;
  border-color: hsl(var(--border));
}

html {
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  tab-size: 4;
  font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  font-feature-settings: normal;
  font-variation-settings: normal;
  -webkit-tap-highlight-color: transparent;
}

/* body: bg-background text-foreground + inter.className (fuente Inter de Google Fonts, G-24). */
body {
  margin: 0;
  line-height: inherit;
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  background-color: hsl(var(--background));
  color: hsl(var(--foreground));
}

hr {
  height: 0;
  color: inherit;
  border-top-width: 1px;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}

a {
  color: inherit;
  text-decoration: inherit;
}

b,
strong {
  font-weight: bolder;
}

button,
input,
optgroup,
select,
textarea {
  font-family: inherit;
  font-feature-settings: inherit;
  font-variation-settings: inherit;
  font-size: 100%;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  color: inherit;
  margin: 0;
  padding: 0;
}

button,
select {
  text-transform: none;
}

button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
  -webkit-appearance: button;
  background-color: transparent;
  background-image: none;
}

button,
[role="button"] {
  cursor: pointer;
}

:disabled {
  cursor: default;
}

blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
  margin: 0;
}

ol,
ul,
menu {
  list-style: none;
  margin: 0;
  padding: 0;
}

img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block;
  vertical-align: middle;
}

img,
video {
  max-width: 100%;
  height: auto;
}

/* Estado [hidden] del contrato DOM: gana a cualquier display de clase (lightbox, velo,
   esqueletos del grid). */
[hidden] {
  display: none !important;
}

/* ------------------------------------------------------------------------------------------
 * 3. Utilidades sueltas que emiten las plantillas.
 * ---------------------------------------------------------------------------------------- */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

.text-muted {
  color: hsl(var(--muted-foreground));
}

.text-center {
  text-align: center;
}

.capitalize {
  text-transform: capitalize;
}

.py-4 {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

/* text-primary hover:underline (enlaces de la ficha del perfil). */
.link {
  color: hsl(var(--primary));
  text-underline-offset: auto;
}

.link:hover {
  text-decoration-line: underline;
}

/* Tailwind container + mx-auto px-4: anchos escalonados, no un max-width fijo (R-CSS-4). */
.container {
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
}

@media (min-width: 640px) {
  .container {
    max-width: 640px;
  }
}

@media (min-width: 768px) {
  .container {
    max-width: 768px;
  }
}

@media (min-width: 1024px) {
  .container {
    max-width: 1024px;
  }
}

@media (min-width: 1280px) {
  .container {
    max-width: 1280px;
  }
}

@media (min-width: 1536px) {
  .container {
    max-width: 1536px;
  }
}

/* md:hidden / hidden md:inline (textos del boton de registro). */
.show-md-up {
  display: none;
}

@media (min-width: 768px) {
  .hide-md-up {
    display: none;
  }

  .show-md-up {
    display: inline;
  }
}

/* Barra de scroll fina de la bio (globals.css). */
.scrollbar-thin::-webkit-scrollbar {
  width: 4px;
}

.scrollbar-thin::-webkit-scrollbar-track {
  background: transparent;
}

.scrollbar-thin::-webkit-scrollbar-thumb {
  background-color: hsl(var(--muted-foreground));
  border-radius: 2px;
}

.scrollbar-thin::-webkit-scrollbar-thumb:hover {
  background-color: hsl(var(--foreground));
}

/* Scroll del sidebar: barra oculta, visible al pasar el raton (globals.css). */
.sidebar-scroll::-webkit-scrollbar {
  width: 8px;
}

.sidebar-scroll::-webkit-scrollbar-track {
  background: transparent;
}

.sidebar-scroll::-webkit-scrollbar-thumb {
  background: transparent;
  border-radius: 4px;
}

.sidebar-scroll:hover::-webkit-scrollbar-thumb {
  background: #888;
}

.sidebar-scroll::-webkit-scrollbar-thumb:hover {
  background: #555;
}

.sidebar-scroll {
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}

.sidebar-scroll:hover {
  scrollbar-color: #888 transparent;
}

/* animate-spin / animate-pulse de Tailwind. */
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: 0.5;
  }
}

/* ------------------------------------------------------------------------------------------
 * 4. Componentes shadcn/ui (copiados de components/ui/*.tsx, T-34).
 * ---------------------------------------------------------------------------------------- */

/* Button (button.tsx): base + variant default + size default (h-10 px-4 py-2). */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  border-radius: calc(var(--radius) - 2px);
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  height: 2.5rem;
  padding: 0.5rem 1rem;
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: var(--ease);
  transition-duration: 150ms;
}

.btn:hover {
  background-color: hsl(var(--primary) / 0.9);
}

.btn:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));
}

.btn:disabled,
.btn[disabled] {
  pointer-events: none;
  opacity: 0.5;
}

/* variant="secondary" */
.btn--secondary {
  background-color: hsl(var(--secondary));
  color: hsl(var(--secondary-foreground));
}

.btn--secondary:hover {
  background-color: hsl(var(--secondary) / 0.8);
}

/* variant="outline" */
.btn--outline {
  border: 1px solid hsl(var(--input));
  background-color: hsl(var(--background));
  color: inherit;
}

.btn--outline:hover {
  background-color: hsl(var(--accent));
  color: hsl(var(--accent-foreground));
}

/* variant="ghost" */
.btn--ghost {
  background-color: transparent;
  color: inherit;
}

.btn--ghost:hover {
  background-color: hsl(var(--accent));
  color: hsl(var(--accent-foreground));
}

/* size="sm": h-9 rounded-md px-3 */
.btn--sm {
  height: 2.25rem;
  padding: 0 0.75rem;
}

/* size="lg": h-11 rounded-md px-8 */
.btn--lg {
  height: 2.75rem;
  padding: 0 2rem;
}

/* size="icon": h-10 w-10 */
.btn--icon {
  height: 2.5rem;
  width: 2.5rem;
  padding: 0;
}

/* Boton de registro de la cabecera: size="sm" + className="h-7 text-xs". */
.btn--xs {
  height: 1.75rem;
  padding: 0 0.75rem;
  font-size: 0.75rem;
  line-height: 1rem;
}

/* "More webcams": size="sm" + className="px-4 py-0 h-7 text-xs"; contenedor mt-4 mb-2. El mb-2
   colapsaba con el mt-8 del bloque SEO y nunca sumo espacio: en el pie flex no colapsaria, asi
   que no se traslada (R-CSS-6, R-CSS-7). */
.btn--load-more {
  height: 1.75rem;
  padding: 0 1rem;
  font-size: 0.75rem;
  line-height: 1rem;
  margin-top: 1rem;
  margin-bottom: 0;
}

.btn--block {
  width: 100%;
}

/* Badge (badge.tsx): border px-2.5 py-0.5 text-xs font-semibold rounded-full. */
.badge {
  display: inline-flex;
  align-items: center;
  border-radius: 9999px;
  border-width: 1px;
  padding: 0.125rem 0.625rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: var(--ease);
  transition-duration: 150ms;
}

.badge:focus {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));
}

/* variant="default" */
.badge--primary {
  border-color: transparent;
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

.badge--primary:hover {
  background-color: hsl(var(--primary) / 0.8);
}

/* variant="secondary" */
.badge--secondary {
  border-color: transparent;
  background-color: hsl(var(--secondary));
  color: hsl(var(--secondary-foreground));
}

.badge--secondary:hover {
  background-color: hsl(var(--secondary) / 0.8);
}

/* variant="outline": el original heredaba text-foreground (negro) sobre el degradado oscuro
   de la tarjeta; el port lo pinta blanco para que se lea (desviacion G-59). */
.badge--outline {
  color: #fff;
}

/* variant="secondary" + className="bg-black/60 hover:bg-black/80" (contador de la tarjeta). */
.badge--dark {
  border-color: transparent;
  background-color: rgba(0, 0, 0, 0.6);
  color: hsl(var(--secondary-foreground));
}

.badge--dark:hover {
  background-color: rgba(0, 0, 0, 0.8);
}

/* Badge de genero de la tarjeta: className="text-[10px] py-0 px-2 h-4 min-w-0 min-h-0". */
.badge--tiny {
  font-size: 10px;
  line-height: inherit;
  padding: 0 0.5rem;
  height: 1rem;
  min-width: 0;
  min-height: 0;
}

/* Badges de idioma del perfil: className="text-xs py-0 h-4". */
.badge--h4 {
  padding-top: 0;
  padding-bottom: 0;
  height: 1rem;
}

/* Badge de genero enlazado: hover:opacity-80 cursor-pointer. */
.badge--link {
  cursor: pointer;
}

.badge--link:hover {
  opacity: 0.8;
}

/* Card (card.tsx): rounded-lg border bg-card text-card-foreground shadow-sm.
   CardContent: p-6 pt-0, que los TSX sustituian por p-4 (fichas) o p-6 (fotos, relacionados). */
.card {
  border-radius: var(--radius);
  border-width: 1px;
  background-color: hsl(var(--card));
  color: hsl(var(--card-foreground));
  box-shadow: var(--shadow-sm);
}

.card__content {
  padding: 1rem;
}

.card__content--lg {
  padding: 1.5rem;
}

/* "Broadcast History": text-sm font-semibold mb-2. */
.card__title {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

/* "Photos" / "Related Sex Cams": text-xl font-semibold mb-4. */
.card__title--lg {
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 600;
  margin-bottom: 1rem;
}

/* Alert variant="destructive" className="my-4" (alert.tsx), creado por app.js cuando falla la
   carga inicial del grid. El texto va en AlertDescription (text-sm). */
.alert {
  position: relative;
  width: 100%;
  border-radius: var(--radius);
  border-width: 1px;
  border-color: hsl(var(--destructive) / 0.5);
  padding: 1rem;
  margin-top: 1rem;
  margin-bottom: 1rem;
  color: hsl(var(--destructive));
  font-size: 0.875rem;
  line-height: 1.25rem;
}

.alert > svg {
  position: absolute;
  left: 1rem;
  top: 1rem;
  width: 1rem;
  height: 1rem;
  color: hsl(var(--destructive));
}

.alert > svg ~ * {
  padding-left: 1.75rem;
}

.alert > svg + div {
  transform: translateY(-3px);
}

/* Toast (toast.tsx + toaster.tsx). La region equivale a ToastViewport; cada .toast reune el
   Root y su div.grid.gap-1 interior (titulo + descripcion). */
.toast-region {
  position: fixed;
  top: 0;
  z-index: 100;
  display: flex;
  max-height: 100vh;
  width: 100%;
  flex-direction: column-reverse;
  padding: 1rem;
  pointer-events: none;
}

@media (min-width: 640px) {
  .toast-region {
    bottom: 0;
    right: 0;
    top: auto;
    flex-direction: column;
  }
}

@media (min-width: 768px) {
  .toast-region {
    max-width: 420px;
  }
}

@keyframes toast-in-top {
  from {
    transform: translateY(-100%);
  }
}

@keyframes toast-in-bottom {
  from {
    transform: translateY(100%);
  }
}

.toast {
  pointer-events: auto;
  position: relative;
  display: grid;
  gap: 0.25rem;
  width: 100%;
  overflow: hidden;
  border-radius: calc(var(--radius) - 2px);
  border-width: 1px;
  padding: 1.5rem 2rem 1.5rem 1.5rem;
  box-shadow: var(--shadow-lg);
  background-color: hsl(var(--background));
  color: hsl(var(--foreground));
  transition: all 150ms var(--ease);
  animation: toast-in-top 150ms ease;
}

@media (min-width: 640px) {
  .toast {
    animation-name: toast-in-bottom;
  }
}

.toast--destructive {
  border-color: hsl(var(--destructive));
  background-color: hsl(var(--destructive));
  color: hsl(var(--destructive-foreground));
}

.toast__title {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
}

.toast__desc {
  font-size: 0.875rem;
  line-height: 1.25rem;
  opacity: 0.9;
}

/* LoadingSpinner (loading-spinner.tsx): flex justify-center items-center h-64 con un anillo
   h-16 w-16 border-4 border-muted-foreground/25 y un arco border-t-primary animate-spin. */
.spinner {
  position: relative;
  width: 4rem;
  height: 4rem;
  margin: 6rem auto;
}

.spinner__ring,
.spinner__arc {
  width: 4rem;
  height: 4rem;
  border-radius: 9999px;
  border-width: 4px;
}

.spinner__ring {
  border-color: hsl(var(--muted-foreground) / 0.25);
}

.spinner__arc {
  position: absolute;
  top: 0;
  left: 0;
  border-top-color: hsl(var(--primary));
  animation: spin 1s linear infinite;
}

/* Spinner del boton mientras carga: animate-spin rounded-full h-3 w-3 border-b-2
   border-current mr-2 (lo crea app.js). */
.spinner--inline {
  display: inline-block;
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 9999px;
  border-bottom: 2px solid currentColor;
  margin-right: 0.5rem;
  animation: spin 1s linear infinite;
}

/* ------------------------------------------------------------------------------------------
 * 5. Layout (app/layout.tsx).
 * ---------------------------------------------------------------------------------------- */

/* div.flex.min-h-screen.flex-col */
.site-shell {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}

/* main.flex-1 */
.site-main {
  flex: 1 1 0%;
}

/* Enlace de salto (no existia en el original; lo exige el contrato E): oculto hasta el foco. */
.skip-link {
  position: absolute;
  left: 1rem;
  top: -100px;
  z-index: 10000;
  padding: 0.5rem 1rem;
  border-radius: calc(var(--radius) - 2px);
  background-color: hsl(var(--background));
  color: hsl(var(--foreground));
  box-shadow: var(--shadow-lg);
  font-size: 0.875rem;
  line-height: 1.25rem;
}

.skip-link:focus {
  top: 1rem;
}

/* ------------------------------------------------------------------------------------------
 * 6. Cabecera (site-header.tsx, header-scroll-wrapper.tsx, header-nav-buttons.tsx).
 * ---------------------------------------------------------------------------------------- */

/* sticky top-0 z-50 w-full transition-all duration-200 bg-white text-black;
   scrolled && shadow-sm (app.js anade is-scrolled cuando scrollY > 20). */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  width: 100%;
  background-color: #fff;
  color: #000;
  transition: all 200ms var(--ease);
}

.site-header.is-scrolled {
  box-shadow: var(--shadow-sm);
}

.dark .site-header {
  background-color: hsl(230, 14%, 10%);
  color: #fff;
}

/* w-full px-4 flex h-12 items-center justify-between */
.site-header__bar {
  display: flex;
  width: 100%;
  height: 3rem;
  align-items: center;
  justify-content: space-between;
  padding: 0 1rem;
}

.site-header__logo {
  display: flex;
  align-items: center;
}

/* img h-8 w-auto */
.site-header__logo img {
  height: 2rem;
  width: auto;
}

/* nav border-b border-gray-200 > div.w-full.px-4.py-1: el padding va fuera del contenedor con
   scroll, que asi recorta en el margen de 16 px (R-CSS-7). */
.site-nav {
  border-bottom: 1px solid #e5e7eb;
  padding: 0.25rem 1rem;
}

.dark .site-nav {
  border-bottom-color: #374151;
}

/* flex items-center space-x-1 overflow-x-auto scrollbar-hide */
.site-nav__list {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  width: 100%;
  overflow-x: auto;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.site-nav__list::-webkit-scrollbar {
  display: none;
}

/* Button size="sm" variant ghost/default + className="font-medium whitespace-nowrap h-9
   md:h-10 px-3 md:px-4 text-sm md:text-base hover:bg-black hover:text-white". */
.site-nav__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  border-radius: calc(var(--radius) - 2px);
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  height: 2.25rem;
  padding: 0 0.75rem;
  background-color: transparent;
  color: inherit;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: var(--ease);
  transition-duration: 150ms;
}

.site-nav__link.is-active {
  background-color: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

.site-nav__link:hover,
.site-nav__link.is-active:hover {
  background-color: #000;
  color: #fff;
}

.site-nav__link:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring));
}

@media (min-width: 768px) {
  .site-nav__link {
    height: 2.5rem;
    padding: 0 1rem;
    font-size: 1rem;
    line-height: 1.5rem;
  }
}

/* ------------------------------------------------------------------------------------------
 * 7. Pie (site-footer.tsx).
 * ---------------------------------------------------------------------------------------- */

/* border-t border-border bg-background > container mx-auto px-4 py-8 */
.site-footer {
  border-top-width: 1px;
  border-color: hsl(var(--border));
  background-color: hsl(var(--background));
}

.site-footer .container {
  padding-top: 2rem;
  padding-bottom: 2rem;
}

/* grid grid-cols-1 md:grid-cols-3 gap-8 */
.site-footer__grid {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  gap: 2rem;
}

@media (min-width: 768px) {
  .site-footer__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* space-y-4 */
.site-footer__col > * + * {
  margin-top: 1rem;
}

/* text-sm font-semibold */
.site-footer__heading {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
}

/* space-y-2 text-sm */
.site-footer__list {
  font-size: 0.875rem;
  line-height: 1.25rem;
}

.site-footer__list > li + li {
  margin-top: 0.5rem;
}

/* text-muted-foreground hover:text-foreground transition-colors */
.site-footer__list a {
  color: hsl(var(--muted-foreground));
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: var(--ease);
  transition-duration: 150ms;
}

.site-footer__list a:hover {
  color: hsl(var(--foreground));
}

/* Link flex items-center > Image h-6 w-auto */
.site-footer__logo {
  display: flex;
  align-items: center;
}

.site-footer__logo img {
  height: 1.5rem;
  width: auto;
}

/* text-sm text-muted-foreground; el enlace al sitemap: hover:text-foreground transition-colors */
.site-footer__muted {
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: hsl(var(--muted-foreground));
}

.site-footer__muted a {
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: var(--ease);
  transition-duration: 150ms;
}

.site-footer__muted a:hover {
  color: hsl(var(--foreground));
}

/* ------------------------------------------------------------------------------------------
 * 8. Paginas de listado (app/page.tsx y paginas de genero/filtro).
 * ---------------------------------------------------------------------------------------- */

/* w-full px-0 pb-2 */
.listing {
  width: 100%;
  padding-bottom: 0.5rem;
}

/* max-w-[1800px] mx-auto > flex flex-col md:flex-row gap-1 */
.listing__inner {
  max-width: 1800px;
  margin-left: auto;
  margin-right: auto;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

/* w-full md:flex-1 */
.listing__content {
  width: 100%;
}

@media (min-width: 768px) {
  .listing__inner {
    flex-direction: row;
  }

  .listing__content {
    flex: 1 1 0%;
  }
}

/* Contenido SEO: mt-8 px-2 > .prose */
.seo-content {
  margin-top: 2rem;
  padding: 0 0.5rem;
}

/* .prose sin @tailwindcss/typography no aplicaba nada (G-65, T-33): texto base 1rem/1.5 y
   las clases que cada elemento llevaba en los TSX. */
.prose {
  font-size: 1rem;
  line-height: 1.5;
}

/* h2/h3: text-lg font-semibold mb-3 */
.prose h2,
.prose h3 {
  font-size: 1.125rem;
  line-height: 1.75rem;
  font-weight: 600;
  margin-bottom: 0.75rem;
}

/* h2 de genero y filtro: text-xl font-bold mb-4 */
.prose .prose__lead {
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 700;
  margin-bottom: 1rem;
}

/* p: mb-4 */
.prose p {
  margin-bottom: 1rem;
}

/* p sin clase en el original */
.prose .prose__tight {
  margin-bottom: 0;
}

/* ul: list-disc list-inside mb-4 space-y-1 */
.prose ul {
  list-style: disc inside;
  margin-bottom: 1rem;
}

.prose ul > li + li {
  margin-top: 0.25rem;
}

/* ------------------------------------------------------------------------------------------
 * 9. Sidebar de filtros (filter-sidebar.tsx + aside de las paginas + Sheet de sheet.tsx).
 *    Un unico DOM (G-09): cajon lateral en movil (G-12, G-66), columna fija en escritorio.
 * ---------------------------------------------------------------------------------------- */

/* Movil: SheetContent side="left" (fixed z-50 inset-y-0 left-0 h-full border-r bg-background
   p-6 shadow-lg) con className="w-full max-w-xs" (y sm:max-w-sm del variant). Cerrado =
   visibility:hidden (+ inert desde app.js, G-66); deslizamiento ease-in-out 300ms al cerrar y
   500ms al abrir en lugar de tailwindcss-animate (G-12). El selector base no declara transition:
   solo la hay con is-animating, que app.js pone justo antes de abrir o cerrar y quita al acabar;
   asi cruzar los 768px no desliza el cajon cerrado por encima de la pagina (R-CSS-3, T-58). */
.filter-drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 51;
  height: 100%;
  width: 100%;
  max-width: 20rem;
  padding: 1.5rem;
  border-right-width: 1px;
  background-color: hsl(var(--background));
  box-shadow: var(--shadow-lg);
  transform: translateX(-100%);
  visibility: hidden;
}

.filter-drawer.is-open {
  transform: translateX(0);
  visibility: visible;
}

/* Cierre animado (300ms, visibility se oculta al terminar) y apertura animada (500ms). */
.filter-drawer.is-animating {
  transition: transform 300ms ease-in-out, visibility 0s linear 300ms;
}

.filter-drawer.is-animating.is-open {
  transition: transform 500ms ease-in-out, visibility 0s linear 0s;
}

@media (min-width: 640px) {
  .filter-drawer {
    max-width: 24rem;
  }
}

/* Cierre del Sheet: absolute right-4 top-4 rounded-sm opacity-70 hover:opacity-100, X h-4 w-4. */
.filter-drawer__head .btn {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: auto;
  height: auto;
  padding: 0;
  border-radius: calc(var(--radius) - 4px);
  background-color: transparent;
  color: inherit;
  opacity: 0.7;
  transition: opacity 150ms var(--ease);
}

.filter-drawer__head .btn:hover {
  background-color: transparent;
  color: inherit;
  opacity: 1;
}

.filter-drawer__head .btn .lucide {
  width: 1rem;
  height: 1rem;
}

/* SheetOverlay: fixed inset-0 z-50 bg-black/80 */
.filter-drawer__overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  background-color: rgba(0, 0, 0, 0.8);
}

/* ScrollArea className="h-[calc(100vh-80px)] mt-4" > div.pr-4 */
.filter-drawer .filter-sidebar {
  margin-top: 1rem;
  height: calc(100vh - 80px);
  overflow-y: auto;
  padding-right: 1rem;
}

/* Boton flotante: md:hidden fixed right-4 z-[9999], bottom calc(24px + safe-area), isolation
   isolate; Button size="icon" + h-[68px] w-[68px] rounded-full shadow-lg hover:shadow-xl
   transition-shadow touch-manipulation, transform translateZ(0); icono h-7 w-7. */
.filter-fab {
  position: fixed;
  right: 1rem;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  z-index: 9999;
  isolation: isolate;
  width: 68px;
  height: 68px;
  padding: 0;
  border-radius: 9999px;
  box-shadow: var(--shadow-lg);
  transition-property: box-shadow;
  transition-timing-function: var(--ease);
  transition-duration: 150ms;
  touch-action: manipulation;
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
}

.filter-fab:hover {
  box-shadow: var(--shadow-xl);
}

.filter-fab .lucide {
  width: 1.75rem;
  height: 1.75rem;
}

/* Secciones: div > div.py-4 > (titulo + lista) + Separator. */
.filter-section__title {
  padding-top: 1rem;
  margin-bottom: 0.75rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #4b5563;
}

/* space-y-2; enlaces block text-sm text-gray-800 hover:text-primary transition-colors */
.filter-section__list {
  padding-bottom: 1rem;
}

.filter-section__list > li + li {
  margin-top: 0.5rem;
}

.filter-section__list a {
  display: block;
  font-size: 0.875rem;
  line-height: 1.25rem;
  color: #1f2937;
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: var(--ease);
  transition-duration: 150ms;
}

.filter-section__list a:hover {
  color: hsl(var(--primary));
}

/* Separator className="bg-gray-400/50": shrink-0 h-[1px] w-full */
.filter-section__separator {
  flex-shrink: 0;
  height: 1px;
  width: 100%;
  background-color: rgb(156 163 175 / 0.5);
}

/* Escritorio: aside hidden md:block w-[180px] flex-shrink-0 self-start sticky overflow-hidden
   con fondo #C0C2C1; pegado bajo la cabecera real (top/alto con --header-height, G-58). */
@media (min-width: 768px) {
  .filter-drawer {
    position: sticky;
    top: var(--header-height);
    bottom: auto;
    left: auto;
    z-index: auto;
    flex-shrink: 0;
    align-self: flex-start;
    width: 180px;
    max-width: none;
    height: calc(100vh - var(--header-height));
    overflow: hidden;
    padding: 0;
    border-right-width: 0;
    background-color: var(--sidebar-bg);
    box-shadow: none;
    transform: none;
    visibility: visible;
    transition: none;
  }

  .filter-drawer.is-open {
    transform: none;
    transition: none;
  }

  /* En escritorio el cajon es una columna estatica: is-animating no anima nada (R-CSS-3). */
  .filter-drawer.is-animating,
  .filter-drawer.is-animating.is-open {
    transition: none;
  }

  .filter-drawer__head,
  .filter-drawer__overlay,
  .filter-fab {
    display: none !important;
  }

  /* div.sidebar-scroll.h-full.overflow-y-auto.px-3 */
  .filter-drawer .filter-sidebar {
    margin-top: 0;
    height: 100%;
    overflow-y: auto;
    padding: 0 0.75rem;
  }
}

/* ------------------------------------------------------------------------------------------
 * 10. Encabezado de pagina (page-header.tsx). PageHeader className="px-2 mb-2" + space-y-0.5.
 * ---------------------------------------------------------------------------------------- */

.page-header {
  padding: 0 0.5rem;
  margin-bottom: 0.5rem;
}

.page-header > * + * {
  margin-top: 0.125rem;
}

/* text-xl font-bold tracking-tight */
.page-header__title {
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.025em;
}

/* input.peer.hidden */
.page-header__toggle {
  display: none;
}

/* label.block.md:hidden.cursor-pointer */
.page-header__label {
  display: block;
  cursor: pointer;
}

/* transition-all duration-200 line-clamp-2 (T-15: line-clamp necesita display:-webkit-box). */
.page-header__text {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  transition: all 200ms var(--ease);
}

/* peer-checked:line-clamp-none */
.page-header__toggle:checked + .page-header__label .page-header__text {
  overflow: visible;
  display: block;
  -webkit-box-orient: horizontal;
  -webkit-line-clamp: none;
}

/* >= 768px: descripcion siempre completa, sin interaccion. */
@media (min-width: 768px) {
  .page-header__label {
    cursor: auto;
  }

  .page-header__text {
    overflow: visible;
    display: block;
    -webkit-box-orient: horizontal;
    -webkit-line-clamp: none;
  }
}

/* ------------------------------------------------------------------------------------------
 * 11. Grid de modelos (server-cam-grid.tsx, client-cam-grid.tsx).
 *     grid grid-cols-2 sm:grid-cols-3 md:grid-cols-3 lg:grid-cols-5 xl:grid-cols-6 gap-1
 * ---------------------------------------------------------------------------------------- */

.cam-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.25rem;
}

@media (min-width: 640px) {
  .cam-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .cam-grid {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

@media (min-width: 1280px) {
  .cam-grid {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}

/* Loader del scroll infinito: el mismo grid con mt-1. Va detras del centinela (orden grid,
   centinela, esqueletos, pie), asi que en modo infinito empieza 16 + 4 px bajo la ultima tarjeta;
   ningun selector depende del orden de esos hermanos (R-CSS-6). */
.cam-grid__loader {
  margin-top: 0.25rem;
}

/* aspect-[4/3] bg-muted animate-pulse rounded */
.cam-grid__skeleton {
  aspect-ratio: 4 / 3;
  background-color: hsl(var(--muted));
  border-radius: 0.25rem;
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Contenedor del boton: flex justify-center (el mt-4 va en .btn--load-more; el mb-2 no se
   traslada, R-CSS-6). */
.cam-grid__footer {
  display: flex;
  justify-content: center;
}

/* Alerta de error (my-4) dentro del pie flex: 16 px arriba; el margen inferior colapsaba con el
   mt-8 del bloque SEO, asi que aqui no suma (R-CSS-6, R-CSS-7). */
.cam-grid__footer .alert {
  margin-bottom: 0;
}

/* Modo infinito (InfiniteScroll className="pb-4"): app.js marca la raiz con is-infinite
   (R-CSS-6, contrato E). */
.cam-grid-wrapper.is-infinite {
  padding-bottom: 1rem;
}

/* "No more performers to show": text-center text-muted-foreground py-4 text-xs */
.cam-grid__end {
  width: 100%;
  text-align: center;
  color: hsl(var(--muted-foreground));
  padding: 1rem 0;
  font-size: 0.75rem;
  line-height: 1rem;
}

/* Disparador del IntersectionObserver: h-4 w-full, que el original solo montaba en modo
   infinito con paginas pendientes: fuera de ese modo mide 0 y app.js le pone hidden cuando no
   quedan paginas (R-CSS-6, R-CSS-7). */
.cam-grid__sentinel {
  height: 0;
  width: 100%;
}

.cam-grid-wrapper.is-infinite .cam-grid__sentinel {
  height: 1rem;
}

/* Relacionados del perfil: grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-2 */
.cam-grid.cam-grid--related {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
}

@media (min-width: 640px) {
  .cam-grid.cam-grid--related {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 768px) {
  .cam-grid.cam-grid--related {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ------------------------------------------------------------------------------------------
 * 12. Tarjeta de modelo (cam-card.tsx + .cam-card de globals.css).
 * ---------------------------------------------------------------------------------------- */

/* div.cam-card.h-full.border-0.block (el <a> y el div se colapsan en uno). */
.cam-card {
  display: block;
  height: 100%;
  border-width: 0;
  transition: transform 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.cam-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

/* relative bg-muted overflow-hidden > AspectRatio 4/3 */
.cam-card__media {
  position: relative;
  overflow: hidden;
  background-color: hsl(var(--muted));
  aspect-ratio: 4 / 3;
}

/* next/image fill + object-cover */
.cam-card__media > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

/* div.absolute.top-0.5.right-0.5: envoltorio de bloque que solo posiciona. Su caja de linea
   (1rem / 1.5, 24px con raiz de 16px, lo que heredaba el div original; se fija para no heredar
   otra cosa de la tarjeta, en rem para que escale con la raiz) es la que sostiene la insignia en
   su linea base (R-HTML-6, R-CSS-7, T-55, R-CSS-4, T-59). */
.cam-card__viewers {
  position: absolute;
  top: 0.125rem;
  right: 0.125rem;
  display: block;
  font-size: 1rem;
  line-height: 1.5;
}

/* Badge py-0 px-1 text-[10px] h-4 min-w-0 min-h-0: tailwind-merge descarta text-xs y con el su
   line-height, que se hereda del envoltorio (R-HTML-6, R-CSS-7). */
.cam-card__viewers .badge {
  padding: 0 0.25rem;
  font-size: 10px;
  line-height: inherit;
  height: 1rem;
  min-width: 0;
  min-height: 0;
}

/* EyeIcon h-2.5 w-2.5 mr-0.5 */
.cam-card__viewers .lucide {
  width: 0.625rem;
  height: 0.625rem;
  margin-right: 0.125rem;
}

/* absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-2 text-white */
.cam-card__overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 0.5rem;
  color: #fff;
  background-image: linear-gradient(to top, rgb(0 0 0 / 0.8), rgb(0 0 0 / 0));
}

/* flex items-center justify-between w-full (primera fila: mb-1) */
.cam-card__row {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
}

.cam-card__row:not(.cam-card__meta) {
  margin-bottom: 0.25rem;
}

/* font-medium text-sm text-white truncate */
.cam-card__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
  color: #fff;
}

/* text-xs text-white/90 */
.cam-card__meta {
  font-size: 0.75rem;
  line-height: 1rem;
  color: rgb(255 255 255 / 0.9);
}

/* flex items-center; MapPinIcon h-3 w-3 mr-1 */
.cam-card__country {
  display: flex;
  align-items: center;
}

.cam-card__country .lucide {
  width: 0.75rem;
  height: 0.75rem;
  margin-right: 0.25rem;
}

/* ------------------------------------------------------------------------------------------
 * 13. Perfil (app/[username]/page.tsx + client-profile-components.tsx).
 *     Un unico DOM (G-09): valores de la copia movil por defecto y de la copia de escritorio
 *     desde lg (1024px).
 * ---------------------------------------------------------------------------------------- */

/* container mx-auto px-4 py-8 */
.profile {
  padding-top: 2rem;
  padding-bottom: 2rem;
}

/* text-2xl lg:text-4xl font-bold mb-6 */
.profile__title {
  font-size: 1.5rem;
  line-height: 2rem;
  font-weight: 700;
  margin-bottom: 1.5rem;
}

/* Movil: bloques apilados. Escritorio: lg:grid lg:grid-cols-3 gap-8, video 2/3, ficha 1/3. */
.profile__grid {
  display: block;
}

/* relative aspect-video overflow-hidden mb-6 bg-black > iframe w-full h-full */
.profile__player {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  margin-bottom: 1.5rem;
  background-color: #000;
}

.profile__player iframe {
  width: 100%;
  height: 100%;
}

/* Movil: flex justify-center mb-8 > a.w-full.max-w-md > Button w-full text-lg py-6. */
.profile__chat {
  display: flex;
  justify-content: center;
  margin-bottom: 2rem;
}

.profile__chat .btn {
  max-width: 28rem;
  font-size: 1.125rem;
  line-height: 1.75rem;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}

/* MessageCircleIcon mr-2 h-5 w-5 */
.profile__chat .lucide {
  width: 1.25rem;
  height: 1.25rem;
  margin-right: 0.5rem;
}

/* Card mb-4 (movil) / mb-3 (escritorio) */
.profile__about {
  margin-bottom: 1rem;
}

/* flex justify-center mb-3 */
.profile__avatar-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 0.75rem;
}

/* w-20 h-20 (movil) / w-16 h-16 (escritorio) rounded-full overflow-hidden border-2
   border-primary > imagen object-cover */
.profile__avatar {
  width: 5rem;
  height: 5rem;
  max-width: none;
  border-radius: 9999px;
  border: 2px solid hsl(var(--primary));
  object-fit: cover;
  overflow: hidden;
}

/* text-lg font-semibold mb-2 text-center (en el original solo en escritorio, G-09). */
.profile__about-title {
  font-size: 1.125rem;
  line-height: 1.75rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
  text-align: center;
}

/* div.mb-4 > div text-muted-foreground text-sm (movil) / text-xs (escritorio)
   whitespace-pre-line max-h-12 overflow-hidden hover:overflow-y-auto hover:max-h-32
   transition-all duration-300, con line-height 1.3 y scrollbar thin (antes inline, R-CSS-5). */
.profile__bio {
  margin-bottom: 1rem;
  color: hsl(var(--muted-foreground));
  font-size: 0.875rem;
  line-height: 1.3;
  white-space: pre-line;
  max-height: 3rem;
  overflow: hidden;
  transition: all 300ms var(--ease);
  scrollbar-width: thin;
  scrollbar-color: hsl(var(--muted-foreground)) transparent;
}

.profile__bio:hover {
  overflow-y: auto;
  max-height: 8rem;
}

/* div.space-y-3 (movil) / space-y-2 (escritorio) con Separator entre filas; text-sm / text-xs.
   Fila: flex items-center justify-between; etiqueta text-muted-foreground. */
.profile__facts {
  font-size: 0.875rem;
  line-height: 1.25rem;
}

.profile__fact {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.profile__fact + .profile__fact {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid hsl(var(--border));
}

.profile__fact dt {
  color: hsl(var(--muted-foreground));
}

/* Celda del valor: en el original el valor era hijo directo de la fila flex items-center, sin
   caja de linea propia; dd flex centrado evita que la insignia cuelgue de su linea base
   (R-CSS-7). */
.profile__fact dd {
  display: flex;
  align-items: center;
}

/* Badges de la ficha: className="text-xs py-0 h-5" */
.profile__fact .badge {
  padding-top: 0;
  padding-bottom: 0;
  height: 1.25rem;
}

/* Genero enlazado: el Badge iba dentro de un <a> cuya caja de linea (16px/24px heredado) media
   24 px y del que colgaba por la linea base, abajo: se reproducen esos 4 px de mas (R-CSS-7). */
.profile__fact a.badge--link {
  margin-top: 0.25rem;
}

/* Idiomas: mt-4, titulo font-medium mb-2 text-sm (movil); mt-3, mb-1 text-xs (escritorio). */
.profile__languages {
  margin-top: 1rem;
}

.profile__languages-title {
  font-weight: 500;
  margin-bottom: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
}

/* flex flex-wrap gap-2 */
.profile__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Card mb-8 (movil); ultima tarjeta de la columna en escritorio. */
.profile__history {
  margin-bottom: 2rem;
}

/* Separator + "Most Active Days" (font-medium text-sm / text-xs) dentro del space-y. */
.profile__chart-title {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid hsl(var(--border));
  font-weight: 500;
  font-size: 0.875rem;
  line-height: 1.25rem;
}

/* grid grid-cols-7 gap-1 text-center */
.profile__chart {
  margin-top: 0.75rem;
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 0.25rem;
  text-align: center;
}

/* text-[10px] */
.profile__chart-day {
  font-size: 10px;
}

/* font-medium */
.profile__chart-label {
  display: block;
  font-weight: 500;
}

/* h-8 relative mt-1 bg-muted; sin actividad opacity-40 */
.profile__chart-bar {
  position: relative;
  height: 2rem;
  margin-top: 0.25rem;
  background-color: hsl(var(--muted));
  opacity: 1;
}

.profile__chart-bar.is-empty {
  opacity: 0.4;
}

/* absolute bottom-0 w-full bg-primary; la altura llega inline calculada en servidor (R-CSS-5). */
.profile__chart-fill {
  position: absolute;
  bottom: 0;
  width: 100%;
  background-color: hsl(var(--primary));
}

/* Fotos: Card mb-8 > grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4 */
.profile__photos {
  margin-bottom: 2rem;
}

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

@media (min-width: 640px) {
  .photo-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 768px) {
  .photo-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* relative aspect-square rounded-md overflow-hidden cursor-pointer */
.photo-grid__item {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: calc(var(--radius) - 2px);
  overflow: hidden;
  cursor: pointer;
}

/* fill object-cover hover:scale-105 transition-transform duration-200 */
.photo-grid__item img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  transition: transform 200ms var(--ease);
}

.photo-grid__item img:hover {
  transform: scale(1.05);
}

/* Lightbox: fixed inset-0 bg-black/80 flex items-center justify-center z-50 p-4 */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background-color: rgba(0, 0, 0, 0.8);
}

/* relative max-w-4xl max-h-[90vh] w-full h-full flex items-center justify-center */
.lightbox__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  max-width: 56rem;
  max-height: 90vh;
}

/* next/image fill + object-contain */
.lightbox__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: contain;
}

/* Button size="icon" variant="secondary" className="absolute top-2 right-2"; X h-4 w-4 */
.lightbox__close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
}

.lightbox__close .lucide {
  width: 1rem;
  height: 1rem;
}

@media (min-width: 1024px) {
  .profile__title {
    font-size: 2.25rem;
    line-height: 2.5rem;
  }

  .profile__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2rem;
  }

  .profile__main {
    grid-column: span 2 / span 2;
  }

  .profile__side {
    grid-column: span 1 / span 1;
  }

  /* div.mb-6 > a.block > Button w-full */
  .profile__chat {
    display: block;
    margin-bottom: 1.5rem;
  }

  .profile__chat .btn {
    max-width: none;
  }

  .profile__about {
    margin-bottom: 0.75rem;
  }

  .profile__avatar {
    width: 4rem;
    height: 4rem;
  }

  .profile__bio {
    font-size: 0.75rem;
  }

  .profile__facts {
    font-size: 0.75rem;
    line-height: 1rem;
  }

  .profile__fact + .profile__fact {
    margin-top: 0.5rem;
    padding-top: 0.5rem;
  }

  .profile__languages {
    margin-top: 0.75rem;
  }

  .profile__languages-title {
    margin-bottom: 0.25rem;
    font-size: 0.75rem;
    line-height: 1rem;
  }

  .profile__history {
    margin-bottom: 0;
  }

  .profile__chart-title {
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    font-size: 0.75rem;
    line-height: 1rem;
  }

  .profile__chart {
    margin-top: 0.5rem;
  }
}

/* ------------------------------------------------------------------------------------------
 * 14. Paginas de error (app/not-found.tsx; la pagina 500 reutiliza el vocabulario, G-60).
 * ---------------------------------------------------------------------------------------- */

/* min-h-[60vh] flex items-center justify-center px-4 */
.not-found {
  min-height: 60vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 1rem;
}

/* text-center space-y-6 max-w-2xl */
.not-found__box {
  text-align: center;
  max-width: 42rem;
}

.not-found__box > * + * {
  margin-top: 1.5rem;
}

/* space-y-2 */
.not-found__head > * + * {
  margin-top: 0.5rem;
}

/* text-6xl font-bold text-muted-foreground */
.not-found__code {
  font-size: 3.75rem;
  line-height: 1;
  font-weight: 700;
  color: hsl(var(--muted-foreground));
}

/* text-2xl font-semibold */
.not-found__title {
  font-size: 1.5rem;
  line-height: 2rem;
  font-weight: 600;
}

/* flex flex-col sm:flex-row gap-3 justify-center items-center. El Button w-full sm:w-auto iba
   dentro de un <a> que encogia a su contenido, asi que el ancho efectivo era el del texto. */
.not-found__actions {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  justify-content: center;
  align-items: center;
}

@media (min-width: 640px) {
  .not-found__actions {
    flex-direction: row;
  }
}

/* Iconos mr-2 h-4 w-4 */
.not-found__actions .lucide {
  width: 1rem;
  height: 1rem;
  margin-right: 0.5rem;
}

/* pt-8; h3 text-sm font-semibold mb-4 */
.not-found__categories {
  padding-top: 2rem;
}

.not-found__categories h3 {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
  margin-bottom: 1rem;
}

/* flex flex-wrap gap-2 justify-center */
.not-found__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
}

/* pt-6 border-t border-border; p text-sm text-muted-foreground */
.not-found__note {
  padding-top: 1.5rem;
  border-top-width: 1px;
  border-color: hsl(var(--border));
}

.not-found__note p {
  font-size: 0.875rem;
  line-height: 1.25rem;
}
