/* =============================================================================
   QUELL BASE v1.0.0
   A safety-first CSS baseline for the modern web.

   License : EULA - need to add
   Docs    : See README.md

   Architecture
   =============================================================================
   @layer ghost_tokens   Ghost/fallback design tokens. Resolved before paint.
   @layer reset          Browser inconsistency erasure. Zero visual opinions.
   @layer baseline       Minimal visual design. Consumes tokens.
   @layer forms          2026-era form normalization. Isolated surface.
   @layer utilities      Reserved slot. Highest-priority layer in quell-base.css core.

   Usage (standalone)
   =============================================================================
   <link rel="stylesheet" href="quell-base.css">

   Usage (companion - load quell-base.css first, then your theme)
   =============================================================================
   <link rel="stylesheet" href="quell-base.css">
   <link rel="stylesheet" href="your-theme.css">

   Override surfaces (in ascending power)
   =============================================================================
   A. Token override  - re-declare --custom-props on :root outside any layer.
   B. Layer append    - @layer baseline { } in your own sheet reopens the layer.
   C. Unlayered rule  - any selector outside a layer beats all quell's layers.

   No !important required. Ever.
   ============================================================================= */

/* =============================================================================
   LAYER DECLARATION
   Order here = priority order, ascending. Last declared = highest priority.
   Unlayered styles (your theme) always beat every layer listed below.
   ============================================================================= */

   @layer ghost_tokens, reset, baseline, forms, utilities;

/* =============================================================================
   LAYER 1 · ghost_tokens
   =============================================================================
   Purpose
     Provide fully-resolved fallback values for every token this baseline
     consumes. The browser parses :root custom properties before the first
     paint, so downstream var() calls are never left with an empty string,
     even if a theme sheet has not loaded yet. This is the FOUC firewall.

   Override strategy
     Declare the same property on :root *outside* any @layer in your theme
     sheet. Unlayered styles always win in the CSS cascade, regardless of
     load order. No specificity gymnastics required.

     Example:
       :root { --color-accent: #7c3aed; }   <-- beats this entire layer

   Token naming convention
     --{category}-{variant}: {value}
     Categories: font, color, space, size, radius, border, shadow, motion
   ============================================================================= */

/* =============================================================================
   QUELL BASE v1.0.0
   Una base CSS enfocada en la seguridad para la web moderna.

   Licencia : EULA - pendiente de añadir
   Docs     : Ver README.md

   Arquitectura
   =============================================================================
   @layer ghost_tokens   Tokens de diseño de respaldo/fantasma. Resueltos antes del pintado.
   @layer reset          Eliminación de inconsistencias del navegador. Cero opinión visual.
   @layer baseline       Diseño visual mínimo. Consume tokens.
   =============================================================================
   @layer forms          Normalización de formularios era 2026. Superficie aislada.
   @layer utilities      Espacio reservado. Capa de mayor prioridad en el núcleo de quell-base.css.

   Uso (independiente)
   =============================================================================
   <link rel="stylesheet" href="quell-base.css">

   Uso (acompañante - carga quell-base.css primero, luego tu tema)
   =============================================================================
   <link rel="stylesheet" href="quell-base.css">
   <link rel="stylesheet" href="your-theme.css">

   Superficies de anulación (en orden ascendente de prioridad)
   =============================================================================
   A. Anulación de tokens - declara de nuevo las --custom-props en :root fuera de cualquier capa.
   B. Anexo de capa         - @layer baseline { } en tu propia hoja reabre la capa.
   C. Regla sin capa        - cualquier selector fuera de una capa supera a todas las capas de quell.

   No se requiere !important. Nunca.
   ============================================================================= */

/* =============================================================================
   DECLARACIÓN DE CAPAS
   El orden aquí = orden de prioridad, ascendente. La última declarada = mayor prioridad.
   Los estilos sin capa (tu tema) siempre superan a todas las capas listadas abajo.
   ============================================================================= */

/* =============================================================================
   CAPA 1 · ghost_tokens
   =============================================================================
   Propósito
     Proporcionar valores de respaldo completamente resueltos para cada token que
     este baseline consume. El navegador analiza las propiedades personalizadas de
     :root antes del primer pintado. Las llamadas var() posteriores nunca quedan
     vacías, incluso si la hoja del tema no ha cargado. Es el cortafuegos contra el FOUC.

   Estrategia de anulación
     Declara la misma propiedad en :root *fuera* de cualquier @layer en la hoja
     de tu tema. Los estilos sin capa siempre ganan en la cascada de CSS, sin importar
     el orden de carga. No requiere gimnasia de especificidad.

     Ejemplo:
       :root { --color-accent: #7c3aed; }   <-- supera a toda esta capa

   Convención de nomenclatura de tokens
     --{categoría}-{variante}: {valor}
     Categorías: font, color, space, size, radius, border, shadow, motion
   ============================================================================= */

