/**
 * tekne/theme.css — Tekne tenant visual identity.
 *
 * Tokens cross-validated 2026-05-14 against two independent sources:
 *   1. Direct CSS export from the Login + Register Figma frames
 *      (`examples/ui_files/tekne/login.css`, `registrar.css`).
 *   2. Claude Design analysis over the full 42-frame `.fig` file
 *      (`examples/ui_files/tekne/design_system/ds/colors_and_type.css`).
 *
 * Where the two sources disagreed (e.g. primary navy `#050d47` Login-only
 * vs `#1E2978` system-wide; radii 36/40/33/29 Login-only vs 14/19/24/46/999
 * system-wide), the system-wide values from Claude Design WIN because:
 *   - It analyzed every frame; the Login frame turned out to be an
 *     outlier from designer sloppiness (no Figma Variables used, colors
 *     copied by hand).
 *   - Adopting 2 navies as `--primary` values would be inconsistency
 *     disguised as flexibility (anti-pattern in design systems).
 * Full rationale: see journal entry 2026-05-14 morning + TL-030 doc §2-bis.
 *
 * Consolidation policy (`feedback_css_token_consolidation.md`):
 *   - Single source of truth per token. NO duplication.
 *   - When a new section arrives, scan THIS file first. Reuse existing
 *     tokens if the value matches.
 *   - Only introduce a new token if the difference is SEMANTIC.
 *
 * Sections covered as of 2026-05-14:
 *   [x] Login screen — paleta + tipografía + radii (system-aligned).
 *   [x] Register screen — same token set, validated zero new tokens needed.
 *   [ ] Dark mode — pending Figma export.
 *   [ ] Dashboard, courses, watch, settings — pending.
 *   [ ] Hover/error/success states — partial (hover convention from ds README).
 *   [x] Shadows — captured from ds.
 *   [x] Typography scale — partial (display+h1..h4+body+meta+eyebrow).
 */

/* ─────────────────────────────────────────────────────────────
   Fonts — Ubuntu, self-hosted (Latin subset, woff2 only).
   Per `feedback_fonts_selfhost_default.md` — `font-display: swap`
   to avoid FOIT.

   Note: ds README also documents Inter Light used in two tactical
   places (email addresses on dark cards + giant stat numerals).
   When we hit those screens we'll self-host Inter the same way.
   ───────────────────────────────────────────────────────────── */