@layer ghost_tokens {

  :root {

    /* == System Configuration ================================================= */

    /* Safe browser default; overridden by unlayered themes */
    /* Configuración por defecto del navegador; anulable por temas sin capas */

    color-scheme: light dark; 

    /* == Typography =========================================================== */

    --font-family-base:       system-ui, -apple-system, BlinkMacSystemFont,
                              'Segoe UI', Roboto, sans-serif;
    --font-family-heading:    inherit;
    --font-family-mono:       ui-monospace, 'Cascadia Code', 'Fira Code',
                              'Consolas', monospace;

    --font-size-base:         1rem;       /* 16px at browser default      */
    --font-size-sm:           0.875rem;   /* 14px                         */
    --font-size-xs:           0.75rem;    /* 12px                         */

    --font-weight-normal:     400;
    --font-weight-medium:     500;
    --font-weight-bold:       600;

    --line-height-base:       1.5;
    --line-height-tight:      1.2;
    --line-height-loose:      1.75;

    --letter-spacing-tight:   -0.015em;
    --letter-spacing-normal:  0em;
    --letter-spacing-wide:    0.05em;

    /* == Color - Neutrals ===================================================== */

    --color-neutral-900:     #0f172a;
    --color-neutral-800:     #1e293b;
    --color-neutral-700:     #334155;
    --color-neutral-600:     #475569;
    --color-neutral-500:     #64748b;
    --color-neutral-400:     #94a3b8;
    --color-neutral-300:     #cbd5e1;
    --color-neutral-200:     #e2e8f0;
    --color-neutral-100:     #f1f5f9;
    --color-neutral-50:      #f8fafc;

    /* == Color - Semantic aliases ============================================= */

    --color-text-primary:    var(--color-neutral-900);
    --color-text-secondary:  var(--color-neutral-600);
    --color-text-muted:      var(--color-neutral-400);
    --color-text-inverse:    #ffffff;

    --color-surface:         #ffffff;
    --color-surface-subtle:  var(--color-neutral-50);
    --color-surface-raised:  #ffffff;

    --color-border:          var(--color-neutral-200);
    --color-border-strong:   var(--color-neutral-300);

    --color-accent:          #0057cc;  /* WCAG AA on white; override freely */
    --color-accent-hover:    #003fa3;
    --color-accent-subtle:   #dbeafe;

    --color-focus-ring:      var(--color-accent);

    /* == Color - State palette ================================================ */

    --color-success:         #16a34a;
    --color-warning:         #d97706;
    --color-error:           #dc2626;
    --color-info:            var(--color-accent);

    /* == Spacing scale (4px base, geometric) ================================== */

    --space-1:               0.25rem;    /*  4px   */
    --space-2:               0.5rem;     /*  8px   */
    --space-3:               0.75rem;    /* 12px   */
    --space-4:               1rem;       /* 16px   */
    --space-5:               1.25rem;    /* 20px   */
    --space-6:               1.5rem;     /* 24px   */
    --space-8:               2rem;       /* 32px   */
    --space-10:              2.5rem;     /* 40px   */
    --space-12:              3rem;       /* 48px   */
    --space-16:              4rem;       /* 64px   */

    /* == Size - Content widths ================================================ */

    --size-content-xs:       20rem;      /* 320px  */
    --size-content-sm:       30rem;      /* 480px  */
    --size-content-md:       45rem;      /* 720px  */
    --size-content-lg:       60rem;      /* 960px  */
    --size-content-xl:       80rem;      /* 1280px */

    /* == Border =============================================================== */

    --border-width-thin:     1px;
    --border-width-base:     2px;

    --radius-sm:             0.25rem;    /*  4px   */
    --radius-md:             0.375rem;   /*  6px   */
    --radius-lg:             0.5rem;     /*  8px   */
    --radius-xl:             0.75rem;    /*  12px  */
    --radius-full:           9999px;

    /* == Shadow =============================================================== */

    --shadow-sm:             0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow-md:             0 4px 6px   -1px  rgb(0 0 0 / 0.07),
                             0 2px 4px   -2px rgb(0 0 0 / 0.05);
    --shadow-lg:             0 10px 15px -3px rgb(0 0 0 / 0.07),
                             0 4px  6px  -4px rgb(0 0 0 / 0.05);
    --shadow-focus:          0 0 0 3px   rgb(0 87 204 / 0.35);

    /* == Motion =============================================================== */

    --duration-instant:      50ms;
    --duration-fast:         150ms;
    --duration-base:         250ms;
    --duration-slow:         400ms;

    --ease-default:          cubic-bezier(0.4, 0, 0.2, 1);  /* Material std  */
    --ease-in:               cubic-bezier(0.4, 0, 1, 1);
    --ease-out:              cubic-bezier(0, 0, 0.2, 1);
    --ease-spring:           cubic-bezier(0.34, 1.56, 0.64, 1);

  }

} /* end @layer ghost_tokens */


/* ==============================================================================
   LAYER 2 | reset
   ==============================================================================
   Purpose
     Erase browser inconsistencies. Zero visual opinions live here.
     Every selector is wrapped in :where() - specificity is (0,0,0).

   What it does NOT do
     - Set colors, fonts, or spacing  --> that is baseline's job.
     - Normalize form appearance      --> that is forms' job.
     - Anything visual                --> zero opinions.
   ============================================================================== */

/* ==============================================================================
   CAPA 2 | reset
   ==============================================================================
   Propósito
     Eliminar las inconsistencias del navegador. Cero opinión visual aquí.
     Cada selector está envuelto en :where() — la especificidad es (0,0,0).

   Lo que NO hace
     - Establecer colores, fuentes o espaciados  --> es trabajo de baseline.
     - Normalizar la apariencia de formularios    --> es trabajo de forms.
     - Nada visual                               --> cero opiniones.
   ============================================================================== */

@layer reset {

  /* == Box model  ============================================================== */
    :where(*, *::before, *::after) {
    box-sizing: border-box;
    /* Prevent margin collapse surprises in unknown contexts */
    margin:     0;
    padding:    0;
  }

  /* == Root ==================================================================== */

  :where(html) {
    /*
     * 100% preserves the user's browser font-size preference.
     * Never set a px value here - it overrides user accessibility settings.
     */
    
    /*
     * Preserva al 100% la preferencia de tamaño de fuente del navegador del usuario.
     * Nunca establezcas un valor en px aquí — anula la configuración de accesibilidad del usuario.
     */
    
    font-size:      100%;
    tab-size:       4;

    /*
     * text-wrap: pretty   -->  avoids single-word orphan lines in paragraphs.
     * overflow-wrap       -->  long unbroken strings (URLs, code) wrap rather
     *                          than overflow their container.
     */
    
    /*
     * text-wrap: pretty   -->  evita líneas huérfanas de una sola palabra en los párrafos.
     * overflow-wrap       -->  las cadenas largas sin espacios (URLs, código) se parten
     *                          en lugar de desbordar su contenedor.
     */    
    
    text-wrap:      pretty;
    overflow-wrap:  anywhere;
    /*
     * Prevents a 300ms tap delay on mobile without disabling zoom.
     * touch-action: manipulation is the modern, safe approach.
     */

    /*
     * Previene el retraso de pulsación de 300ms en móviles sin deshabilitar el zoom.
     * touch-action: manipulation es el enfoque moderno y seguro.
     */

    touch-action:   manipulation;
  }

  /* == Block flow elements ====================================================== */

  /* dvb = dynamic viewport block - safe on mobile  */

  /* dvb = dynamic viewport block — seguro en móviles */
  :where(body) {
    min-block-size: 100dvb; 
  }

  :where(h1, h2, h3, h4, h5, h6) {
    /*
     * text-wrap: balance --> distributes text evenly across heading lines,
     * preventing a single word on the last line (orphan).
     * Browsers apply this heuristically; no JS needed.
     */

    /*
     * text-wrap: balance --> distribuye el texto uniformemente en las líneas del encabezado,
     * evitando una sola palabra en la última línea (huérfana).
     * Los navegadores lo aplican de forma heurística; no requiere JS.
     */

    text-wrap: balance;
  }

  :where(ul, ol) {
    list-style: none;
  }

  :where(address) {
    font-style: normal;
  }

  /* == Media ====================================================================== */

  :where(img, picture, video, canvas, svg) {
    display:   block;
    max-width: 100%;
  }

  /*
     * height: auto preserves the intrinsic aspect ratio when only
     * width is constrained (e.g. max-width: 100%).
     */
  
  /*
     * height: auto preserva la relación de aspecto intrínseca cuando solo
     * se limita el ancho (por ejemplo, max-width: 100%).
     */

  :where(img, video) {
    height:         auto;
  }

  /*
     * Removes implicit extra space beneath inline SVGs.
     * Redundant with display:block above but explicit for clarity.
     */

  /*
     * Elimina el espacio extra implícito debajo de los SVGs inline.
     * Redundante con display: block arriba, pero explícito por claridad.
     */

  :where(svg) {
    overflow:       hidden;
  }

  /* == Typography primitives ====================================================== */

  /* Relative to parent; avoids hardcoding 700 */

  /* Relativo al contenedor padre; evita escribir 700 en código duro */

  :where(b, strong) {
    font-weight:    bolder; 
  }

  :where(small) {
    font-size:      80%;
  }

  :where(sub, sup) {
    font-size:      75%;
    line-height:    0;
    position:       relative;
    vertical-align: baseline;
  }

  :where(sub) { inset-block-end:   -0.25em; }
  :where(sup) { inset-block-start: -0.5em;  }

  /* == Links ===================================================================== */

  /*
     * Inherits color from parent by default so links inside colored
     * containers (cards, callouts) adopt context naturally.
     * baseline layer applies the actual link color.
     */

  /*
     * Hereda el color del padre por defecto para que los enlaces dentro de
     * contenedores con color (tarjetas, llamadas) adopten el contexto de forma natural.
     * La capa baseline aplica el color de enlace real.
     */

  :where(a) {
    color:           inherit;
    text-decoration: inherit;
  }

  /* == Tables ==================================================================== */

  :where(table) {
    border-collapse: collapse;
    border-spacing:  0;
  }

  /* Logical property - RTL-safe */

  /* Propiedad lógica — segura para RTL */

  :where(th) {
    font-weight: inherit;
    text-align:  start; 
  }

  /* == Horizontal rule ============================================================ */

  :where(hr) {
    height:     0;
    border:     0;
    overflow:   visible;
  }

  /* == Embeds ===================================================================== */

  :where(iframe, embed, object) {
    display:    block;
    max-width:  100%;
    border:     0;
  }

  /* == Dialogs ==================================================================== */

  /*
     * Browsers ship <dialog> with a 2px border and UA margin.
     * Reset here; baseline or your theme styles the visual treatment.
     */

  /*
     * Los navegadores entregan <dialog> con un borde de 2px y un margen de agente de usuario.
     * Se restablece aquí; la capa baseline o tu tema definen el tratamiento visual.
     */

  :where(dialog) {
    border:     0;
    padding:    0;
    max-width:  100%;
    max-height: 100%;
  }

  /* == Hidden attribute =========================================================== */

  /*
     * !important is justified here: [hidden] is a semantic HTML attribute
     * whose sole purpose is to hide elements. It must never be overridden
     * by cascade accidents. This is the only !important in quell-base.css.
     */

  /*
     * !important está justificado aquí: [hidden] es un atributo HTML semántico
     * cuyo único propósito es ocultar elementos. Nunca debe ser anulado
     * por accidentes en la cascada. Este es el único !important en quell-base.css.
     */

  :where([hidden]) {
    display:    none !important;
  }

} /* end @layer reset */