@font-face {
  font-family: "Ubuntu";
  src: url("/themes/tekne/fonts/Ubuntu-Light.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Ubuntu";
  src: url("/themes/tekne/fonts/Ubuntu-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Ubuntu";
  src: url("/themes/tekne/fonts/Ubuntu-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Ubuntu";
  src: url("/themes/tekne/fonts/Ubuntu-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Inter — self-hosted, Latin subset, woff2 only. Used in landing footer
   (nav links + contact info) per Figma Phase 8.8 footer spec. Two weights
   covers everything Inter is asked to render in our footer scope; we have
   intentionally NOT added more weights — keep the bundle small and avoid
   font sprawl. */
@font-face {
  font-family: "Inter";
  src: url("/themes/tekne/fonts/Inter-Light.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("/themes/tekne/fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ─────────────────────────────────────────────────────────────
   Light theme tokens (`:root`).
   ───────────────────────────────────────────────────────────── */

:root {
  /* ── Brand palette — corrected 2026-05-14 ── */
  --tk-primary: #1e2978; /* PRIMARY navy — most usage across site (was #050d47) */
  --tk-navy-deep: #060841; /* footer/heavy bg — distinct SEMANTIC role */
  --tk-navy-mid: #384cde; /* gradient mid-point */
  --tk-accent: #70ffe5; /* mint: CTAs, brand mark, check pills */

  /* 🔴 LA SELECCIÓN TIENE TOKENS PROPIOS, Y ESA ES TODA LA CORRECCIÓN.
     `::selection` pintaba `background: var(--tk-accent); color: var(--tk-primary)`.
     Funcionaba en el site, donde `--tk-primary` es navy. Pero `--tk-primary` es
     un token de ROL —«el color de la acción principal»— y dentro del cromo de
     gestión (`.tk-admin`, que visten TAMBIÉN las pantallas de alumno vía
     StudentLayoutShell) vale mint, el MISMO valor que `--tk-accent`. Resultado:
     menta sobre menta, texto invisible al seleccionarlo (reporte de José,
     22-09). Estos dos no los redefine ningún ámbito, así que la selección se
     ve igual en claro, oscuro, gestión y `.force-light`. */
  --tk-selection-bg: #70ffe5; /* mint */
  --tk-selection-fg: #1e2978; /* navy — el valor que la selección YA tenía en el site */
  --tk-accent-hover: #48deb1; /* mint darken on hover (per ds spec) */
  --tk-link-blue: #116af8; /* bright blue accent — body links, dividers */

  /* ── Surfaces ── */
  --tk-bg: #ffffff; /* page background (corrected from cream #fffefc) */
  --tk-bg-deep: var(--tk-primary); /* hero / dark sections */
  --tk-bg-footer: var(--tk-navy-deep);
  --tk-surface: #ffffff; /* input fields, cards */
  --tk-bg-muted: #f8f8f8; /* gris muy claro — bandas del site que necesitan
     separarse del blanco sin ser oscuras. Nace con «Formações pensadas…» de
     /courses (2026-08-27). NO se reusa --tk-surface (#ffffff): ahí el blanco
     es el de las TARJETAS, y esta banda existe justamente para que las
     tarjetas blancas se recorten contra ella. Igualarlos las borraría. */
  --tk-paper: #f5f7fa; /* subtle bg shift */
  --tk-grey-divider: #d9d9d9; /* banner placeholder mat */

  /* ── Text ── */
  --tk-text: var(--tk-primary); /* default text color — navy on light bg */
  --tk-text-strong: rgba(3, 1, 20, 0.95);
  --tk-text-body: rgba(3, 1, 20, 0.8);
  --tk-text-secondary: #5b5b5b;
  --tk-text-muted: #acacac; /* placeholders */
  --tk-text-on-primary: #ffffff; /* text on navy buttons */
  --tk-text-on-accent: var(--tk-primary); /* text on mint buttons */
  --tk-c-card-title: #2f327d; /* purplish navy — feature card titles (landing) */
  --tk-c-card-body: #696984; /* purplish grey — feature card body (landing) */
  --tk-c-course-card-overlay: rgba(
    30,
    41,
    120,
    0.86
  ); /* landing course carousel — navy 86% over photo (Phase 8.3) */
  --tk-overlay-photo-dim: rgba(
    0,
    0,
    0,
    0.2
  ); /* photo-dim layer (Figma stacks 2 of these for ~36% effective) */
  --tk-text-on-footer: #b2b3cf; /* lavender-grey — footer body text (nav links + contact info) per Figma Phase 8.8 */
  --tk-border-footer-input: #83839a; /* slate-blue — footer newsletter input border + placeholder (Phase 8.8) */
  --tk-bg-icon-pill: #cfd1f6; /* periwinkle — footer contact-icon ellipse bg (email/location chips) (Phase 8.8) */
  --tk-icon-on-light: #242545; /* deep navy — footer social/contact icon glyph on white/light bg (distinct from --tk-primary) (Phase 8.8) */
  --tk-bg-form-card: rgba(
    131,
    74,
    139,
    0.11
  ); /* purple-violet 11% — contact form card surface over navy bg (Phase 8.7 MODULO ENCERRAMENTO) */
  --tk-r-input-pill: 44px; /* pill input radius — landing contact form fields, Figma 44.22px (Phase 8.7) */

  /* ── Semantic UI tokens (NEW 2026-05-14, Phase 3.6) ── */
  --link-color: var(--tk-link-blue);
  --link-color-hover: var(--tk-primary);
  --text-on-light-bg: var(--tk-text);
  --button-primary-bg: var(--tk-primary);
  --button-primary-text: var(--tk-text-on-primary);
  --button-accent-bg: var(--tk-accent);
  --button-accent-text: var(--tk-text-on-accent);
  --input-border: rgba(30, 41, 120, 0.18);
  --input-border-focus: var(--tk-primary);
  --input-bg: var(--tk-surface);

  /* ── Borders ── */
  --tk-border-soft: rgba(30, 41, 120, 0.08);
  --tk-border-default: rgba(30, 41, 120, 0.18);
  --tk-border-strong: var(--tk-primary);
  /* Filete para tarjetas apoyadas SOBRE una banda oscura del site. Los
     `--tk-border-*` de arriba son navy translúcido —invisibles sobre navy— y
     los blancos sólo existen en el bloque del tema oscuro, que el site no usa
     porque va forzado en claro. De ahí que haga falta éste.
     ⚠️ El valor es una ESTIMACIÓN a partir del visual, no del export: el
     `Rectangle 265` de Figma trae `box-sizing` y radio pero perdió el color
     del trazo por el camino. Se afina en un número si hace falta. */
  --tk-border-on-dark: rgba(255, 255, 255, 0.3);

  /* ── Shadows (per ds README) ── */
  --tk-shadow-card: 0 14px 34px rgba(0, 0, 0, 0.1);
  --tk-shadow-card-hero: 20px 14px 34px rgba(0, 0, 0, 0.25);
  --tk-shadow-soft: 0 8px 18px rgba(38, 45, 118, 0.08);
  --tk-shadow-card-elevated: 0 8.47849px 50.871px rgba(38, 45, 118, 0.08); /* landing feature cards — Figma exact */
  --tk-shadow-testimonial: 0 4px 4px rgba(0, 0, 0, 0.25); /* landing testimonial cards — Figma Phase 8.6 (drop shadow) */
  --tk-shadow-ring: 0 0 0 4px rgba(112, 255, 229, 0.25);
  /* Flechas del carrusel de cursos: son un ARO HUECO sobre la foto del curso,
     así que su legibilidad depende de lo que haya justo detrás. Medido sobre
     los cuatro fondos (2026-08-28): siete de las ocho posiciones dan entre
     4,62:1 y 18,86:1, pero el lado derecho de `course-slide-analytics` tiene
     un resplandor cian y cae a 2,57:1 — por debajo del 3:1 que pide un icono.
     Esta sombra lo separa del fondo sin tocar la foto ni el diseño del aro, y
     sobre los fondos oscuros no se aprecia. ⛔ NO sustituir por un círculo
     relleno: el aro hueco es la pieza que vino de Figma. */
  --tk-shadow-carousel-arrow: 0 1px 8px rgba(0, 0, 0, 0.75);

  /* ── Radii — aligned to ds system (2026-05-14 correction) ──
     Note: --tk-r-button (semantic) overrides the ds-derived --tk-r-md (14px)
     for primary buttons after José's cross-screen Figma observation
     2026-05-14: 36px appears consistently across multiple frames, not just
     Login. Claude Design captured 14px as dominant but missed the auth +
     contact + form buttons that use 36px. Owner observation > automated
     extraction. --tk-r-md kept available for future legitimate medium-radius
     uses (chips, badges) not yet encountered. */
  --tk-r-xs: 6px;
  --tk-r-nav-button: 8px; /* marketing nav CTA — per landing navbar Figma (Phase 8) */
  --tk-r-sm: 12px; /* secondary buttons */
  --tk-r-md: 14px; /* ds-derived medium — reserved for future use */
  --tk-r-button: 36px; /* PRIMARY button radius — cross-screen Tekne signature */
  --tk-r-card-elevated: 16.957px; /* landing feature cards — Figma exact (Phase 8.2) */
  --tk-r-lg: 19px; /* feature cards, overlay panels, input fields */
  --tk-r-xl: 24px; /* dark blog/promo cards */
  --tk-r-2xl: 46px; /* huge form container */
  --tk-r-course-photo: 30px; /* caja de foto de §2 en la página de curso (30) */
  --tk-r-director-photo: 27px; /* caja del retrato de §7 (26.5482). No reusa
     `--tk-r-xl` (24): son casi 3px y las dos cajas conviven en la misma
     página, así que la diferencia se ve. */
  --tk-r-pill: 999px; /* social bubbles, segmented Login/Register */

  /* Platform contract mapping — these are consumed by globals.css `@theme inline`
     and by shared component code. Update here when Tekne semantic changes. */
  --background: var(--tk-bg);
  --surface: var(--tk-surface);
  --surface-secondary: var(--tk-paper);
  --foreground: var(--tk-text);
  --text-secondary: var(--tk-text-secondary);
  --muted-foreground: var(--tk-text-muted);
  --border: var(--input-border);
  --primary: var(--tk-primary);
  --primary-hover: var(--tk-primary); /* opacity hover convention — see below */
  --primary-active: var(--tk-primary);
  --secondary: var(--tk-navy-deep);
  --secondary-hover: var(--tk-navy-deep);
  --accent: var(--tk-accent);
  --accent-hover: var(--tk-accent-hover);
  --accent-soft: rgba(112, 255, 229, 0.11);
  --success: #2e7d32;
  --warning: #ed6c02;
  --error: #d32f2f;
  --info: #1d4ed8;

  --radius: var(--tk-r-button); /* default radius for tenant-Tekne pages */

  /* ── Spacing scale (per ds) ── */
  --tk-space-1: 4px;
  --tk-space-2: 8px;
  --tk-space-3: 12px;
  --tk-space-4: 16px;
  --tk-space-5: 24px;
  --tk-space-6: 32px;
  --tk-space-7: 48px;
  --tk-space-8: 64px;
  --tk-space-9: 96px;
  --tk-space-10: 128px;

  /* ── Typography ── */
  --font-sans: "Ubuntu", system-ui, -apple-system, sans-serif;
  --tk-font-display: "Ubuntu", system-ui, sans-serif;
  --tk-font-body: "Ubuntu", system-ui, sans-serif;

  /* Type ramp (per ds) */
  --tk-fs-display: 62px;
  --tk-fs-h1: 48px;
  --tk-fs-h2: 38px;
  --tk-fs-h3: 28px;
  --tk-fs-h4: 24px;
  --tk-fs-body-lg: 25px;
  --tk-fs-body: 18px;
  --tk-fs-body-sm: 16px;
  --tk-fs-nav: 22px; /* tekne marketing nav text (links + CTA) — Figma 2026-05-18 */
  --tk-fs-benefit-body: 22px; /* cuerpo de las tarjetas de banda oscura —
     Figma /companies §3, 2026-08-27. Vale lo mismo que `--tk-fs-nav` y NO lo
     reusa a propósito: aquél es el tamaño del texto del menú, y un cambio en
     la navegación no tiene por qué arrastrar el cuerpo de una tarjeta. Mismo
     número, roles distintos. */
  --tk-fs-section-headline: 48px; /* landing section H2 — Figma Phase 8.2 (Methodology, etc.) */
  --tk-fs-card-title: 27px; /* landing feature card title — Figma 27.3075px rounded */
  --tk-fs-course-title: 54px; /* landing course carousel hero title — Figma Phase 8.3 */
  --tk-fs-stat-number: 58px; /* landing stats section — Figma Phase 8.4 (57.6205 rounded) */
  --tk-fs-step-number: 51px; /* numeral «01…06» de las tarjetas de proceso —
     Figma /companies §4, 2026-08-27 (51.1731). No reusa `--tk-fs-stat-number`
     (58) ni `--tk-fs-course-title` (54): aquéllos son una cifra de resultado y
     un titular de carrusel, y ninguno de los dos se mueve por lo que le pase a
     un ordinal dentro de una tarjeta. */
  --tk-fs-stat-label: 29px; /* landing stats section label — Figma Phase 8.4 (28.8976 rounded) */
  --tk-fs-testimonial-body: 20px; /* landing testimonials quote body — Figma Phase 8.6 (Ubuntu 300 light, lh 23) */
  --tk-fs-banner-title: 73px; /* H1 del banner de sub-página — Figma 73.2 (Nossos Cursos, 2026-08-27).
     NO reusa --tk-fs-display (62px): son 11px de diferencia y roles distintos —
     aquél es el titular de la portada, éste el de una página con nombre. */
  /* ── Página de detalle de curso (Figma «Cursos interna», 2026-08-28) ──
     Es la primera página del site con una rampa propia, porque su banner NO es
     el de las sub-páginas: aquél mide 73 y éste 62. */
  --tk-fs-course-hero-title: 62px; /* H1 del banner del curso (Figma 62).
     Vale lo mismo que `--tk-fs-display` y NO lo reusa: aquél es el titular de
     la PORTADA, y un retoque de la portada no tiene por qué mover el de un
     curso. Tampoco es `--tk-fs-banner-title` (73), que es el de /courses y
     /companies — la página de curso trae su propio tamaño. */
  --tk-fs-course-hero-body: 32px; /* entradilla del banner (Figma 32/37) */
  --tk-fs-course-section-title: 58px; /* titular de sección interna: §2
     «Bootcamp em Introdução a Python» (58/61) y §5 «Porque estudar…»
     (57.6716). Los dos son titulares de sección de ESTA página, así que
     comparten token. No reusa `--tk-fs-stat-number` (58), que es una cifra de
     resultado de la portada. */
  --tk-fs-course-body: 28px; /* cuerpo largo de §2 y §7 (28/41, Ubuntu 300).
     No reusa `--tk-fs-h3`: aquél es un nivel de la rampa de titulares. */
  --tk-fs-course-reason-title: 36px; /* subtítulo de columna en §5 (35.8983) */
  --tk-fs-course-reason-body: 33px; /* cuerpo de columna en §5 (33.3213) */
  --tk-fs-course-cta: 22px; /* rótulo del botón «Começar Agora!» (22.0339) */
  --tk-fs-module-eyebrow: 27px; /* «MÓDULO 01» del carrusel de módulos (27.1733) */
  --tk-fs-module-title: 54px; /* titular del módulo (54). Vale lo mismo que
     `--tk-fs-course-title` y no lo reusa: aquél titula la TARJETA del carrusel
     de la portada. */
  --tk-fs-module-body: 22px; /* descripción del módulo (22/117%) */
  --tk-fs-module-track-title: 26px; /* «Trilha de Aprendizado» (26.4) */
  --tk-fs-module-track-item: 20px; /* puntos de la trilha (19.6182) */
  --tk-fs-director-title: 56px; /* §7: titular y nombre del director (55.7516) */
  --tk-fs-director-role: 40px; /* cargo bajo el nombre. ⚠️ El export da 55.7516
     para el bloque entero —nombre y cargo en una sola capa de texto—, pero la
     maqueta enseña el cargo claramente MENOR. Se separa y se fija aquí; si el
     diseño quería los dos al mismo tamaño, es este número el que cambia. */

  --tk-fs-meta: 14px;
  --tk-fs-eyebrow: 12px;

  --tk-lh-tight: 1;
  --tk-lh-snug: 1.17;
  --tk-lh-body: 1.6;
  --tk-lh-cap: 1.1;

  --tk-tracking-display: 0.02em;
  --tk-tracking-eyebrow: 0.08em;

  /* ── Gradients ── */
  /* Las DOS paradas del degradado de marca, en un solo sitio. Nacen separadas
     el 2026-08-27, al aparecer el mismo degradado con otro ángulo en la banda
     de «Por que capacitar seu time» de /companies: los colores coincidían al
     dígito y sólo cambiaba la dirección. Definir dos gradientes completos
     habría dejado #1e2978 y #384cde escritos dos veces cada uno. */
  --tk-c-grad-navy-from: #1e2978;
  --tk-c-grad-navy-to: #384cde;
  --tk-gradient-navy: linear-gradient(
    180deg,
    var(--tk-c-grad-navy-from) 0%,
    var(--tk-c-grad-navy-to) 100%
  ); /* vertical — hero de la portada */
  /* Navy → azul brillante. Tercer degradado de marca, y el único que no usa
     la menta: cierra la página de empresas con la llamada a contacto. Se
     compone con los dos tokens que ya tenían esos valores exactos —
     `--tk-c-grad-navy-from` (#1e2978) y `--tk-link-blue` (#116af8)—, así que
     no entra ni un literal. Figma /companies §5, 2026-08-27. */
  --tk-gradient-navy-bright: linear-gradient(
    101.67deg,
    var(--tk-c-grad-navy-from) 8.22%,
    var(--tk-link-blue) 99.15%
  );
  --tk-gradient-navy-wide: linear-gradient(
    95.01deg,
    var(--tk-c-grad-navy-from) 2.07%,
    var(--tk-c-grad-navy-to) 100%
  ); /* casi horizontal — bandas anchas. Figma /companies §3, 2026-08-27 */
  /* Velo de los banners con foto: oscurece la mitad izquierda para que el texto
     blanco se lea sobre la imagen, y se desvanece hacia la derecha para dejar
     ver el motivo. Figma «Nossos Cursos» 2026-08-27.
     📌 El origen decía #0B0541; se usa --tk-navy-deep (#060841), que es el mismo
     azul profundo con 5 puntos de diferencia por canal. Y la parada final lleva
     ese mismo color con alfa 0 —no `transparent`— porque interpolar hacia
     `transparent` pasa por negro transparente y ensucia el centro del degradado. */
  --tk-gradient-banner-veil: linear-gradient(
    91.25deg,
    var(--tk-navy-deep) 19.17%,
    rgba(6, 8, 65, 0) 89.36%
  );
  --tk-gradient-check: radial-gradient(
    circle at 30% 25%,
    #70ffe5 0%,
    #48deb1 70%,
    #2bb38b 100%
  );
  --tk-gradient-icon: linear-gradient(
    180deg,
    #1e2978 0%,
    #70ffe5 100%
  ); /* navy → mint — landing card icons (Phase 8.2) */
  /* El mismo recurso sobre el NUMERAL de las tarjetas de proceso. No reusa
     `--tk-gradient-icon` aunque se parezca: aquél identifica el círculo de
     `TekneFeatureCard` y hay una prueba que exige que aparezca en UN solo
     fichero — usarlo aquí lo vaciaba de sentido. Y separarlo sale además más
     fiel al origen, que arranca en #2F327D y no en #1E2978: se construye con
     los dos tokens que ya tenían esos valores, sin literales nuevos.
     Figma /companies §4, 2026-08-27. */
  --tk-gradient-numeral: linear-gradient(
    180deg,
    var(--tk-c-card-title) 0%,
    var(--tk-accent) 100%
  );
  /* Iconos de las tres píldoras de datos duros (§3 de la página de curso):
     azul de enlace → menta oscura. Es el ÚNICO degradado del site que no
     arranca en navy, y por eso no puede salir de ninguno de los anteriores.
     Se compone con los dos tokens que ya tenían esos valores exactos —
     `--tk-link-blue` (#116af8) y `--tk-accent-hover` (#48deb1)—, sin literales.
     Figma «Cursos interna» §3, 2026-08-28. */
  --tk-gradient-course-fact-icon: linear-gradient(
    180deg,
    var(--tk-link-blue) 0%,
    var(--tk-accent-hover) 100%
  );
  /* Marca de verificación de §5. Coincide al dígito con `--tk-gradient-icon`
     (navy → menta, 180°) y NO lo reusa: hay una prueba que exige que aquél
     aparezca en UN solo fichero, porque identifica el círculo de
     `TekneFeatureCard`. Reusarlo aquí lo vaciaría de sentido — es la misma
     razón por la que nació `--tk-gradient-numeral`. Figma §5, 2026-08-28. */
  --tk-gradient-course-check: linear-gradient(
    180deg,
    var(--tk-c-grad-navy-from) 0%,
    var(--tk-accent) 100%
  );
  /* Titular y nombre de §7, pintados SOBRE el texto (`background-clip: text`).
     Es el primer degradado del site que se usa como tinta y no como fondo.
     Figma §7, 2026-08-28. */
  --tk-gradient-director-text: linear-gradient(
    93.72deg,
    var(--tk-c-grad-navy-from) 19.38%,
    var(--tk-accent) 114.38%
  );
  /* Píldora «MÓDULO 01» del carrusel de módulos: blanco casi transparente con
     desenfoque por detrás. Figma §6, 2026-08-28. */
  --tk-c-module-eyebrow-bg: rgba(255, 255, 255, 0.08);
  /* Velo de las bandas con foto a sangre. Figma apila DOS capas negras al
     20 %, que compuestas dan este 36 %; se guarda ya combinado para no dejar
     dos elementos en el DOM haciendo el trabajo de uno.
     📌 Es un recurso ESTÉTICO, no de contraste: medido el 2026-08-28, el texto
     sobre el panel navy al 86 % llega a 10,44:1 sobre estas fotos sin velo
     ninguno. Quitarlo no rompe la lectura; cambia el tono. */
  --tk-overlay-photo-veil: rgba(0, 0, 0, 0.36);
  /* Fondos de los dos avisos de las páginas legales (2026-08-28).
     Son TINTES del color que ya lleva cada aviso en su filete, no colores
     nuevos: el ámbar es --warning y el azul es --tk-primary, los dos
     rebajados a un fondo que no compite con el texto de al lado.
     🔴 El ámbar es el único sitio del site que sale de la paleta
     navy/menta, y es deliberado: marca un defecto del documento de origen, y
     un aviso que se mimetiza con el diseño deja de ser un aviso.
     📌 Las alfas difieren (6 % vs 5 %) porque el ámbar es mucho más claro
     que el navy y al mismo valor se veía más fuerte. */
  --tk-bg-note-review: rgba(237, 108, 2, 0.06);
  --tk-bg-note-info: rgba(30, 41, 120, 0.05);
  --tk-gradient-stats: linear-gradient(
    95deg,
    #1e2978 0%,
    #384cde 100%
  ); /* horizontal-ish navy → navy-mid — landing stats band (Phase 8.4) */
  --tk-gradient-quote: linear-gradient(
    180deg,
    #116af8 0%,
    #49bbbd 100%
  ); /* link-blue → teal — landing testimonial quote-mark décor (Phase 8.6) */
  --tk-gradient-testimonials-bg: linear-gradient(
    269.35deg,
    #ffffff 0%,
    rgba(17, 106, 248, 0.6) 50%,
    #ffffff 100%
  ); /* Owner-driven 3-stop white→link-blue→white sandwich, middle stop @ 60 % alpha per owner request 2026-05-19 (was solid 100 → 80 → 60 after iterative tone-downs). Tune by swapping the alpha if needed. (Phase 8.6) */

  /* ── Animation timing (per ds — calm, confident) ── */
  --tk-motion-fast: 160ms; /* color/opacity transitions */
  --tk-motion-medium: 240ms; /* transforms */
  --tk-motion-easing: cubic-bezier(0.16, 1, 0.3, 1); /* ease-out */
}

/* ─────────────────────────────────────────────────────────────
   Dark theme tokens — Tekne native (2026-05-21, senior-derived).
   ───────────────────────────────────────────────────────────── */
/*
 * Approach: navy family backgrounds (NOT absolute black), mint accent
 * preserved (works beautifully on navy), text scale via white-alpha
 * opacity for hierarchy without color noise.
 *
 * Replaces the previous platform `.dark` cascade fallthrough (which was
 * dropping in Aranha tokens: red primary #8B0000, gold accent #C9A44C)
 * over the surviving Tekne `--tk-*` raw tokens — producing the
 * "Frankenstein" UI captured in admin dashboard screenshot 2026-05-21.
 *
 * Scope: ONLY applies when this file is loaded (Tekne tenant). Aranha
 * (which loads platform default) is unaffected because this file is not
 * fetched on Aranha routes.
 *
 * Pending: explicit Figma export. When Led provides one, cross-validate
 * these senior-derived values against the spec and iterate.
 *
 * Contrast verified WCAG AA/AAA:
 *   - white #FFFFFF on bg #0A0F2E → ~17:1 (AAA)
 *   - body rgba(255,255,255,0.85) on bg → ~14:1 (AAA)
 *   - secondary rgba(255,255,255,0.65) on bg → ~11:1 (AAA)
 *   - muted rgba(255,255,255,0.45) on bg → ~7.6:1 (AA pass)
 *   - mint #70FFE5 on bg → ~14:1 (AAA — accent)
 *   - surface #131A3F vs bg #0A0F2E → 1.4:1 (intentional subtle
 *     separation for cards — sufficient with shadow + border)
 */
.dark {
  /* ── Surfaces — navy family (NOT absolute black) ── */
  --tk-bg: #0a0f2e; /* deep navy — page background */
  --tk-bg-deep: #050818; /* deeper still — footer/heavy sections */
  --tk-bg-footer: #050818;
  --tk-surface: #131a3f; /* card bg — clearly distinguishable from page */
  --tk-paper: #1b2350; /* subtle bg shift — secondary surface */
  --tk-grey-divider: rgba(255, 255, 255, 0.1);

  /* ── Text — white-alpha scale for hierarchy ── */
  --tk-text: #ffffff;
  --tk-text-strong: rgba(255, 255, 255, 0.95);
  --tk-text-body: rgba(255, 255, 255, 0.85);
  --tk-text-secondary: rgba(255, 255, 255, 0.65);
  --tk-text-muted: rgba(255, 255, 255, 0.45);
  --tk-text-on-primary: #ffffff;
  --tk-text-on-accent: #0a0f2e; /* dark navy on mint stays — adjusted to dark bg navy */
  --tk-c-card-title: #c8d2ff; /* light lavender — navy family for dark contrast */
  --tk-c-card-body: rgba(255, 255, 255, 0.7);

  /* ── Borders — white-alpha ── */
  --tk-border-soft: rgba(255, 255, 255, 0.08);
  --tk-border-default: rgba(255, 255, 255, 0.18);
  --tk-border-strong: rgba(255, 255, 255, 0.4);

  /* ── Brand — mint stays, navy lightened for dark contrast ── */
  --tk-primary: #4a5aac; /* navy lightened — buttons stand out on dark navy bg */
  --tk-navy-deep: #050818;
  --tk-navy-mid: #6577e0; /* navy mid lightened for dark */
  --tk-accent: #70ffe5; /* mint STAYS — works perfectly on dark navy */
  --tk-accent-hover: #5deacf; /* mint slightly dimmer for hover in dark */
  --tk-link-blue: #5a9ffc; /* link blue lightened for dark contrast */

  /* ── Semantic UI ── */
  --link-color: var(--tk-accent);
  --link-color-hover: var(--tk-link-blue);
  --text-on-light-bg: var(--tk-text);
  --button-primary-bg: var(--tk-primary);
  --button-primary-text: var(--tk-text-on-primary);
  --button-accent-bg: var(--tk-accent);
  --button-accent-text: var(--tk-text-on-accent);
  --input-border: rgba(255, 255, 255, 0.2);
  --input-border-focus: var(--tk-accent);
  --input-bg: var(--tk-surface);

  /* ── Shadows — softer + glow-friendly for dark ── */
  --tk-shadow-card: 0 8px 24px rgba(0, 0, 0, 0.4);
  --tk-shadow-soft: 0 4px 12px rgba(0, 0, 0, 0.3);
  --tk-shadow-card-elevated: 0 10px 40px rgba(0, 0, 0, 0.4);
  --tk-shadow-card-hero: 0 14px 50px rgba(0, 0, 0, 0.5);
  --tk-shadow-testimonial: 0 4px 12px rgba(0, 0, 0, 0.35);
  --tk-shadow-ring: 0 0 0 4px rgba(112, 255, 229, 0.3);

  /* ── Platform contract — re-map for Tekne dark ──
     These override the globals.css `.dark` Aranha defaults
     (red primary #8B0000, gold accent #C9A44C, generic dark
     surfaces) so platform-agnostic components rendering on Tekne
     dark routes see Tekne navy + mint instead of Frankenstein.   */
  --background: var(--tk-bg);
  --background-internal: var(
    --tk-bg
  ); /* match body bg in Tekne dark — overrides
                                            globals.css `.dark` default #161616 so
                                            internal routes children container stays
                                            navy instead of gray-on-navy clash. */
  --surface: var(--tk-surface);
  --surface-secondary: var(--tk-paper);
  --foreground: var(--tk-text);
  --text-secondary: var(--tk-text-secondary);
  --muted-foreground: var(--tk-text-muted);
  --border: var(--tk-border-default);
  --primary: var(--tk-primary);
  --primary-hover: var(--tk-navy-mid);
  --primary-active: var(--tk-primary);
  --secondary: var(--tk-navy-deep);
  --secondary-hover: var(--tk-paper);
  --accent: var(--tk-accent);
  --accent-hover: var(--tk-accent-hover);
  --accent-soft: rgba(112, 255, 229, 0.16);

  /* Semantic feedback — lightened for dark legibility */
  --success: #66bb6a;
  --warning: #ffb74d;
  --error: #ef5350;
  /* Aclarado como sus hermanos: light-blue 400 de Material, 7,3:1 sobre la
     tarjeta #131a3f (el azul del claro se queda en 2,5:1). */
  --info: #29b6f6;
}

/* ─────────────────────────────────────────────────────────────
   `.tk-admin` — Tekne INTERNAL (logged-in) routes re-skin — NAVY + MINT.
   ═══════════════════════════════════════════════════════════════
   "Techy blueprint" two-colour brand system from the 2026-06-21 design
   handoff (`design_handoff_tekne_admin/` + canonical `.dc.html` screens).
   THE single visual identity for every Tekne internal surface: admin
   (2026-06-21), professor (TL-065) and — since the student-identity
   unification (José 2026-08-31) — the STUDENT as well. The earlier
   editorial-monochrome `.tk-protected` system it superseded has been
   removed from this file (git history keeps it). Two brand hues — navy
   #1E2978 + mint #70FFE5 — plus secondary blue #4E61F6; shadows
   REINSTATED; two themes share structure, swap surfaces:
     • Light "Light Ops" — navy ink on #f4f6fb, white cards, mint pills.
     • Dark "Blueprint"  — deep navy #06083f canvas, mint accent + glow.

   Isolation (triple guarantee):
     • Lives ONLY in tekne/theme.css → Aranha never downloads it.
     • Class gated to `themeKey === 'tekne'` at every mount point:
       (admin)/layout.tsx + BOTH Tekne branches of StudentLayoutShell
       (professor chrome and student chrome) → other tenants never
       carry it. Public/auth stay `.force-light`; superadmin unclassed.
     • Nearer ancestor than `<html class="dark">` → wins by proximity.

   RESET-raw-tokens-FIRST gotcha: declared AFTER
   `.dark` so `var(--tk-*)` resolves to navy+mint, not the inherited dark.
   Dual-family type: --font-sans = Ubuntu (titles/numbers/UI/nav/buttons);
   --tk-font-label = Inter (uppercase eyebrows + column labels).
   ───────────────────────────────────────────────────────────── */
.tk-admin {
  /* ── RESET raw --tk-* to navy+mint LIGHT (Light Ops) (FIRST) ── */
  --tk-bg: #f4f6fb; /* page / frame canvas */
  --tk-bg-deep: #06083f; /* blueprint ink (any deep section) */
  --tk-bg-footer: #06083f;
  --tk-surface: #ffffff; /* cards / topbar / sidebar surfaces */
  --tk-paper: #f8f9fd; /* table header + row hover (cool neutral) */
  --tk-grey-divider: rgba(30, 41, 120, 0.08); /* hairline */

  --tk-primary: #70ffe5; /* mint — PRIMARY action pill bg */
  --tk-navy-deep: #06083f;
  --tk-navy-mid: #384cde; /* light KPI/receita gradient endpoint */
  --tk-accent: #70ffe5; /* mint — live accent (active nav, toggles, dots) */
  --tk-accent-hover: #48deb1; /* mint hover / teal */
  --tk-link-blue: #4e61f6; /* secondary blue — eyebrows, inset bars, chart 2 */

  --tk-text: #1e2978; /* navy — headings / strong */
  --tk-text-strong: #1e2978;
  --tk-text-body: #5b5f7a; /* body / secondary */
  --tk-text-secondary: #5b5f7a;
  --tk-text-muted: #8a8fae; /* placeholders / column labels / sub-meta */
  --tk-text-on-primary: #1e2978; /* navy label on mint pill */
  --tk-text-on-accent: #06083f;
  --tk-c-card-title: #1e2978;
  --tk-c-card-body: #5b5f7a;

  --tk-border-soft: rgba(30, 41, 120, 0.06);
  --tk-border-default: rgba(30, 41, 120, 0.08); /* hairline */
  --tk-border-strong: rgba(30, 41, 120, 0.16);

  /* ── Shadows REINSTATED — soft navy elevation (Light Ops) ── */
  --tk-shadow-card: 0 8px 18px rgba(38, 45, 118, 0.05);
  --tk-shadow-card-hero: 0 24px 60px rgba(38, 45, 118, 0.1);
  --tk-shadow-soft: 0 4px 12px rgba(38, 45, 118, 0.04);
  --tk-shadow-card-elevated: 0 8px 18px rgba(38, 45, 118, 0.05);
  --tk-shadow-testimonial: 0 8px 18px rgba(38, 45, 118, 0.05);
  --tk-shadow-ring: 0 0 0 4px rgba(112, 255, 229, 0.25);

  /* ── Semantic UI tokens ── */
  /* Link ink = --tk-ink-accent (#384cde, 5.96:1 on the canvas), NOT
     --tk-link-blue #4e61f6: that one measures 4.45:1 on #f4f6fb — a hair
     under AA — which mattered once announcement/answer links started
     rendering on bg-background cards (student unification 2026-08-31). */
  --link-color: #384cde;
  --link-color-hover: #1e2978;
  --text-on-light-bg: #1e2978;
  --button-primary-bg: #70ffe5;
  --button-primary-text: #1e2978;
  --button-accent-bg: #70ffe5;
  --button-accent-text: #06083f;
  --input-border: rgba(30, 41, 120, 0.12);
  --input-border-focus: #4e61f6;
  --input-bg: #f4f6fb;

  /* ── Platform contract (consumed by globals.css @theme inline) ── */
  --background: #f4f6fb;
  --background-internal: #f4f6fb;
  --surface: #ffffff;
  --surface-secondary: #f8f9fd;
  --foreground: #1e2978;
  --text-secondary: #5b5f7a;
  /* #666a86 (4.89:1 on the canvas, 5.29:1 on white cards) — raised from the
     handoff's #8a8fae (2.93:1, sub-AA) when the student surface joined
     `.tk-admin` (José 2026-08-31): there this token paints substantive
     PARAGRAPHS (course/module descriptions, lesson subtitles), not just
     hints. Interpolated between --text-secondary and --tk-text-muted —
     both existing ramp stops. --tk-text-muted keeps #8a8fae for
     placeholders/column labels. */
  --muted-foreground: #666a86;
  --border: rgba(30, 41, 120, 0.08);
  /* `--muted` was NEVER defined in any Tekne scope while ~92 call sites use
     the arbitrary form `bg-[var(--muted)]` / `bg-(--muted)/N` → they painted
     `transparent`. Mirror the `bg-muted` UTILITY mapping (globals.css @theme:
     --color-muted → --surface-secondary) so both doors show the same value
     (feedback_puertas_divergentes). */
  --muted: var(--surface-secondary);
  --primary: #70ffe5; /* mint pill */
  --primary-hover: #48deb1;
  --primary-active: #48deb1;
  --primary-foreground: #1e2978; /* navy text on mint pill */
  --secondary: #1e2978; /* navy as secondary surface/text */
  --secondary-hover: #06083f;
  --accent: #70ffe5;
  --accent-hover: #48deb1;
  --accent-soft: rgba(112, 255, 229, 0.16);
  --accent-foreground: #06083f;
  --success: #1e8a5b; /* status green (light) */
  --warning: #ed6c02;
  --error: #d32f2f;
  --info: #1d4ed8; /* 6,7:1 sobre la tarjeta blanca; 4,9:1 en su pastilla sobre el lienzo */

  /* ── INK tokens — brand/status colours used as TEXT, not as SURFACE ──────
     `--accent`/`--primary` are mint #70ffe5 in BOTH modes while the canvas
     inverts, so every `text-accent` authored against the dark canvas lands at
     ~1.13:1 here. `@theme inline` compiles `.text-accent` and `.bg-accent` to
     read the SAME custom property, so the two roles cannot be split at the
     token alone — the `color` consumers are re-pointed by the rules further
     down. `--accent`/`--primary` keep the SURFACE role untouched: every mint
     pill, chip and fill is byte-identical.

     Values are EXISTING palette members, not new brand colours:
       #384cde = --tk-navy-mid (above)   #1e2978 = --foreground / --tk-text
     The status inks are luminance-only darkenings of --success / --warning
     along the same hue.

     `--tk-link-blue` #4e61f6 was REJECTED as the accent ink: it measures
     4.45:1 on the #f4f6fb canvas — a hair under AA.
     Measured (WCAG 2.1): #384cde on #ffffff 6.45 · #f4f6fb 5.96 · #f8f9fd 6.13
     · mint/5 6.36 · mint/15 5.78. #146b45 on bg-success/20 5.08 ·
     #a04f00 on bg-warning/15 4.93. */
  --tk-ink-accent: #384cde;
  --tk-ink-accent-hover: #1e2978;
  --tk-ink-success: #146b45;
  --tk-ink-warning: #a04f00;

  /* ── Radius — design handoff: control 10px default; cards 14px (via the
        named-utility overrides below). ── */
  --radius: 10px;

  /* ── Type — dual family (Ubuntu UI + Inter labels), self-hosted ── */
  --font-sans: "Ubuntu", system-ui, -apple-system, sans-serif;
  --tk-font-display: "Ubuntu", system-ui, sans-serif;
  --tk-font-body: "Ubuntu", system-ui, sans-serif;
  --tk-font-label: "Inter", system-ui, -apple-system, sans-serif;
  font-family: var(--font-sans);

  /* Self-paint so the dark <body> underneath never bleeds at edges. */
  position: relative; /* anchor the dark grid-mesh + glow pseudo-elements */
  background: var(--background);
  color: var(--foreground);
}

/* ── `.dark .tk-admin` — DARK "Blueprint": deep navy #06083f + mint glow.
   Specificity (0,2,0) > `.tk-admin` (0,1,0) → wins when <html class="dark">.
   --radius + --font-* + self-paint carry over (same element, vars re-resolve). */
.dark .tk-admin {
  --tk-bg: #06083f; /* deep navy blueprint canvas */
  --tk-bg-deep: #050518;
  --tk-bg-footer: #050518;
  --tk-surface: rgba(255, 255, 255, 0.03); /* barely-lifted translucent card */
  --tk-paper: rgba(255, 255, 255, 0.05);
  --tk-grey-divider: rgba(112, 255, 229, 0.12); /* mint-tinted hairline */

  --tk-primary: #70ffe5; /* mint pill stays */
  --tk-navy-deep: #050518;
  --tk-navy-mid: #4e61f6;
  --tk-accent: #70ffe5;
  --tk-accent-hover: #48deb1;
  --tk-link-blue: #70ffe5; /* links go mint in dark */

  --tk-text: #ffffff;
  --tk-text-strong: #ffffff;
  --tk-text-body: #cdd2ec;
  --tk-text-secondary: #cdd2ec;
  --tk-text-muted: #9aa0c9;
  --tk-text-on-primary: #06083f; /* ink-navy on mint pill */
  --tk-text-on-accent: #06083f;
  --tk-c-card-title: #ffffff;
  --tk-c-card-body: #cdd2ec;

  --tk-border-soft: rgba(255, 255, 255, 0.06);
  --tk-border-default: rgba(112, 255, 229, 0.12);
  --tk-border-strong: rgba(112, 255, 229, 0.2);

  /* shadows — deeper for dark + mint focus glow */
  --tk-shadow-card: 0 8px 24px rgba(0, 0, 0, 0.35);
  --tk-shadow-card-hero: 0 24px 60px rgba(0, 0, 0, 0.45);
  --tk-shadow-soft: 0 4px 12px rgba(0, 0, 0, 0.3);
  --tk-shadow-card-elevated: 0 10px 40px rgba(0, 0, 0, 0.4);
  --tk-shadow-testimonial: 0 8px 24px rgba(0, 0, 0, 0.35);
  --tk-shadow-ring: 0 0 0 4px rgba(112, 255, 229, 0.3);

  /* ── Semantic UI tokens ── */
  --link-color: #70ffe5;
  --link-color-hover: #48deb1;
  --text-on-light-bg: #ffffff;
  --button-primary-bg: #70ffe5;
  --button-primary-text: #06083f;
  --button-accent-bg: #70ffe5;
  --button-accent-text: #06083f;
  --input-border: rgba(112, 255, 229, 0.16);
  --input-border-focus: #70ffe5;
  --input-bg: rgba(255, 255, 255, 0.05);

  /* ── Platform contract (dark) ── */
  --background: #06083f;
  /* transparent so the blueprint grid-mesh + glow (on the .tk-admin pseudos,
     z-0) show THROUGH the content scroll area and behind the translucent
     cards. The deep-navy canvas is painted by .tk-admin self-paint. */
  --background-internal: transparent;
  --surface: rgba(255, 255, 255, 0.03);
  --surface-secondary: rgba(255, 255, 255, 0.05);
  /* Superficie de lo que flota sobre el contenido (ventanas y paneles
     laterales): OPACA a propósito, o el contenido de detrás se lee a través
     del cristal (TK-54). Sólo aquí: en los demás ámbitos --surface ya es opaca.
     #121449 = 5 % de blanco sobre #06083f: 255·0,05 + (6, 8, 63)·0,95. */
  --surface-overlay: #121449;
  --foreground: #ffffff;
  --text-secondary: #cdd2ec;
  --muted-foreground: #9aa0c9;
  --border: rgba(112, 255, 229, 0.12);
  --muted: var(--surface-secondary); /* see the light-scope note */
  --primary: #70ffe5;
  --primary-hover: #48deb1;
  --primary-active: #48deb1;
  --primary-foreground: #06083f;
  --secondary: #cdd2ec;
  --secondary-hover: #ffffff;
  --accent: #70ffe5;
  --accent-hover: #48deb1;
  --accent-soft: rgba(112, 255, 229, 0.12);
  --accent-foreground: #06083f;
  --success: #70ffe5; /* mint encodes positive in dark */
  --warning: #ffb74d;
  --error: #ef5350;
  --info: #29b6f6; /* aclarado como error y warning: 7,8:1 sobre la tarjeta */

  /* ── INK tokens — DARK is a PROVABLE no-op ──────────────────────────────
     Each points back at the token the utility already resolves to, so every
     remap below computes byte-identically in dark. Written as var()
     indirection and NEVER as copied literals, so a future palette re-tune
     flows through and cannot silently fork. Asserted mechanically in
     tests/tekne-admin-light-ink.test.ts. */
  --tk-ink-accent: var(--accent);
  --tk-ink-accent-hover: var(--accent-hover);
  --tk-ink-success: var(--success);
  --tk-ink-warning: var(--warning);
}

/* ── DARK "Blueprint" ATMOSPHERE — decorative grid mesh + navy glow. ──
   Verbatim from the canonical Dashboard .dc.html (Blueprint frame): a 42px mint
   grid (rgba(112,255,229,.045)) + a 520px secondary-blue radial glow anchored
   off the top-right corner. LIGHT "Light Ops" has NEITHER (flat #f4f6fb canvas)
   so these live ONLY under `.dark .tk-admin`. Pointer-events:none, z-0; the
   shell children are lifted to z-1 (rule below) so they paint above. The dark
   content area is transparent (--background-internal) so the mesh + glow show
   through behind the translucent cards. */
.dark .tk-admin::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(112, 255, 229, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(112, 255, 229, 0.045) 1px, transparent 1px);
  background-size: 42px 42px;
  pointer-events: none;
  z-index: 0;
}
.dark .tk-admin::after {
  content: "";
  position: absolute;
  top: -160px;
  right: -120px;
  width: 520px;
  height: 520px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(78, 97, 246, 0.35), transparent 65%);
  pointer-events: none;
  z-index: 0;
}
/* Lift the shell (sidebar + main column) above the z-0 decoration. Scoped to
   `.tk-admin` so it cannot reach Aranha. */
.tk-admin > * {
  position: relative;
  z-index: 1;
}

/* Pulsing status dot — topbar "Operacional" + sidebar footer (design tkpulse). */
@keyframes tk-pulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(112, 255, 229, 0.5);
  }
  50% {
    box-shadow: 0 0 0 4px rgba(112, 255, 229, 0);
  }
}
.tk-pulse-dot {
  animation: tk-pulse 2.4s infinite;
}

/* Foreground pairing utilities for `.tk-admin` — Tailwind v4 gotcha: the token
   lives only in a scoped class (never in :root at build time) so the utility is
   never generated → define as plain scoped CSS (flips per mode via .dark). */
.tk-admin .text-primary-foreground {
  color: var(--primary-foreground);
}
.tk-admin .text-accent-foreground {
  color: var(--accent-foreground);
}

/* ── LIGHT-mode contrast repair on mint accent surfaces ──────────────────────
   Two class pairs invert catastrophically in LIGHT, because `--accent` stays
   mint (#70ffe5) in BOTH modes while `--background` flips (#06083f dark →
   #f4f6fb light):

     (A) `bg-accent`   + `text-background`  →  1.13:1  (near-white on mint)
     (B) `bg-accent/N` + `text-accent`      →  1.18:1  (mint on pale mint)

   Both were authored against the dark canvas, where they read correctly.

   Repaired here as scoped CSS instead of by editing the components, because
   those components are SHARED: `components/layout/Header.tsx` is imported by
   `app/[locale]/(public)/layout.tsx` — the Tekne LANDING. Editing the JSX
   would change the landing and Aranha; a `.tk-admin`-scoped rule provably
   cannot, since that class exists only on the Tekne admin + professor
   layouts. Same technique as the radii overrides below (José 2026-06-20,
   Option A).

   Colour is `--accent-foreground` (#06083f) — already part of the light
   palette and semantically "text on accent". The mint background is left
   untouched, so brand identity does not change.

   Specificity: `.tk-admin [class~=…][class*=…]` = (0,3,0) beats the bare
   utility (0,1,0); the `.dark` restore below = (0,4,0) beats that. */

/* (A) — applied in BOTH modes deliberately: in `.dark .tk-admin`,
   `--background` and `--accent-foreground` are the SAME `#06083f`, so the
   computed colour in dark is byte-identical to today. Provable no-op. */
.tk-admin [class~="text-background"][class*="bg-accent"],
.tk-admin [class~="text-[var(--background)]"][class*="bg-[var(--accent)"] {
  color: var(--accent-foreground);
}

/* (B) — light only. The fourth selector closes a structural hole found in the
   student unification (Sidebar.tsx nav items): the bare-var spelling
   `bg-(--accent)/N` is EXCLUDED from the general ink rule below (correctly —
   it has a mint background) but was never covered here either, so its
   `text-accent` kept raw mint on light. */
.tk-admin [class~="text-accent"][class*="bg-accent"],
.tk-admin [class~="text-primary"][class*="bg-primary"],
.tk-admin [class~="text-[var(--accent)]"][class*="bg-[var(--accent)"],
.tk-admin [class~="text-accent"][class*="bg-(--accent)"] {
  color: var(--accent-foreground);
}

/* (B) restored for dark — mint text over translucent mint reads correctly on
   the deep-navy canvas, so dark must keep its original colour. */
.dark .tk-admin [class~="text-accent"][class*="bg-accent"],
.dark .tk-admin [class~="text-primary"][class*="bg-primary"],
.dark .tk-admin [class~="text-[var(--accent)]"][class*="bg-[var(--accent)"],
.dark .tk-admin [class~="text-accent"][class*="bg-(--accent)"] {
  color: var(--accent);
}

/* ══════════════════════════════════════════════════════════════════════════
   LIGHT-MODE INK REPAIR — brand/status colours used as TEXT on light surfaces.

   Extends the block above from the SAME-ELEMENT mint-on-mint pairs to the
   general case: mint used as ink with no mint background of its own. That is
   the majority of the defect and the block above structurally cannot reach it
   (it requires both classes on ONE element, so text whose background sits on a
   PARENT — e.g. LessonManagement.tsx:463-464 under a `bg-[var(--accent)]/5`
   parent — was never covered), nor can it reach `hover:`/`group-hover:`
   variants, which are DIFFERENT class tokens.

   WHY SCOPED CSS AND NOT COMPONENT EDITS — unchanged: `components/layout/
   Header.tsx` is imported by `app/[locale]/(public)/layout.tsx`, the Tekne
   LANDING, and the course-editor components are shared with Aranha's admin.
   `.tk-admin` exists on exactly two elements repo-wide (admin/layout.tsx:24,
   StudentLayoutShell.tsx:60), so a scoped rule provably reaches neither.

   CASCADE — this stylesheet is UNLAYERED (no @layer in this file) while
   Tailwind's utilities compile into `@layer utilities`. Unlayered author CSS
   beats every layered rule regardless of specificity or source order, so these
   win over `hover:` variants with no specificity padding. Do NOT add `[class]`
   filler "to break a tie" — there is no tie.

   MATCHING — `[class~=…]` is whole-token, so `text-accent-foreground` and
   `text-primary-foreground` (already correct) can never match. Rules key on
   CLASS NAMES ONLY, never on hex literals, which is what keeps
   TekneAdminDashboard.tsx:556 (`text-[#48deb1]` on an aria-hidden <svg> feeding
   currentColor into a gradient + polyline — NOT text) and :272
   (`text-[#c4fff4]` on the navy Receita tile, ~11.5:1 — already correct)
   untouched. Both were false positives of the static sweep.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Mint-as-ink, rest state. The :not() list excludes:
   1-4. any mint BACKGROUND spelling → owned by the block above, which already
        paints --accent-foreground there. Four spellings because Tailwind v4
        accepts `bg-[var(--accent)]` AND the bare-var shorthand `bg-(--accent)`;
        the latter IS used in this repo (Sidebar.tsx:174,
        admin/content-review/page.tsx:233).
   5.   form controls → `text-*` on a checkbox is the @tailwindcss/forms FILL
        idiom, not text (content/CourseSettingsForm.tsx:203). Inert today. */
.tk-admin
  :is(
    [class~="text-accent"],
    [class~="text-primary"],
    [class~="text-[var(--accent)]"]
  ):not(
    [class*="bg-accent"],
    [class*="bg-primary"],
    [class*="bg-[var(--accent)"],
    [class*="bg-(--accent)"],
    input,
    select,
    textarea
  ) {
  color: var(--tk-ink-accent);
}

/* Hover + group-hover. `hover:text-accent-hover` gets the DARKER ink: its rest
   state is already --tk-ink-accent, so darkening is the standard link idiom.
   `hover:text-primary/80` DROPS its alpha deliberately — 80% of #384cde
   composites to 4.25:1, under AA. */
.tk-admin
  :is(
    [class~="hover:text-accent"],
    [class~="hover:text-primary"],
    [class~="hover:text-[var(--accent)]"]
  ):hover {
  color: var(--tk-ink-accent);
}
.tk-admin :is([class~="text-accent-hover"], [class~="hover:text-accent-hover"]):hover,
.tk-admin [class~="hover:text-primary/80"]:hover {
  color: var(--tk-ink-accent-hover);
}
.tk-admin
  .group:hover
  :is([class~="group-hover:text-accent"], [class~="group-hover:text-primary"]) {
  color: var(--tk-ink-accent);
}

/* Status tokens on their own translucent tints. --success/--warning keep the
   SURFACE role, so every bg-success/N and bg-warning/N tint is unchanged. */
.tk-admin [class~="text-success"] {
  color: var(--tk-ink-success);
}
.tk-admin [class~="text-warning"] {
  color: var(--tk-ink-warning);
}

/* Extends rule (A) by the ONE broken `text-background` pairing. Verified by
   grep, `text-background` co-occurs with: bg-accent (covered by (A)),
   bg-foreground ×7 (11.82:1 — CORRECT, must not change), bg-error ×4 (4.61:1 —
   CORRECT, must not change), bg-warning ×1 (2.88:1 — broken:
   announcements/RetryFailedButton.tsx:177).
   This stays an INCLUSION list. Do NOT invert it to an exclusion list — that is
   the single most damaging edit possible here (bg-foreground would fall from
   11.82:1 to 1.48:1 across 7 sites). #06083f on #ed6c02 = 6.06:1; in dark,
   --accent-foreground and --background are both #06083f, so this is a no-op
   there, exactly like rule (A). */
.tk-admin [class~="text-background"][class*="bg-warning"] {
  color: var(--accent-foreground);
}

/* ── Raw Tailwind-palette ink — the status-badge family ────────────────────
   `app/[locale]/(admin)/admin/courses/page.tsx:106-110` is
   `bg-green-500/20 text-green-400` — RAW PALETTE, not `text-success`. The -400
   tier is Tailwind's DARK-canvas ink tier; every use here was authored for the
   dark theme and lands at ~1.4:1 on light. Same maps in content/page.tsx,
   students/page.tsx, users/page.tsx, SurveyStatusBadge.tsx, events/page.tsx.

   CLASS selectors, deliberately NOT a `--color-*-400` variable override: that
   var is also read by `bg-`, `border-` and `fill-` utilities, so overriding it
   turns the gold stars at reviews/CourseReviewSection.tsx:77,120,179
   (`fill-amber-400 text-amber-400`, reachable under .tk-admin via the
   professor-viewer shell) burnt orange. A class selector touches only `color`;
   `:not([class*="fill-"])` protects the one element feeding an SVG stroke.

   Targets are Tailwind's own -800 shades — hue preserved, luminance moved — so
   the semantic colour coding survives. Gated `:not(.dark *)` (`.dark` sits on
   <html> via next-themes, app/[locale]/layout.tsx) — the -400 tier is correct
   on the dark canvas and is left alone. */
.tk-admin:not(.dark *)
  :is([class~="text-green-400"], [class~="text-green-500"]):not([class*="fill-"]) {
  color: var(--color-green-800, oklch(44.8% 0.119 151.328));
}
.tk-admin:not(.dark *)
  :is([class~="text-emerald-400"], [class~="text-emerald-500"]):not([class*="fill-"]) {
  color: var(--color-emerald-800, oklch(43.2% 0.095 166.913));
}
.tk-admin:not(.dark *)
  :is([class~="text-blue-400"], [class~="text-blue-300"]):not([class*="fill-"]) {
  color: var(--color-blue-800, oklch(42.4% 0.199 265.638));
}
.tk-admin:not(.dark *)
  :is([class~="text-yellow-400"], [class~="text-yellow-500"]):not([class*="fill-"]) {
  color: var(--color-yellow-800, oklch(47.6% 0.114 61.907));
}
.tk-admin:not(.dark *)
  :is([class~="text-amber-400"], [class~="text-amber-500"]):not([class*="fill-"]) {
  color: var(--color-amber-800, oklch(47.3% 0.137 46.201));
}
.tk-admin:not(.dark *) :is([class~="text-orange-400"]):not([class*="fill-"]) {
  color: var(--color-orange-800, oklch(47% 0.157 37.304));
}
.tk-admin:not(.dark *)
  :is([class~="text-red-400"], [class~="text-red-300"]):not([class*="fill-"]) {
  color: var(--color-red-800, oklch(44.4% 0.177 26.899));
}

/* ══════════════════════════════════════════════════════════════════════════
   STUDENT-UNIFICATION REPAIR BATTERY (2026-08-31).

   When the Tekne STUDENT shell moved from the monochrome `.tk-protected` to
   `.tk-admin`, a measured sweep of the ~27 student screens (43 confirmed
   defects after adversarial verification) surfaced defect families the admin
   surface never exercised — authored against the monochrome contract, where
   `--accent` was near-black ink. Same technique as everything above: scoped
   class-matching CSS, no component edits, unlayered so it beats utilities.
   Several rules also repair PRE-EXISTING admin/professor light-mode bugs
   (WatchCourseSidebar, MaterialUploadDialog, LessonManagement fills).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Tier additions — colours the admin screens never used (student dashboard
   StatCards, leaderboard medals). Same -800 target logic as the family above;
   greys move two steps instead (they are already desaturated). */
.tk-admin:not(.dark *)
  :is([class~="text-violet-400"], [class~="text-violet-500"]):not([class*="fill-"]) {
  color: var(--color-violet-800, oklch(43.2% 0.232 292.759));
}
.tk-admin:not(.dark *)
  :is([class~="text-cyan-400"], [class~="text-cyan-500"]):not([class*="fill-"]) {
  color: var(--color-cyan-800, oklch(45% 0.085 224.283));
}
.tk-admin:not(.dark *)
  :is([class~="text-pink-400"], [class~="text-pink-500"]):not([class*="fill-"]) {
  color: var(--color-pink-800, oklch(45.9% 0.187 3.815));
}
.tk-admin:not(.dark *) :is([class~="text-gray-300"]):not([class*="fill-"]) {
  color: var(--color-gray-500, oklch(55.1% 0.027 264.364));
}
.tk-admin:not(.dark *) :is([class~="text-gray-400"]):not([class*="fill-"]) {
  color: var(--color-gray-600, oklch(44.6% 0.03 256.802));
}
.tk-admin:not(.dark *) :is([class~="text-amber-600"]):not([class*="fill-"]) {
  color: var(--color-amber-800, oklch(47.3% 0.137 46.201));
}

/* White-on-mint — BOTH modes. `--accent`/`--primary` are mint in light AND
   dark, so `text-white` (survey primary buttons, checkbox check) and the
   white radio dot / switch thumb land at ~1.25:1 everywhere. The word-match
   `[class~="bg-accent"]` deliberately requires the SOLID surface: children of
   translucent tints (`bg-accent/10`) keep their own colours. `text-white` and
   `bg-white` are not in any rule above, so there is no overlap to restore. */
.tk-admin [class~="text-white"]:is([class~="bg-accent"], [class~="bg-primary"]),
.tk-admin
  :is([class~="bg-accent"], [class~="bg-primary"])
  [class~="text-white"] {
  color: var(--accent-foreground);
}
.tk-admin
  :is([class~="bg-accent"], [class~="bg-primary"])
  [class~="bg-white"] {
  background-color: var(--accent-foreground);
}

/* Focus / state indication — light only. Mint rings and borders measure
   1.13–1.14:1 on the light canvas, and several controls pair them with
   `focus:outline-none` — leaving NO visible keyboard-focus indicator (WCAG
   2.4.7/1.4.11). `[class*="ring-accent"]` intentionally catches every
   spelling at once: `ring-accent`, `ring-accent/30`, `focus:ring-accent`,
   `focus-visible:ring-accent` — the ring only paints when the ring-width
   utility activates, so re-inking the colour var is safe in every state. */
.tk-admin:not(.dark *) [class*="ring-accent"] {
  --tw-ring-color: var(--tk-ink-accent);
}
.tk-admin:not(.dark *) [class~="border-accent"],
.tk-admin:not(.dark *) [class~="hover:border-accent"]:hover,
.tk-admin:not(.dark *) [class~="focus:border-accent"]:focus,
.tk-admin:not(.dark *) [class~="focus-visible:border-accent"]:focus-visible {
  border-color: var(--tk-ink-accent);
}

/* Progress fills — light only. A mint fill on the near-white tracks
   (`bg-muted-foreground/15`, `bg-muted/30`…) measures ~1.01:1: the bar
   literally vanishes. Every `h-full` + mint-background pairing in the repo IS
   a progress fill (verified by grep — course page, survey taker,
   ContinueWatching, history, requirements, watch sidebar, admin upload/lesson
   dialogs), so the combo is safe to re-ink wholesale. */
.tk-admin:not(.dark *)
  [class~="h-full"]:is(
    [class~="bg-accent"],
    [class~="bg-[var(--accent)]"]
  ) {
  background-color: var(--tk-ink-accent);
}

/* Indicator dots — light only (notification unread dot, survey progress
   dots). Sized word-matches keep this away from pills and buttons. The /50
   "answered" dot keeps its reduced emphasis via color-mix on the ink. */
.tk-admin:not(.dark *)
  :is([class~="h-1.5"][class~="w-1.5"], [class~="h-2"][class~="w-2"])[class~="rounded-full"][class~="bg-accent"] {
  background-color: var(--tk-ink-accent);
}
.tk-admin:not(.dark *)
  :is([class~="h-1.5"][class~="w-1.5"], [class~="h-2"][class~="w-2"])[class~="rounded-full"][class~="bg-accent/50"] {
  background-color: color-mix(in oklab, var(--tk-ink-accent) 65%, transparent);
}

/* @tailwindcss/forms fill idiom — light only. `text-accent` on a radio/
   checkbox is the CHECKED-STATE FILL (background: currentColor), which the
   general ink rule above correctly excludes as "not text" — but the mint fill
   itself is 1.23:1 on a light card, so the checked state disappears. */
.tk-admin:not(.dark *) input[type="radio"][class~="text-accent"],
.tk-admin:not(.dark *) input[type="checkbox"][class~="text-accent"] {
  color: var(--tk-ink-accent);
}

/* Alpha-modified mint text — light only. The /N suffix makes a DIFFERENT
   class token, so `[class~="text-accent"]` never matches it and the element
   keeps raw mint (~1.1:1). No opaque ink survives a 0.4–0.8 multiplier at AA,
   so the alpha is deliberately dropped (same reasoning as
   `hover:text-primary/80` above). Enumerated word-matches — a contains-match
   on "text-accent/" would also seize `hover:`-variant tokens at rest. */
.tk-admin:not(.dark *)
  :is(
    [class~="text-accent/40"],
    [class~="text-accent/50"],
    [class~="text-accent/60"],
    [class~="text-accent/70"],
    [class~="text-accent/80"]
  ) {
  color: var(--tk-ink-accent);
}

/* Mention chip (globals.css `.mention-chip`) — a CSS class, not utilities, so
   rule (A) cannot see it: `background: var(--accent)` + `color:
   var(--background)` = near-white on mint (1.13:1) in light. Same provable
   no-op in dark as rule (A): there `--background` and `--accent-foreground`
   are both #06083f. */
.tk-admin .mention-chip {
  color: var(--accent-foreground);
}

/* Survey error card — the ink `#384cde` painted by the general rule measures
   ~4.2:1 over the red-tinted card (`bg-red-950/20` over the canvas), a hair
   under AA. The darker ink clears it. Light only. */
.tk-admin:not(.dark *) [class~="bg-red-950/20"] [class~="text-accent"] {
  color: var(--tk-ink-accent-hover);
}

/* Mobile nav drawer (Sidebar) — `bg-(--muted)/30` over the `bg-black/60`
   overlay composed to mud even with `--muted` now defined (30% of a light
   surface over a dark scrim). A floating drawer needs an OPAQUE canvas. */
.tk-admin [class~="bg-(--muted)/30"] {
  background-color: var(--tk-bg);
}

/* Radii — the design handoff uses two tiers: controls/nav = 10px (rounded-lg),
   cards/modules = 14px (rounded-xl/2xl/3xl). Retarget the shared Tailwind
   utilities under `.tk-admin` (specificity 0,2,0 > the bare utility 0,1,0) so
   every admin screen honours the design radii WITHOUT editing shared
   components (e.g. the sidebar nav items use `rounded-lg` → now 10px, matching
   the proposal). Pills (rounded-full) + small chips (rounded-[3px]/sm/md) keep
   their intended radii. Aranha-safe: only under `.tk-admin`. */
.tk-admin :is(.rounded-lg) {
  border-radius: 10px;
}
.tk-admin :is(.rounded-xl, .rounded-2xl, .rounded-3xl) {
  border-radius: 14px;
}

/* ─────────────────────────────────────────────────────────────
   Original placeholder kept as historical reference (was line 264-271)
   ───────────────────────────────────────────────────────────── */

/* ─────────────────────────────────────────────────────────────
   `.force-light` — Tekne overrides for the global `.force-light` opt-out
   wrapper (defined in globals.css). When a route applies `.force-light`
   (today: `(public)` landing + `(auth)` flows), even under
   `<html class="dark">`, the subtree renders with Tekne LIGHT tokens
   (brand-specific white #FFFFFF, navy text, mint accent). Per José
   2026-05-21: landing pages are always light; only internal dashboard
   routes honor dark mode.
   ───────────────────────────────────────────────────────────── */
.force-light {
  /* RESET all Tekne raw tokens that `.dark` overrode back to `:root` LIGHT
     values FIRST. Without this, `var(--tk-bg)` (and friends) below would
     resolve to the dark navy `.dark` set on `<html>` (inherited), and the
     wrapper would still render dark — which was the bug 2026-05-21 fix.
     CSS custom property cascade resolves var() at use-time on the element
     where the var is read; so as long as the raw tokens are redeclared on
     `.force-light` itself, the platform contract below resolves to light. */
  --tk-bg: #ffffff;
  --tk-bg-deep: #1e2978;
  --tk-bg-footer: #060841;
  --tk-surface: #ffffff;
  --tk-paper: #f5f7fa;
  --tk-grey-divider: #d9d9d9;

  --tk-primary: #1e2978;
  --tk-navy-deep: #060841;
  --tk-navy-mid: #384cde;
  --tk-accent: #70ffe5;
  --tk-accent-hover: #48deb1;
  --tk-link-blue: #116af8;

  --tk-text: #1e2978;
  --tk-text-strong: rgba(3, 1, 20, 0.95);
  --tk-text-body: rgba(3, 1, 20, 0.8);
  --tk-text-secondary: #5b5b5b;
  --tk-text-muted: #acacac;
  --tk-text-on-primary: #ffffff;
  --tk-text-on-accent: #1e2978;
  --tk-c-card-title: #2f327d;
  --tk-c-card-body: #696984;

  --tk-border-soft: rgba(30, 41, 120, 0.08);
  --tk-border-default: rgba(30, 41, 120, 0.18);
  --tk-border-strong: #1e2978;

  /* Shadows — light variants (heavier rgba on light bg per design system) */
  --tk-shadow-card: 0 14px 34px rgba(0, 0, 0, 0.1);
  --tk-shadow-card-hero: 20px 14px 34px rgba(0, 0, 0, 0.25);
  --tk-shadow-soft: 0 8px 18px rgba(38, 45, 118, 0.08);
  --tk-shadow-card-elevated: 0 8.47849px 50.871px rgba(38, 45, 118, 0.08);
  --tk-shadow-testimonial: 0 4px 4px rgba(0, 0, 0, 0.25);
  --tk-shadow-ring: 0 0 0 4px rgba(112, 255, 229, 0.25);

  /* Platform contract — now resolves to LIGHT values via the reset raw tokens */
  --background: #ffffff;
  --background-internal: #ffffff;
  --surface: #ffffff;
  --surface-secondary: #f5f7fa;
  --foreground: #1e2978;
  --text-secondary: #5b5b5b;
  --muted-foreground: #acacac;
  --border: rgba(30, 41, 120, 0.18);
  --primary: #1e2978;
  --primary-hover: #1e2978;
  --primary-active: #1e2978;
  --secondary: #060841;
  --secondary-hover: #060841;
  --accent: #70ffe5;
  --accent-hover: #48deb1;
  --accent-soft: rgba(112, 255, 229, 0.11);
  --success: #2e7d32;
  --warning: #ed6c02;
  --error: #d32f2f;
  --info: #1d4ed8;

  /* Semantic UI tokens (Phase 3.6 contract) */
  --link-color: #116af8;
  --link-color-hover: #1e2978;
  --text-on-light-bg: #1e2978;
  --button-primary-bg: #1e2978;
  --button-primary-text: #ffffff;
  --button-accent-bg: #70ffe5;
  --button-accent-text: #1e2978;
  --input-border: rgba(30, 41, 120, 0.18);
  --input-border-focus: #1e2978;
  --input-bg: #ffffff;

  /* Re-apply body-level visuals on the wrapper so the dark <body>
     underneath does not bleed through edges (callers also use min-h-screen). */
  background: var(--background);
  color: var(--foreground);
}

/* ─────────────────────────────────────────────────────────────
   Selection color (per ds README — mint highlight on navy)
   ───────────────────────────────────────────────────────────── */
::selection {
  background: var(--tk-selection-bg);
  color: var(--tk-selection-fg);
}

/* Firefox antiguo no entiende `::selection`; va en su PROPIA regla porque un
   selector desconocido dentro de una lista invalida la regla entera. */
::-moz-selection {
  background: var(--tk-selection-bg);
  color: var(--tk-selection-fg);
}