/* ================================================================================
   LAYER 3 | baseline
   ================================================================================
   Purpose
     Apply minimal, intentional visual design by consuming ghost tokens.
     This is the layer that makes quell-base.css look like something, not just reset.

   Specificity contract
     :where() throughout --> (0,0,0). Exception: :focus-visible (see note).

   Relationship to reset
     reset erases; baseline builds. They must not duplicate rules.
   ================================================================================ */

  /* ================================================================================
   CAPA 3 | baseline
   ================================================================================
   Propósito
     Aplicar un diseño visual mínimo e intencional consumiendo los ghost tokens.
     Esta es la capa que hace que quell-base.css tenga un aspecto propio, no solo un reset.

   Contrato de especificidad
     Uso de :where() en todo el bloque --> (0,0,0). Excepción: :focus-visible (ver nota).

   Relación con reset
     reset borra; baseline construye. No deben duplicar reglas.
   ================================================================================ */

@layer baseline {

  /* == Body ====================================================================== */

  :where(body) {
    font-family:             var(--font-family-base);
    font-size:               var(--font-size-base);
    font-weight:             var(--font-weight-normal);
    line-height:             var(--line-height-base);
    color:                   var(--color-text-primary);
    background-color:        var(--color-surface);
    -webkit-font-smoothing:  antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  /* == Headings =================================================================== */

  :where(h1, h2, h3, h4, h5, h6) {
    font-family:             var(--font-family-heading);
    font-weight:             var(--font-weight-bold);
    line-height:             var(--line-height-tight);
    letter-spacing:          var(--letter-spacing-tight);
    color:                   var(--color-text-primary);
  }

  /* == Links ====================================================================== */

  :where(a) {
    color:                     var(--color-accent);
    text-decoration:           underline;
    text-decoration-color:     color-mix(in srgb, var(--color-accent) 40%, transparent);
    text-underline-offset:     0.2em;
    text-decoration-thickness: var(--border-width-thin);
    transition:
      color                    var(--duration-fast) var(--ease-default),
      text-decoration-color    var(--duration-fast) var(--ease-default);

    &:hover {
      color:                   var(--color-accent-hover);
      text-decoration-color:   var(--color-accent-hover);
    }

    /*
       * visited styling is intentionally minimal. Full override via
       * @layer baseline { :where(a:visited) { } } in your theme.
       */

    /*
       * El estilo de visited es intencionalmente mínimo. Anulación completa mediante
       * @layer baseline { :where(a:visited) { } } en tu tema.
       */

    &:visited {
      color: var(--color-text-secondary);
    }
  }

  /* == Horizontal rule ============================================================= */

  :where(hr) {
    border-block-start: var(--border-width-thin) solid var(--color-border);
    margin-block:       var(--space-8);
  }

  /* == Code & preformatted ========================================================= */

  :where(code, kbd, samp, pre) {
    font-family:      var(--font-family-mono);
    font-size:        var(--font-size-sm);
  }

  /*
     * Inline code only (not code inside pre).
     * :not(:where()) avoids double-applying to pre > code.
     */

    /*
     * Solo código inline (no código dentro de pre).
     * :not(:where()) evita la doble aplicación en pre > code.
     */

  :where(code):not(:where(pre) :where(code)) {
    background-color: var(--color-surface-subtle);
    border:           var(--border-width-thin) solid var(--color-border);
    border-radius:    var(--radius-sm);
    padding-block:    0.1em;
    padding-inline:   0.35em;
    color:            var(--color-text-primary);
  }

  :where(pre) {
    overflow-x:       auto;
    padding:          var(--space-4);
    background:       var(--color-neutral-900);
    color:            var(--color-neutral-100);
    border-radius:    var(--radius-lg);
    tab-size:         2;

    :where(code) {
      background:     transparent;
      border:         0;
      padding:        0;
      color:          inherit;
      font-size:      inherit;
    }
  }

  /* == Blockquote ================================================================= */

  :where(blockquote) {
    border-inline-start:    var(--border-width-base) solid var(--color-border-strong);
    padding-inline-start:   var(--space-4);
    color:                  var(--color-text-secondary);
    font-style:             italic;
  }

  /* == Lists (opt-in restoration) ================================================= */

  /*
   * reset removes list styles globally for layout safety.
   * Here we restore them for prose-context lists:
   * semantic lists inside articles, sections, or .prose wrappers.
   */

  /*
   * reset elimina los estilos de lista globalmente por seguridad en el diseño.
   * Aquí se restauran para listas en contexto de prosa:
   * listas semánticas dentro de articles, sections o contenedores .prose.
   */

  :where(article, section, .prose) {
    :where(ul) {
      list-style:           disc;
      padding-inline-start: var(--space-6);
    }

    :where(ol) {
      list-style:           decimal;
      padding-inline-start: var(--space-6);
    }
  }

  /* == Tables ===================================================================== */

  :where(table) {
    width:            100%;
    font-size:        var(--font-size-sm);
  }

  :where(th, td) {
    padding-block:    var(--space-2);
    padding-inline:   var(--space-3);
    text-align:       start;
    border-block-end: var(--border-width-thin) solid var(--color-border);
  }

  :where(th) {
    font-weight:      var(--font-weight-bold);
    color:            var(--color-text-primary);
    background:       var(--color-surface-subtle);
  }

  /* == Selection =================================================================== */

  ::selection {
    background-color: var(--color-accent-subtle);
    color:            var(--color-text-primary);
  }

  /* == Focus visible =============================================================== */

  /*
   * INTENTIONAL: :focus-visible is NOT wrapped in :where().
   * Specificity is (0,1,0). This is a deliberate safety choice.
   *
   * Rationale: focus rings are a critical accessibility mechanism.
   * A slightly elevated specificity prevents them from being silently
   * suppressed by a cascade accident in a downstream stylesheet.
   * To override, use :focus-visible { } in your own unlayered sheet,
   * which beats this layer regardless of selector weight.
   */

   /*
   * INTENCIONAL: :focus-visible NO está envuelto en :where().
   * La especificidad es (0,1,0). Esta es una decisión de seguridad deliberada.
   *
   * Justificación: los anillos de enfoque son un mecanismo crítico de accesibilidad.
   * Una especificidad ligeramente elevada evita que sean silenciados o anulados
   * accidentalmente por la cascada en una hoja de estilos posterior.
   * Para anularlo, usa :focus-visible { } en tu propia hoja sin capas (unlayered),
   * la cual prevalece sobre esta capa independientemente del peso del selector.
   */

  :focus-visible {
    outline:         var(--border-width-base) solid var(--color-focus-ring);
    outline-offset:  var(--space-1);
    border-radius:   var(--radius-sm);
    box-shadow:      var(--shadow-focus);
  }

  /*
   * Suppress focus ring for pointer users; preserve for keyboard users.
   * :focus-visible already handles this natively, but the explicit
   * :focus:not(:focus-visible) rule eliminates the ring in older Chromium.
   */

   /*
   * Suprime el anillo de enfoque para usuarios de puntero; lo preserva para usuarios de teclado.
   * :focus-visible ya maneja esto de forma nativa, pero la regla explícita
   * :focus:not(:focus-visible) elimina el anillo en versiones antiguas de Chromium.
   */

  :focus:not(:focus-visible) {
    outline:         none;
    box-shadow:      none;
  }

  /* == Reduced motion =============================================================== */

  /*
   * quell-base.css itself uses no animations, but this preference query is placed
   * here so downstream utilities that append to the utilities layer
   * can reference it or know it is already present in the baseline.
   */
  
  /*
   * quell-base.css en sí no utiliza animaciones, pero esta consulta de preferencia se coloca
   * aquí para que las utilidades posteriores que se añadan a la capa de utilidades (utilities)
   * puedan hacer referencia a ella o saber que ya está presente en la capa baseline.
   */
  
  @media (prefers-reduced-motion: reduce) {
    :where(*, *::before, *::after) {
      animation-duration:        0.01ms !important;
      animation-iteration-count: 1      !important;
      transition-duration:       0.01ms !important;
      scroll-behavior:           auto   !important;
    }
  }

} /* end @layer baseline */


/* ==================================================================================
   LAYER 4 | forms
   ==================================================================================
   Purpose
     2026-era form normalization. Isolated from baseline so that headless UI
     libraries (Radix, Shoelace, Ark, etc.) can re-declare this entire layer
     without touching reset or baseline.

   What "normalization" means here
     -  Inherit document font (browsers don't do this by default for inputs)
     -  Normalize cross-browser appearance quirks
     -  Provide accessible defaults for state (disabled, invalid, readonly)
     -  No visual opinions beyond what is required for usability

   Specificity
     :where() throughout --> (0,0,0). All overridable with a plain selector.
   ================================================================================== */

   /* ==================================================================================
   CAPA 4 | forms
   ==================================================================================
   Propósito
     Normalización de formularios para la era de 2026. Aislada de baseline para que las
     librerías de UI headless (Radix, Shoelace, Ark, etc.) puedan volver a declarar
     esta capa completa sin alterar reset o baseline.

   Qué significa "normalización" aquí
     - Heredar la fuente del documento (los navegadores no hacen esto por defecto en los inputs)
     - Normalizar las peculiaridades de apariencia entre navegadores
     - Proveer estados por defecto accesibles (disabled, invalid, readonly)
     - Sin opiniones visuales más allá de lo requerido para la usabilidad

   Especificidad
     Uso de :where() en todo el bloque --> (0,0,0). Todo es anulable con un selector simple.
   ================================================================================== */

@layer forms {

  /* == Font inheritance ============================================================ */

  /*
     *  'font: inherit' is shorthand for: font-family, font-size,
     *  font-style, font-variant, font-weight, and line-height.
     *  Browsers do not inherit these on form elements by default.
     */

  /*
     * 'font: inherit' es el atajo para: font-family, font-size,
     * font-style, font-variant, font-weight y line-height.
     * Los navegadores no heredan estas propiedades en los elementos de formulario por defecto.
     */

  :where(button, input, optgroup, select, textarea) {
    font:     inherit;
    color:    inherit;
    margin:   0;
  }

  /* == Buttons ===================================================================== */

  :where(button, [type="button"], [type="reset"], [type="submit"]) {
    /*
     * appearance: none removes platform button chrome.
     * cursor: pointer is an expected affordance.
     */
    
    /*
     * appearance: none elimina el acabado por defecto del botón de la plataforma.
     * cursor: pointer es una pista visual esperada de interactividad.
     */
    appearance:          none;
    cursor:              pointer;
    border:              0;
    background:          transparent;
    padding:             0;
    /*
     * touch-action: manipulation removes the 300ms tap delay on iOS
     * without disabling pinch-zoom.
     */

    /*
     * touch-action: manipulation elimina el retraso de 300 ms al pulsar en iOS
     * sin deshabilitar el zoom de pellizco (pinch-zoom).
     */
    touch-action:        manipulation;
    user-select:         none;
    -webkit-user-select: none;
  }

  /* == Text inputs ================================================================= */

  :where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
         select, textarea) {
    appearance:          none;
    -webkit-appearance:  none;
    border-radius:       0;    /* Overrides iOS rounded inputs */ /* Anula los inputs redondeados en iOS */
  }

  /* == Textarea ==================================================================== */

  :where(textarea) {
    resize:         vertical;
    /*
     * min-block-size: 3lh - "3 line heights" using the lh unit (2023+).
     * Falls back gracefully in older browsers (property ignored, textarea
     * uses its UA default height).
     */

    /*
     * min-block-size: 3lh - "3 alturas de línea" usando la unidad lh (2023+).
     * Se degrada elegantemente en navegadores antiguos (la propiedad se ignora,
     * el textarea usa su altura por defecto de agente de usuario).
     */
    min-block-size: 3lh;

    /* Cleans up unnecessary track lines in strict layout environments */
    /* Elimina las líneas de carril innecesarias en entornos de diseño estrictos */
    overflow: auto;
  }

  /* == Select ====================================================================== */

  /* Restores truncated text in selects on some platforms.*/
  /* Restaura el texto truncado en los selects en algunas plataformas.*/
  :where(select) {
    max-width:      100%;
  }

  /* == Checkbox & Radio ============================================================ */

  :where(input[type="checkbox"],
         input[type="radio"]) {
    /*
     * accent-color applies the brand color to the checked state
     * indicator, the radio dot, and the checkmark — without custom
     * widget engineering. Supported in all modern browsers.
     */

    /*
     * accent-color aplica el color de la marca al indicador del estado marcado,
     * al punto de los inputs de tipo radio y a la casilla de verificación (checkmark),
     * sin necesidad de maquetar componentes a medida. Soportado en todos los navegadores modernos.
     */
    accent-color:  var(--color-accent);
    width:          1rem;
    height:         1rem;
    cursor:         pointer;
    /* Prevents collapse in flex label layouts */
    /* Evita el colapso en layouts de etiquetas con flexbox */
    flex-shrink:    0;
  }

  :where(input[type="radio"]) {
    border-radius:  var(--radius-full);
  }

  /* == Range ======================================================================== */

  :where(input[type="range"]) {
    accent-color:   var(--color-accent);
    cursor:         pointer;
    width:          100%;
  }

  /* == Color picker  ================================================================ */

  :where(input[type="color"]) {
    cursor:         pointer;
    block-size:     2rem;
    inline-size:    3rem;
    padding:        var(--space-1);
    border-radius:  var(--radius-sm);
  }

  /* == Fieldset & Legend ============================================================ */

  :where(fieldset) {
    /*
     * Browsers apply 2px border and non-zero padding/margin to fieldset.
     * Resetting here lets your theme control the visual grouping.
     */
    /*
     * Los navegadores aplican un borde de 2px y un padding/margin que no es cero a los fieldset.
     * Restablecerlo aquí permite que tu tema controle la agrupación visual.
     */
    border:          0;
    padding:         0;
    margin:          0;
    /*
     * min-inline-size: 0 — critical fix. Browsers set min-inline-size
     * to min-content on fieldset, which causes flex/grid overflow.
     */
    /*
     * min-inline-size: 0 — corrección crítica. Los navegadores establecen min-inline-size
     * como min-content en los fieldset, lo que provoca desbordamientos (overflow) en flex/grid.
     */
    min-inline-size: 0;
  }

  :where(legend) {
    padding:         0;
    max-width:       100%;
  }

  /* == Label ======================================================================== */

  :where(label) {
    cursor:          pointer;
  }

  /* == Progress & Meter ============================================================= */

  :where(progress, meter) {
    vertical-align:  middle;
    accent-color:    var(--color-accent);
  }

  /* == Output ======================================================================= */

  :where(output) {
    display:        block;
    font-size:      var(--font-size-sm);
    color:          var(--color-text-secondary);
  }

  /* == State: Disabled ============================================================== */

  :where([disabled], [aria-disabled="true"]) {
    cursor:         not-allowed;
    opacity:        0.55;
  }

  /*
   * Fieldsets can disable all children. The above rule doesn't cascade
   * into children so we target the fieldset itself.
   */
   /*
   * Los fieldsets pueden deshabilitar a todos sus hijos. La regla anterior no se aplica
   * en cascada hacia los hijos, por lo que apuntamos al propio fieldset.
   */
  :where(fieldset[disabled]) :where(button, input, select, textarea, label) {
    cursor:         not-allowed;
    pointer-events: none;
  }

  /* == State: Read-only ============================================================== */

  :where(input[readonly], textarea[readonly]) {
    cursor: default;
  }

  /* == State: Invalid ================================================================ */

  /*
   * :user-invalid fires only after user interaction (2023+).
   * :invalid fires immediately on page load if a required field is empty,
   * which causes false-positive visual errors before the user types.
   * Prefer :user-invalid for UX. Both are listed for progressive enhancement.
   */
   /*
   * :user-invalid se activa solo después de la interacción del usuario (2023+).
   * :invalid se activa inmediatamente al cargar la página si un campo requerido está vacío,
   * lo que causa falsos positivos de errores visuales antes de que el usuario escriba.
   * Se prefiere :user-invalid por UX. Ambos se listan para mejora progresiva.
   */
  :where(input:user-invalid, textarea:user-invalid, select:user-invalid) {
    accent-color: var(--color-error);
  }

  /* == Search input normalization ==================================================== */

  :where(input[type="search"]) {
    /* Removes the native 'x' clear button on WebKit */
    /* Elimina el botón nativo de limpieza 'x' en WebKit */
    &::-webkit-search-decoration,
    &::-webkit-search-cancel-button { appearance: none; }
  }

  /* == Number input normalization ==================================================== */

  :where(input[type="number"]) {
    /* Removes spinner arrows - rarely useful, always inconsistent */
    /* Elimina las flechas del spinner — rara vez son útiles, siempre son inconsistentes */
    appearance: textfield;
    &::-webkit-inner-spin-button,
    &::-webkit-outer-spin-button { display: none; }
  }

} /* end @layer forms */


/* ====================================================================================
   LAYER 5 | utilities
   ====================================================================================
   Purpose
     Reserved slot. Intentionally empty in quell-base.css core.

   For downstream systems
     Atomic utility classes appended to this layer automatically win over
     all quell-base.css layers below, because layer priority = declaration order.
     No specificity hacks needed.

     Example (in your theme or utility sheet):
       @layer utilities {
         .sr-only   { position: absolute; width: 1px; ... }
         .truncate  { overflow: hidden; text-overflow: ellipsis; ... }
       }
   =================================================================================== */

   /* ====================================================================================
   CAPA 5 | utilities
   ====================================================================================
   Propósito
     Espacio reservado. Intencionalmente vacío en el núcleo de quell-base.css.

   Para sistemas posteriores (downstream)
     Las clases de utilidad atómicas que se añadan a esta capa prevalecerán automáticamente
     sobre todas las capas inferiores de quell-base.css, ya que la prioridad de las capas
     se define por el orden de declaración. No se necesitan trucos de especificidad.

     Ejemplo (en tu tema u hoja de utilidades):
       @layer utilities {
         .sr-only   { position: absolute; width: 1px; ... }
         .truncate  { overflow: hidden; text-overflow: ellipsis; ... }
       }
   =================================================================================== */

@layer utilities {
  /* intentionally empty — reserved for downstream use */
  /* intencionalmente vacío — reservado para uso posterior */
}


/* ==================================================================================
   End of quell-base.css
   ================================================================================== */
