6. PWA con listas y Material Design 3 Expressive

Versión para imprimir.

A. Introduccion

B. Referencias

Sitios de Material Design
Material.io

Material Design es una guía de diseño para aplicaciones multiplataforma. La encuentras en https://m3.material.io/.

Herramienta para selección de colores
Material Theme Builder

https://material-foundation.github.io/material-theme-builder/

Adaptación multiplataforma

La forma de adaptar Material Design en distintas plataformas está en https://material.io/design/platform-guidance/cross-platform-adaptation.html

C. Hazlo funcionar (con videos)

  1. Prueba e instala, de preferencia con Chrome, el sitio https://gilpgpwal.github.io/.

  2. Descarga el archivo /src/pwalista.zip y descompáctalo.

  3. Crea una cuenta de email con el nombre de tu sitio, por ejemplo, miapp@google.com

  4. Crea una cuenta de GitHub usando el email anterior y selecciona el nombre de usuario unsando la parte inicial del correo electrónico, por ejemplo miapp.

  5. Crea un repositorio nuevo. En el nombre del repositorio debes poner el nombre de tu cuenta seguido por .github.io; por ejemplo miapp.github.io

  6. Importa el proyecto de GitHub a Visual Studio Code

  7. Edita los archivos que desees.

  8. El archivo sw.js tiene una lista de los archivos que se instalan. El archivo instruccionesListadoSw.txt te indica como generarla usando Visual Studio Code.

  9. Crea los íconos del proyecto con https://www.photopea.com/.

  10. Crea los íconos enmascarables con https://maskable.app/ a partir del archivo «icono2048.png».

  11. Coloca el archivo favicon.ico en la raíz del proyecto.

  12. Coloca los otros íconos en la carpeta img y asegúrate de que estén declarados en el archivo site.webmanifest.

  13. El archivo sw.js tiene una lista de los archivos que se instalan. El archivo instruccionesListadoSw.txt te indica como generarla usando Visual Studio Code.

  14. Cada vez que modifiques los archivos, debes modificar el valor de VERSION en el archivo sw.js para poder ver los cambios en el navegador.

  15. Prueba tu PWA.

  16. Publica tu PWA.

  17. Instala y usa tu PWA en Windows. Aunque en este video se recomienda usar Edge, al momento de actualizar el contenido, la opción más recomendada es Chrome para que te muestre las descripciones y las capturas de pantalla.

  18. Instala y usa tu PWA en Android. Al momento de actualizar las notas, tal vez no te aparezca el botón para instalar y tengas que seleccionar la acción de agregar a la pantalla principal que aparece en el menú de extensión de Chrome.

  19. Instala y usa tu PWA en iOS (iPhone y iPad).

D. Hazlo funcionar (texto)

  1. Prueba e instala, de preferencia con Chrome, el sitio https://gilpgpwal.github.io/.

  2. Descarga el archivo /src/pwalista.zip y descompáctalo.

  3. Crea tu proyecto en GitHub pages:

    1. Crea una cuenta de email con el nombre de tu sitio, por ejemplo, miapp@google.com

    2. Crea una cuenta de GitHub usando el email anterior y selecciona el nombre de usuario unsando la parte inicial del correo electrónico, por ejemplo miapp.

    3. Crea un repositorio nuevo. En la página principal de GitHub cliquea 📘 New.

    4. En la página Create a new repository introduce los siguientes datos:

      • Proporciona el nombre de tu repositorio debajo de donde dice Repository name *. Debes usar el nombre de tu cuenta seguido por .github.io; por ejemplo miapp.github.io

      • Mantén la selección Public.

      • Verifica la casilla Add a README file. En este archivo se muestra información sobre tu proyecto.

      • Cliquea License: None. y selecciona la licencia que consideres más adecuada para tu proyecto.

      • Cliquea Create repository.

    5. Entra al repositorio y selecciona ⚙️ Settings, luego selecciona 📁 Pages y en la sección Branches selecciona la carpeta donde se ubicará la carpeta. De preferencia selecciona / (root) para que coloques la página en la raíz del proyecto. Si haces cambios, clic en Save.

    6. En la misma pestaña de ⚙️ Settings selecciona ◯ Actions, luego selecciona General y en Actions permissions selecciona el rediobotón Allow xxxx, and select non-xxxx, actions and reusable workflows y abajo la casilla de verificación Allow actions created by GitHub y cliquea el botón Save.

  4. Importa el proyecto de GitHub a Visual Studio Code:

    1. En la página principal de tu proyecto en GitHub, en la pestaña < > Code, cliquea < > Code y en la sección Branches y copia la dirección que está en HTTPS, debajo de Clone.

    2. En Visual Studio Code, usa el botón de la izquierda para Source Control.

      Imagen de Source Control
    3. Cliquea el botón Clone Repository.

    4. Pega la url que copiaste anteriormente hasta arriba, donde dice algo como Provide repository URL y presiona la teclea Intro.

    5. Selecciona la carpeta donde se guardará la carpeta del proyecto.

    6. Abre la carpeta del proyecto importado.

    7. Añade el contenido de la carpeta descompactada que contiene el código del ejemplo, excepto el archivo .htaccess.

  5. Edita los archivos que desees.

  6. Crea los íconos del proyecto con https://www.photopea.com/.

  7. Crea los íconos enmascarables con https://maskable.app/ a partir del archivo «icono2048.png».

  8. Coloca el archivo favicon.ico en la raíz del proyecto.

  9. Coloca los otros íconos en la carpeta img y asegúrate de que estén declarados en el archivo site.webmanifest.

  10. El archivo sw.js tiene una lista de los archivos que se instalan. El archivo instruccionesListadoSw.txt te indica como generarla usando Visual Studio Code.

  11. Cada vez que modifiques los archivos, debes modificar el valor de VERSION en el archivo sw.js para poder ver los cambios en el navegador.

  12. Haz clic derecho en index.html, selecciona Open with Live Server y se abre el navegador para que puedas probar localmente el ejemplo.

  13. Haz al menos una captura de la ventana de tu aplicación con orientación vertical y otra con orientación horizontal, todas ellas de 320 px como mínimo y 3,840 px como máximo.

  14. Coloca las capturas en la carpeta img y asegúrate de que estén declaradas en el archivo site.webmanifest.

  15. Cuando desarrolles, es incómodo modificar la versión cada que realizas cambios; en vez de ello desinstala la app:

    1. Abre las herramientas de depuración haciendo clic derecho en la página y selecciona Inspeccionar (o Inspect si aparece en inglés).

    2. En la Pestaña Aplicación (o Application en inglés) selecciona Almacenamoento (o Storage en inglés). Cliquea Borrar datos del sitio.

    3. Recarga la app, de preferencia haciendo clic derecho en el ícono de volver a cargar la página Ïmagen del ícono de recarga y seleccionando vaciar caché y volver a cargar de manera forzada (o algo parecido). Si no aparece un menú emergente, simplemente cliquea volver a cargar la página Ïmagen del ícono de recarga. Revisa que no aparezca ningún error ni en la pestañas Consola, ni en Red.

    4. Tanbién puedes usar la combinación de teclas Ctrl+Mayúsculas+r para forzar que se actualice temporalmente el navegador en caso de que no se vean los cambios.

    5. En la Pestaña Aplicación (o Application en inglés) selecciona Archivo de manifiesto (o Manifest file en inglés). Esta herramienta analiza la estructura del archivo de manifiesto y te indica si hay un error.

    6. En la Pestaña Aplicación (o Application en inglés) selecciona Almacenamiento en caché (o Cache storage en inglés). Aquí puedes revisar si el caché de la aplicación se llenó correctamente. En caso de que esté vacío, es que hubo algún error durante la carga y la app se ejecuta más lenta.

  16. Cuando usas GitHub pages, antes de subir los archivos, no debes modificar el valor de VERSION en el archivo sw.js.

  17. Para subir el código a GitHub, en la sección de SOURCE CONTROL, en Message introduce un mensaje sobre los cambios que hiciste, por ejemplo index.html corregido, selecciona v y luego Commit & Push.

    Imagen de Commit & Push
  18. Si usas GitHub pages:

    1. Entra a la página de tu repositorio y abajo a la derecha, selecciona el enlace github-pages.

    2. Se muestran los despliegues realizados. Recarga la página hasta que apareca el mensaje de tu último push con una palomita dentro de un círculo verde.

    3. A partir de este momento, espera al menos 11 minutos para modificar el valor de VERSION en el archivo sw.js y volver a subir el proyecto.

  19. Instala y usa tu PWA en Windows. Aunque en este video se recomienda usar Edge, al momento de actualizar el contenido, la opción más recomendada es Chrome para que te muestre las descripciones y las capturas de pantalla.

  20. Instala y usa tu PWA en Android. Al momento de actualizar las notas, tal vez no te aparezca el botón para instalar y tengas que seleccionar la acción de agregar a la pantalla principal que aparece en el menú de extensión de Chrome.

  21. Instala y usa tu PWA en iOS (iPhone y iPad).

E. Archivos

Haz clic en los triángulos para expandir las carpetas

F. index.html

1
<!DOCTYPE html>
2
<html lang="es" class="light dark">
3
4
<head>
5
6
 <meta charset="UTF-8">
7
8
 <title>PWA con Lista</title>
9
10
 <!-- Resumen para los motores de búsqueda. -->
11
 <meta name="description" content="Ejemplo de PWA con Material Design">
12
13
 <script type="module" src="js/lib/registraServiceWorker.js"></script>
14
15
 <meta name="viewport" content="width=device-width">
16
17
 <!-- Color de la barra de navegación de Chrome en dispositivos móviles. -->
18
 <meta name="theme-color" content="#fffbfe">
19
20
 <!-- Ícono para la página web, que normalmente se pone en la raíz del sitio.
21
  Puede ser diferente para cada página. -->
22
 <link rel="icon" sizes="32x32" href="favicon.ico">
23
24
 <!-- Configuración de la PWA para Chrome, Edge y Safari.
25
  Debe ponerse en todas las páginas. -->
26
 <link rel="manifest" href="site.webmanifest">
27
28
 <!-- Permite a los navegadores, que como Safari no soportan el estándar
29
  completo de custom elementsm, lo cumplan totalmente. Debe ponerse en todas
30
  las páginas. -->
31
 <script src="ungap/custom-elements.js"></script>
32
33
 <script type="module" src="js/lib/custom/md-app-bar.js"></script>
34
 <script type="module" src="js/nav-tab-fixed.js"></script>
35
36
 <link rel="stylesheet" href="css/estilos.css">
37
 <link rel="stylesheet" href="css/transicion_pestanas.css">
38
 <link rel="stylesheet" href="css/md-tab.css">
39
 <link rel="stylesheet" href="css/material-symbols-outlined.css">
40
 <link rel="stylesheet" href="css/md-list.css">
41
42
</head>
43
44
<body>
45
46
 <md-app-bar class="centered" adicional="tab">
47
48
  <h1>PWA con Lista</h1>
49
50
 </md-app-bar>
51
52
 <nav-tab-fixed id="tab"></nav-tab-fixed>
53
54
 <section>
55
56
  <ul class="md-list">
57
58
   <li class="md-one-line">
59
    <span class="headline">
60
     Ciudad de México
61
    </span>
62
   </li>
63
64
   <li class="md-one-line">
65
    <span class="headline">
66
     Lorem ipsum dolor sit amet consectetur adipisicing elit.
67
     Laboriosam eaque unde voluptates tempore ad suscipit libero, saepe neque
68
     illo amet, eos ea similique quia, maiores tenetur modi nobis expedita
69
     alias!
70
    </span>
71
   </li>
72
73
   <li class="md-one-line icon">
74
    <span class="material-symbols-outlined">account_balance</span>
75
    <span class="headline">
76
     Atenas
77
    </span>
78
   </li>
79
80
   <li class="md-one-line avatar">
81
    <img alt="Avatar de Ana" src="img/pexels-moises-patrício-10961948.jpg">
82
    <span class="headline">
83
     Ana
84
    </span>
85
   </li>
86
87
   <li class="md-one-line image">
88
    <img alt="Coyote de Neza" src="img/Escultura_de_coyote.jpeg">
89
    <span class="headline">
90
     Neza
91
    </span>
92
   </li>
93
94
   <li class="md-one-line video">
95
    <img alt="Ciudad de San Francisco"
96
      src="img/pexels-craig-dennis-3701822.jpg">
97
    <span class="headline">
98
     San Francisco
99
    </span>
100
   </li>
101
102
   <li class="md-one-line video">
103
    <img alt="Ciudad de San Francisco"
104
      src="img/pexels-craig-dennis-3701822.jpg">
105
    <span class="headline">
106
     Lorem ipsum dolor sit amet consectetur adipisicing elit.
107
     Laboriosam eaque unde voluptates tempore ad suscipit libero, saepe neque
108
     illo amet, eos ea similique quia, maiores tenetur modi nobis expedita
109
    </span>
110
   </li>
111
112
   <li>
113
    <a class="md-one-line image" target="_blank" rel="noopener noreferrer"
114
      href="https://culturacolectiva.com/historia/ciudad-neza-su-historia-en-fotografias/">
115
     <img alt="Coyote de Neza" src="img/Escultura_de_coyote.jpeg">
116
     <span class="headline">
117
      Neza Link
118
     </span>
119
    </a>
120
   </li>
121
122
  </ul>
123
124
  <footer>
125
   <ul>
126
    <li>
127
     <p>
128
      <small>
129
       <a target="_blank" rel="noopener noreferrer"
130
         href="https://www.pexels.com/es-es/foto/nina-mono-cara-sonriente-10961948/">
131
        La foto de la niña es de Moises Patrício, publicada en el sitio Pexels.
132
        Haz clic en este hipervínculo para más información.
133
       </a>
134
      </small>
135
     </p>
136
    </li>
137
    <li>
138
     <p>
139
      <small>
140
       <a target="_blank" rel="noopener noreferrer"
141
         href="https://www.pinterest.com.mx/ludresi/">
142
        La foto del Coyote de Neza es de Ludres Isan, publicada en el sitio
143
        Pinterest. Haz clic en este hipervínculo para más información.
144
       </a>
145
      </small>
146
     </p>
147
    </li>
148
    <li>
149
     <p>
150
      <small>
151
       <a target="_blank" rel="noopener noreferrer"
152
         href="https://www.pexels.com/es-es/foto/puente-golden-gate-san-francisco-california-3701822/">
153
        La foto del puente de San Francisco es de Craig Dennis, publicada en el
154
        sitio Pexels. Haz clic en este hipervínculo para más información.
155
       </a>
156
      </small>
157
     </p>
158
    </li>
159
   </ul>
160
  </footer>
161
162
 </section>
163
164
</body>
165
166
</html>

G. ayuda.html

1
<!DOCTYPE html>
2
<html lang="es" class="light dark">
3
4
<head>
5
6
 <meta charset="UTF-8">
7
8
 <title>Ayuda - PWA con Lista</title>
9
10
 <script type="module" src="js/lib/registraServiceWorker.js"></script>
11
12
 <meta name="viewport" content="width=device-width">
13
 <meta name="theme-color" content="#fffbfe">
14
 <link rel="icon" sizes="32x32" href="favicon.ico">
15
 <link rel="manifest" href="site.webmanifest">
16
 <script src="ungap/custom-elements.js"></script>
17
18
 <script type="module" src="js/lib/custom/md-app-bar.js"></script>
19
 <script type="module" src="js/nav-tab-fixed.js"></script>
20
21
 <link rel="stylesheet" href="css/estilos.css">
22
 <link rel="stylesheet" href="css/transicion_pestanas.css">
23
 <link rel="stylesheet" href="css/md-headline.css">
24
 <link rel="stylesheet" href="css/md-tab.css">
25
 <link rel="stylesheet" href="css/material-symbols-outlined.css">
26
 <link rel="stylesheet" href="css/md-list.css">
27
28
</head>
29
30
<body>
31
32
 <md-app-bar adicional="tab">
33
34
  <h1>Ayuda</h1>
35
36
 </md-app-bar>
37
38
 <nav-tab-fixed id="tab"></nav-tab-fixed>
39
40
 <section>
41
42
  <ul class="md-list">
43
   <li class="md-two-line">
44
    <span class="headline">
45
     Título
46
    </span>
47
    <span class="supporting">
48
     PWA con Material Design
49
    </span>
50
   </li>
51
   <li class="md-two-line">
52
    <span class="headline">
53
     Descripción
54
    </span>
55
    <span class="supporting">
56
     Ejemplos de vistas móviles.
57
    </span>
58
   </li>
59
   <li class="md-two-line">
60
    <span class="headline">
61
     Autor
62
    </span>
63
    <span class="supporting">
64
     Gilberto Pacheco Gallegos
65
    </span>
66
   </li>
67
   <li class="md-two-line">
68
    <span class="headline">
69
     Derechos de autor
70
    </span>
71
    <span class="supporting">
72
     © 2025 Gilberto Pacheco Gallegos
73
    </span>
74
   </li>
75
   <li class="md-three-line">
76
    <span class="headline">
77
     Este software usa la librería para PWA
78
    </span>
79
    <span class="supporting">
80
     Esta obra de Gilberto Pacheco Gallegos está bajo una
81
     <a target="_blank" rel="license noreferrer"
82
       href="http://creativecommons.org/licenses/by/4.0/">
83
      Licencia Creative Commons Atribución 4.0 Internacional</a></span>
84
   </li>
85
   <li>
86
    <a class="md-three-line" target="_blank" rel=”noreferrer”
87
      href="https://fonts.google.com/icons">
88
     <span class="headline">
89
      También usa Material Symbols
90
     </span>
91
     <span class="supporting">
92
      Desarrollada por Google bajo licencia Apache 2.0
93
     </span>
94
    </a>
95
   </li>
96
  </ul>
97
98
 </section>
99
100
 <nav-drw></nav-drw>
101
102
</body>
103
104
</html>

H. site.webmanifest

  • Este archivo sirve para configurar los instaladores de la aplicación.

Explicación de las propiedades

short_name

Nombre corto. Normalmente se despliega en dispositivos móviles. Máximo 20 caracteres.

name

Nombre largo. Normalmente se despliega en computadoras de escritorio. Máximo 30 caracteres.

id

Identificador del archivo de instalación. Normalmente es la ruta del archivo inicial de la app.

start_url

Ruta del archivo inicial de la app.

display

Forma de mostrar la app. El término standalone significa que no se muestra la barra de navegación del navegador web.

theme_color

Color de la barra de estado (en dispositivos móviles) o de título (en computadoras de escritorio) de la app.

background_color

Color de fondo de la pantalla desplah en dispositivos móviles.

description

Describe el propósito de la aplicación. Aparece en el cuadro de diálogo que muestra el navegador al instalar la app.

screenshots

Listado de máximo 8 capturas de pantalla. Aparecen en el cuadro de diálogo que muestra el navegador al instalar la app. Debes incluir al menos una con "form_factor": "wide" y otra con "form_factor": "narrow".

icons

Listado de íconos en distintas resoluciones para los instaladores de la app. Se selecciona el que se vea mejor según las característocas del dispositivo.

src

Url de la imagen dentro de la app.

sizes

Dimensiones en pixeles de la imagen, anchoxalto.

type

Tipo mime de la imagen.

purpose

Forma en que se usa la imagen.

maskable

La imagen puede recortarse de forma segura para tomar distintas formas, como círculos, gotas, cuadrados con esquinas redondeadas, etc. Normalmente se usa para dispositivos móviles.

any

No se puede asegurar nada sobre la imagen. Normalmente se usa para dispositivos de escritorio.

Normalmente debe proporcionarse un juego de íconos con purpose any y otro juego de íconos con purpose maskable.

form_factor

Orientación de una screenshot.

wide

La screenshot tiene una orientación horizontal. Normalmente la creenshot se usa para dispositivos de escritorio.

narrow

La screenshot tiene una orientación vertical. Normalmente la creenshot se usa para dispositivos móviles.

Debes incluir al menos una screenshot con "form_factor": "wide" y otra con "form_factor": "narrow".

label

Descripción de una screenshot. Aparece en el cuadro de diálogo que muestra el navegador al instalar la app.

1
{
2
 "short_name": "Lista PWA",
3
 "name": "PWA con Lista",
4
 "id": "/index.html",
5
 "start_url": "/index.html",
6
 "display": "standalone",
7
 "theme_color": "#fffbfe",
8
 "background_color": "#fffbfe",
9
 "display_override": [
10
  "window-controls-overlay"
11
 ],
12
 "description": "Ejemplos de una lista con Material Design 3.",
13
 "screenshots": [
14
  {
15
   "src": "/img/screenshot_horizontal.png",
16
   "sizes": "699x389",
17
   "type": "image/png",
18
   "form_factor": "wide",
19
   "label": "Lista con Material Design 3."
20
  },
21
  {
22
   "src": "/img/screenshot_vertical.png",
23
   "sizes": "502x636",
24
   "type": "image/png",
25
   "form_factor": "narrow",
26
   "label": "Lista con Material Design 3. (2)"
27
  }
28
 ],
29
 "icons": [
30
  {
31
   "purpose": "maskable",
32
   "sizes": "2730x2730",
33
   "src": "img/maskable_icon.png",
34
   "type": "image/png"
35
  },
36
  {
37
   "purpose": "maskable",
38
   "sizes": "48x48",
39
   "src": "img/maskable_icon_x48.png",
40
   "type": "image/png"
41
  },
42
  {
43
   "purpose": "maskable",
44
   "sizes": "72x72",
45
   "src": "img/maskable_icon_x72.png",
46
   "type": "image/png"
47
  },
48
  {
49
   "purpose": "maskable",
50
   "sizes": "96x96",
51
   "src": "img/maskable_icon_x96.png",
52
   "type": "image/png"
53
  },
54
  {
55
   "purpose": "maskable",
56
   "sizes": "128x128",
57
   "src": "img/maskable_icon_x128.png",
58
   "type": "image/png"
59
  },
60
  {
61
   "purpose": "maskable",
62
   "sizes": "192x192",
63
   "src": "img/maskable_icon_x192.png",
64
   "type": "image/png"
65
  },
66
  {
67
   "purpose": "maskable",
68
   "sizes": "384x384",
69
   "src": "img/maskable_icon_x384.png",
70
   "type": "image/png"
71
  },
72
  {
73
   "purpose": "maskable",
74
   "sizes": "512x512",
75
   "src": "img/maskable_icon_x512.png",
76
   "type": "image/png"
77
  },
78
  {
79
   "purpose": "any",
80
   "sizes": "2730x2730",
81
   "src": "img/maskable_icon.png",
82
   "type": "image/png"
83
  },
84
  {
85
   "purpose": "any",
86
   "sizes": "48x48",
87
   "src": "img/maskable_icon_x48.png",
88
   "type": "image/png"
89
  },
90
  {
91
   "purpose": "any",
92
   "sizes": "72x72",
93
   "src": "img/maskable_icon_x72.png",
94
   "type": "image/png"
95
  },
96
  {
97
   "purpose": "any",
98
   "sizes": "96x96",
99
   "src": "img/maskable_icon_x96.png",
100
   "type": "image/png"
101
  },
102
  {
103
   "purpose": "any",
104
   "sizes": "128x128",
105
   "src": "img/maskable_icon_x128.png",
106
   "type": "image/png"
107
  },
108
  {
109
   "purpose": "any",
110
   "sizes": "192x192",
111
   "src": "img/maskable_icon_x192.png",
112
   "type": "image/png"
113
  },
114
  {
115
   "purpose": "any",
116
   "sizes": "384x384",
117
   "src": "img/maskable_icon_x384.png",
118
   "type": "image/png"
119
  },
120
  {
121
   "purpose": "any",
122
   "sizes": "512x512",
123
   "src": "img/maskable_icon_x512.png",
124
   "type": "image/png"
125
  },
126
  {
127
   "purpose": "any",
128
   "sizes": "2048x2048",
129
   "src": "img/icono2048.png",
130
   "type": "image/png"
131
  }
132
 ]
133
}

I. sw.js

1
/* Este archivo debe estar colocado en la carpeta raíz del sitio.
2
 * 
3
 * Cualquier cambio en el contenido de este archivo hace que el service
4
 * worker se reinstale. */
5
6
/**
7
 * Cambia el número de la versión cuando cambia el contenido de los
8
 * archivos.
9
 * 
10
 * El número a la izquierda del punto (.), en este caso <q>1</q>, se
11
 * conoce como número mayor y se cambia cuando se realizan
12
 * modificaciones grandes o importantes.
13
 * 
14
 * El número a la derecha del punto (.), en este caso <q>00</q>, se
15
 * conoce como número menor y se cambia cuando se realizan
16
 * modificaciones menores.
17
 */
18
const VERSION = "1.00"
19
20
/**
21
 * Nombre de la carpeta de caché.
22
 */
23
const CACHE = "pwamd"
24
25
/**
26
 * Archivos requeridos para que la aplicación funcione fuera de
27
 * línea.
28
 */
29
const ARCHIVOS = [
30
 "ayuda.html",
31
 "favicon.ico",
32
 "index.html",
33
 "site.webmanifest",
34
 "css/baseline.css",
35
 "css/colors.css",
36
 "css/elevation.css",
37
 "css/estilos.css",
38
 "css/material-symbols-outlined.css",
39
 "css/md-headline.css",
40
 "css/md-list.css",
41
 "css/md-tab.css",
42
 "css/motion.css",
43
 "css/palette.css",
44
 "css/roboto.css",
45
 "css/shape.css",
46
 "css/state.css",
47
 "css/transicion_pestanas.css",
48
 "css/typography.css",
49
 "css/theme/dark.css",
50
 "css/theme/light.css",
51
 "fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].codepoints",
52
 "fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf",
53
 "fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2",
54
 "fonts/roboto-v32-latin-regular.woff2",
55
 "img/Escultura_de_coyote.jpeg",
56
 "img/icono2048.png",
57
 "img/maskable_icon.png",
58
 "img/maskable_icon_x128.png",
59
 "img/maskable_icon_x192.png",
60
 "img/maskable_icon_x384.png",
61
 "img/maskable_icon_x48.png",
62
 "img/maskable_icon_x512.png",
63
 "img/maskable_icon_x72.png",
64
 "img/maskable_icon_x96.png",
65
 "img/pexels-craig-dennis-3701822.jpg",
66
 "img/pexels-moises-patrício-10961948.jpg",
67
 "img/screenshot_horizontal.png",
68
 "img/screenshot_vertical.png",
69
 "js/nav-tab-fixed.js",
70
 "js/lib/ES_APPLE.js",
71
 "js/lib/getAttribute.js",
72
 "js/lib/querySelector.js",
73
 "js/lib/registraServiceWorker.js",
74
 "js/lib/resaltaSiEstasEn.js",
75
 "js/lib/custom/md-app-bar.js",
76
 "ungap/custom-elements.js",
77
 "/"
78
]
79
80
// Verifica si el código corre dentro de un service worker.
81
if (self instanceof ServiceWorkerGlobalScope) {
82
 // Evento al empezar a instalar el servide worker,
83
 self.addEventListener("install",
84
  (/** @type {ExtendableEvent} */ evt) => {
85
   console.log("El service worker se está instalando.")
86
   evt.waitUntil(llenaElCache())
87
  })
88
89
 // Evento al solicitar información a la red.
90
 self.addEventListener("fetch", (/** @type {FetchEvent} */ evt) => {
91
  if (evt.request.method === "GET") {
92
   evt.respondWith(buscaLaRespuestaEnElCache(evt))
93
  }
94
 })
95
96
 // Evento cuando el service worker se vuelve activo.
97
 self.addEventListener("activate",
98
  () => console.log("El service worker está activo."))
99
}
100
101
async function llenaElCache() {
102
 console.log("Intentando cargar caché:", CACHE)
103
 // Borra todos los cachés.
104
 const keys = await caches.keys()
105
 for (const key of keys) {
106
  await caches.delete(key)
107
 }
108
 // Abre el caché de este service worker.
109
 const cache = await caches.open(CACHE)
110
 // Carga el listado de ARCHIVOS.
111
 await cache.addAll(ARCHIVOS)
112
 console.log("Cache cargado:", CACHE)
113
 console.log("Versión:", VERSION)
114
}
115
116
/** @param {FetchEvent} evt */
117
async function buscaLaRespuestaEnElCache(evt) {
118
 // Abre el caché.
119
 const cache = await caches.open(CACHE)
120
 const request = evt.request
121
 /* Busca la respuesta a la solicitud en el contenido del caché, sin
122
  * tomar en cuenta la parte después del símbolo "?" en la URL. */
123
 const response = await cache.match(request, { ignoreSearch: true })
124
 if (response === undefined) {
125
  /* Si no la encuentra, empieza a descargar de la red y devuelve
126
   * la promesa. */
127
  return fetch(request)
128
 } else {
129
  // Si la encuentra, devuelve la respuesta encontrada en el caché.
130
  return response
131
 }
132
}

J. Carpeta « css »

Versión para imprimir.

A. css / baseline.css

1
/*
2
 Copyright 2016 Google Inc. All rights reserved.
3
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at
7
8
     http://www.apache.org/licenses/LICENSE-2.0
9
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
*/
16
17
@import url(palette.css);
18
@import url(typography.css);
19
@import url(colors.css);
20
@import url(shape.css);
21
@import url(motion.css);
22
@import url(state.css);
23
@import url(elevation.css);
24
@import url(theme/light.css) screen and (prefers-color-scheme: light);
25
@import url(theme/dark.css) screen and (prefers-color-scheme: dark);
26

B. css / colors.css

1
/*
2
 Copyright 2016 Google Inc. All rights reserved.
3
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at
7
8
     http://www.apache.org/licenses/LICENSE-2.0
9
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
*/
16
17
.primary {
18
  color: var(--md-sys-color-on-primary);
19
  background-color: var(--md-sys-color-primary);
20
}
21
.on-primary {
22
  color: var(--md-sys-color-primary);
23
  background-color: var(--md-sys-color-on-primary);
24
}
25
.primary-container {
26
  color: var(--md-sys-color-on-primary-container);
27
  background-color: var(--md-sys-color-primary-container);
28
}
29
.on-primary-container {
30
  color: var(--md-sys-color-primary-container);
31
  background-color: var(--md-sys-color-on-primary-container);
32
}
33
.secondary {
34
  color: var(--md-sys-color-on-secondary);
35
  background-color: var(--md-sys-color-secondary);
36
}
37
.on-secondary {
38
  color: var(--md-sys-color-secondary);
39
  background-color: var(--md-sys-color-on-secondary);
40
}
41
.secondary-container {
42
  color: var(--md-sys-color-on-secondary-container);
43
  background-color: var(--md-sys-color-secondary-container);
44
}
45
.on-secondary-container {
46
  color: var(--md-sys-color-secondary-container);
47
  background-color: var(--md-sys-color-on-secondary-container);
48
}
49
.tertiary {
50
  color: var(--md-sys-color-on-tertiary);
51
  background-color: var(--md-sys-color-tertiary);
52
}
53
.on-tertiary {
54
  color: var(--md-sys-color-tertiary);
55
  background-color: var(--md-sys-color-on-tertiary);
56
}
57
.tertiary-container {
58
  color: var(--md-sys-color-on-tertiary-container);
59
  background-color: var(--md-sys-color-tertiary-container);
60
}
61
.on-tertiary-container {
62
  color: var(--md-sys-color-tertiary-container);
63
  background-color: var(--md-sys-color-on-tertiary-container);
64
}
65
.background {
66
  color: var(--md-sys-color-on-background);
67
  background-color: var(--md-sys-color-background);
68
}
69
.surface {
70
  color: var(--md-sys-color-on-surface);
71
  background-color: var(--md-sys-color-surface);
72
}
73
.surface-variant {
74
  color: var(--md-sys-color-on-surface-variant);
75
  background-color: var(--md-sys-color-surface-variant);
76
}
77
.on-surface-variant {
78
  color: var(--md-sys-color-surface-variant);
79
  background-color: var(--md-sys-color-on-surface-variant);
80
}
81
.outline {
82
  border: 1px solid var(--md-sys-color-outline);
83
}
84
.inverse-surface {
85
  color: var(--md-sys-color-on-inverse-surface);
86
  background-color: var(--md-sys-color-inverse-surface);
87
}
88
.on-inverse-surface {
89
  color: var(--md-sys-color-inverse-surface);
90
  background-color: var(--md-sys-color-on-inverse-surface);
91
}
92
.inverse-primary {
93
  color: var(--md-sys-color-on-inverse-primary);
94
  background-color: var(--md-sys-color-inverse-primary);
95
}
96
.on-inverse-primary {
97
  color: var(--md-sys-color-inverse-primary);
98
  background-color: var(--md-sys-color-on-inverse-primary);
99
}
100
.surface-tint {
101
  background-color: var(--md-sys-color-on-surface-tint);
102
}
103
.error {
104
  color: var(--md-sys-color-on-error);
105
  background-color: var(--md-sys-color-error);
106
}
107
.on-error {
108
  color: var(--md-sys-color-error);
109
  background-color: var(--md-sys-color-on-error);
110
}
111
.error-container {
112
  color: var(--md-sys-color-on-error-container);
113
  background-color: var(--md-sys-color-error-container);
114
}
115
.on-error-container {
116
  color: var(--md-sys-color-error-container);
117
  background-color: var(--md-sys-color-on-error-container);
118
}
119
.black {
120
  background-color: var(--md-ref-palette-black);
121
}
122
.black-text {
123
  color: var(--md-ref-palette-black);
124
}
125
.white {
126
  background-color: var(--md-ref-palette-white);
127
}
128
.white-text {
129
  color: var(--md-ref-palette-white);
130
}
131

C. css / elevation.css

1
/*
2
 Copyright 2016 Google Inc. All rights reserved.
3
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at
7
8
     http://www.apache.org/licenses/LICENSE-2.0
9
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
*/
16
17
:root {
18
  /* Surface tint color */
19
  --md-sys-elevation-surface-tint-color: var(--md-sys-color-primary);
20
  /* +5 */
21
  --md-sys-elevation-level5-value: 12px;
22
  --md-sys-elevation-level5-unit: 1px;
23
  --md-sys-elevation-level5: 12px;
24
  /* +4 */
25
  --md-sys-elevation-level4-value: 8px;
26
  --md-sys-elevation-level4-unit: 1px;
27
  --md-sys-elevation-level4: 8px;
28
  /* +3 */
29
  --md-sys-elevation-level3-value: 6px;
30
  --md-sys-elevation-level3-unit: 1px;
31
  --md-sys-elevation-level3: 6px;
32
  /* +2 */
33
  --md-sys-elevation-level2-value: 3px;
34
  --md-sys-elevation-level2-unit: 1px;
35
  --md-sys-elevation-level2: 3px;
36
  /* +1 */
37
  --md-sys-elevation-level1-value: 1px;
38
  --md-sys-elevation-level1-unit: 1px;
39
  --md-sys-elevation-level1: 1px;
40
  /* 0 */
41
  --md-sys-elevation-level0-value: 0px;
42
  --md-sys-elevation-level0-unit: 1px;
43
  --md-sys-elevation-level0: 0px;
44
}
45
.elevation-0 {
46
  box-shadow: var(--md-sys-elevation-level0);
47
}
48
.elevation-1 {
49
  box-shadow: var(--md-sys-elevation-level1);
50
}
51
.elevation-2 {
52
  box-shadow: var(--md-sys-elevation-level2);
53
}
54
.elevation-3 {
55
  box-shadow: var(--md-sys-elevation-level3);
56
}
57
.elevation-4 {
58
  box-shadow: var(--md-sys-elevation-level4);
59
}
60
.elevation-5 {
61
  box-shadow: var(--md-sys-elevation-level5);
62
}
63

D. css / estilos.css

1
/* Definiciones para Material Design 3  */
2
@import url(baseline.css);
3
/* Fonts utilizados */
4
@import url(roboto.css);
5
6
html {
7
 /* Indica los temas del sistema operativo que son soportados. */
8
 color-scheme: light dark;
9
 --tabWidth: 3.75rem;
10
 --anchoNav: 22.5rem;
11
}
12
13
body>section,
14
form>section {
15
 max-width: 600px;
16
 margin-left: auto;
17
 margin-right: auto;
18
}
19
20
/* Quita un borde rojo que coloca Firefox. */
21
:-moz-ui-invalid {
22
 box-shadow: none;
23
}
24
25
body {
26
 margin: 0;
27
 font-family: var(--md-sys-typescale-body-large-font);
28
 font-weight: var(--md-sys-typescale-body-large-weight);
29
 font-size: var(--md-sys-typescale-body-large-size);
30
 font-style: var(--md-sys-typescale-body-large-font-style);
31
 letter-spacing: var(--md-sys-typescale-body-large-tracking);
32
 line-height: var(--md-sys-typescale-body-large-line-height);
33
 text-transform: var(--md-sys-typescale-body-large-text-transform);
34
 text-decoration: var(--md-sys-typescale-body-large-text-decoration);
35
 color: var(--md-sys-color-on-background);
36
 background-color: var(--md-sys-color-background);
37
 /* Las siguientes líneas Evita los cambios de apariencia al cargar estilos y
38
 + custom elements, que son conocidos como Flash Of Unstyled Content (fouc). */
39
 opacity: 0;
40
 animation-name: fouc;
41
 animation-fill-mode: forwards;
42
 animation-duration: 1.5s;
43
}
44
45
@keyframes fouc {
46
 to {
47
  opacity: 1;
48
 }
49
}
50
51
html {
52
 --Font: -apple-system, BlinkMacSystemFont, roboto, sans-serif;
53
 --colIntIos: white;
54
 --colIntIosOnBk: #2acc2a;
55
 --colIntIosOnBkFc: #1bbb1b;
56
 --colIntIosOffBk: #dbdbdb;
57
 --colIntIosOffBkFc: #BDBDBD;
58
 /* Plain typeface */
59
 --md-ref-typeface-plain: var(--Font);
60
 /* Brand typeface */
61
 --md-ref-typeface-brand: var(--Font);
62
 --md-sys-typescale-label-large-weight-prominent:
63
  var(--md-ref-typeface-weight-bold);
64
 --md-box_shadow_level4:
65
  0 var(--md-sys-elevation-level4) var(--md-sys-elevation-level4) var(--md-sys-color-shadow);
66
 --md-box_shadow_level3:
67
  0 var(--md-sys-elevation-level3) var(--md-sys-elevation-level3) var(--md-sys-color-shadow);
68
 --md-box_shadow_level2:
69
  0 var(--md-sys-elevation-level2) var(--md-sys-elevation-level2) var(--md-sys-color-shadow);
70
 --md-box_shadow_level1:
71
  0 var(--md-sys-elevation-level1) var(--md-sys-elevation-level1) var(--md-sys-color-shadow);
72
 --md-box_shadow_level0: none;
73
 --iconSize: 1.5rem;
74
 --avatarSize: 2.5rem;
75
 --imageSize: 3.5rem;
76
 --videoWidth: 7.125rem;
77
 --videoHeight: 4rem;
78
 --scroll-headline-duracion: 2s;
79
 --md-sys-state-focus-indicator-outer-offset: 0.125rem;
80
 --md-sys-state-focus-indicator-thickness: 0.1875rem;
81
 /* Pressed state layer opacity */
82
 --state-pressed-transparency-percentage: 84%;
83
 /* Focus state layer opacity */
84
 --state-focus-transparency-percentage: 88%;
85
 /* Hover state layer opacity */
86
 --state-hover-transparency-percentage: 92%;
87
}
88
89
p {
90
 margin: 1rem;
91
}
92
93
a {
94
 color: var(--md-sys-color-on-background);
95
}
96
97
@media (prefers-color-scheme: light) {
98
 html {
99
  --md-riple-color: #00000020;
100
 }
101
}
102
103
@media (prefers-color-scheme: dark) {
104
 html {
105
  --md-riple-color: #ffffff40;
106
 }
107
}
108
109
@keyframes md-ripple {
110
111
 from {
112
  background-size: 100%;
113
 }
114
115
 to {
116
  background-size: 15000%;
117
 }
118
119
}
120
121
@keyframes salePorLaIzquierda {
122
 to {
123
  translate: -100vw 0;
124
 }
125
}
126
127
@keyframes entraPorLaDerecha {
128
 from {
129
  translate: 100vw 0;
130
 }
131
}
132
133
@keyframes aparece {
134
 from {
135
  opacity: 0;
136
 }
137
}
138
139
@keyframes desvanece {
140
 to {
141
  opacity: 0;
142
 }
143
}

E. css / material-symbols-outlined.css

1
@font-face {
2
 font-family: 'Material Symbols Outlined';
3
 font-style: normal;
4
 src:
5
  url(../fonts/MaterialSymbolsOutlined[FILL\,GRAD\,opsz\,wght].woff2) format('woff2'),
6
  url(../fonts/MaterialSymbolsOutlined[FILL\,GRAD\,opsz\,wght].ttf) format('truetype');
7
}
8
9
.material-symbols-outlined {
10
 font-family: 'Material Symbols Outlined';
11
 font-weight: normal;
12
 font-style: normal;
13
 font-size: 1.5rem;
14
 width: 1.5rem;
15
 height: 1.5rem;
16
 /* Preferred icon size */
17
 display: inline-block;
18
 line-height: 1;
19
 text-transform: none;
20
 letter-spacing: normal;
21
 word-wrap: normal;
22
 white-space: nowrap;
23
 direction: ltr;
24
}

F. css / md-headline.css

1
.md-headline {
2
 box-sizing: border-box;
3
 margin: 0;
4
 color: var(--md-sys-color-on-surface);
5
 background-color: var(--md-sys-color-surface);
6
 transition-property: color;
7
 transition-duration: var(--md-sys-motion-duration-1000);
8
 transition-timing-function: ease-in;
9
}
10
11
.md-headline.scroll-adicional {
12
 color: var(--md-sys-color-surface-container-low);
13
 background-color: var(--md-sys-color-surface-container-low);
14
}
15
16
.md-headline.scroll {
17
 color: var(--md-sys-color-surface);
18
}
19
20
.md-headline.headline-small {
21
 padding: 0 1rem 1.5rem 1rem;
22
}
23
24
.md-headline.headline-medium {
25
 padding: 0 1rem 1.75rem 1rem;
26
}
27
28
md-app-bar.centered~.md-headline {
29
 text-align: center;
30
}
31
32
md-app-bar[headline] h1 {
33
 opacity: 0;
34
 transition-property: opacity;
35
 transition-duration: var(--md-sys-motion-duration-1000);
36
}
37
38
md-app-bar[headline].scroll h1 {
39
 opacity: 1;
40
 transition-timing-function: ease-in;
41
}

G. css / md-list.css

1
.md-list {
2
 margin: 0.5rem 0;
3
 padding: 0;
4
 list-style-type: none;
5
}
6
7
.md-list .md-one-line,
8
.md-list .md-two-line,
9
.md-list .md-three-line {
10
 position: relative;
11
 display: flex;
12
 box-sizing: border-box;
13
}
14
15
/* container */
16
.md-list .md-one-line::before,
17
.md-list .md-two-line::before,
18
.md-list .md-three-line::before {
19
 content: "";
20
 position: absolute;
21
 z-index: -2;
22
 top: 0;
23
 right: 0;
24
 left: 0;
25
 bottom: 0;
26
 background-color: var(--md-sys-color-surface);
27
}
28
29
/* state layer */
30
.md-list .md-one-line::after,
31
.md-list .md-two-line::after,
32
.md-list .md-three-line::after {
33
 content: "";
34
 position: absolute;
35
 z-index: -1;
36
 top: 0;
37
 right: 0;
38
 left: 0;
39
 bottom: 0;
40
 background-color: transparent;
41
}
42
43
.md-list .md-one-line {
44
 align-items: center;
45
 gap: 1rem;
46
 min-height: 3.5rem;
47
 padding: 0.5rem 1.5rem 0.5rem 1rem;
48
}
49
50
.md-list .md-one-line.video,
51
.md-list .md-two-line.video {
52
 padding: 0.75rem 1.5rem 0.75rem 0;
53
}
54
55
.md-list .md-two-line,
56
.md-list .md-three-line {
57
 flex-flow: column;
58
}
59
60
.md-list .md-two-line {
61
 justify-content: center;
62
 min-height: 4.5rem;
63
 padding: 0.5rem 1.5rem 0.5rem 1rem;
64
}
65
66
.md-list .md-two-line.icon,
67
.md-list .md-two-line.avatar,
68
.md-list .md-two-line.image,
69
.md-list .md-two-line.video,
70
.md-list .md-three-line.icon,
71
.md-list .md-three-line.avatar,
72
.md-list .md-three-line.image,
73
.md-list .md-three-line.video {
74
 display: grid;
75
 column-gap: 1rem;
76
 row-gap: 0;
77
 grid-template-areas:
78
  "img headline"
79
  "img supporting";
80
}
81
82
.md-list .md-two-line.icon,
83
.md-list .md-two-line.avatar,
84
.md-list .md-two-line.image,
85
.md-list .md-two-line.video {
86
 align-content: center;
87
 grid-template-rows: 1fr 1fr;
88
}
89
90
.md-list .md-two-line.icon,
91
.md-list .md-three-line.icon {
92
 grid-template-columns: var(--iconSize) 1fr;
93
}
94
95
.md-list .md-two-line.avatar,
96
.md-list .md-three-line.avatar {
97
 grid-template-columns: var(--avatarSize) 1fr;
98
}
99
100
.md-list .md-two-line.image,
101
.md-list .md-three-line.image {
102
 grid-template-columns: var(--imageSize) 1fr;
103
}
104
105
.md-list .md-two-line.video,
106
.md-list .md-three-line.video {
107
 grid-template-columns: var(--videoWidth) 1fr;
108
}
109
110
.md-list .md-three-line {
111
 align-content: flex-start;
112
 min-height: 5.5rem;
113
 padding: 0.75rem 1.5rem 0.75rem 1rem;
114
}
115
116
.md-list .md-three-line.video {
117
 padding: 0.75rem 1.5rem 0.75rem 0;
118
}
119
120
.md-list .md-three-line.icon,
121
.md-list .md-three-line.avatar,
122
.md-list .md-three-line.image,
123
.md-list .md-three-line.video {
124
 align-content: start;
125
 grid-template-rows: var(--md-sys-typescale-label-large-line-height) 1fr;
126
}
127
128
/* state layer */
129
.md-list .md-one-line:hover::after,
130
.md-list .md-two-line:hover::after,
131
.md-list .md-three-line:hover::after {
132
 background-color: var(--md-sys-color-on-surface);
133
 opacity: var(--md-sys-state-hover-state-layer-opacity);
134
}
135
136
/* state layer */
137
.md-list a.md-one-line:focus::after,
138
.md-list a.md-two-line:focus::after,
139
.md-list a.md-three-line:focus::after,
140
.md-list a.md-one-line:focus-visible::after,
141
.md-list a.md-two-line:focus-visible::after,
142
.md-list a.md-three-line:focus-visible::after {
143
 background-color: var(--md-sys-color-on-surface);
144
 opacity: var(--md-sys-state-focus-state-layer-opacity);
145
}
146
147
.md-list a:focus,
148
.md-list a:focus-visible {
149
 outline: none;
150
}
151
152
.md-list a:active {
153
 background-position: center;
154
 background-image:
155
  radial-gradient(circle, var(--md-riple-color) 1%, transparent 1%);
156
 background-size: 100%;
157
 animation-name: md-ripple;
158
 animation-duration: var(--md-sys-motion-duration-500);
159
 box-shadow: var(--md-box_shadow_level0) !important;
160
}
161
162
/* state layer */
163
.md-list a.md-one-line:active::after,
164
.md-list a.md-two-line:active::after,
165
.md-list a.md-three-line:active::after {
166
 background-color: var(--md-sys-color-on-surface);
167
 opacity: var(--md-sys-state-pressed-state-layer-opacity);
168
}
169
170
.md-list a.md-two-line,
171
.md-list a.md-three-line {
172
 text-decoration: none;
173
}
174
175
.md-list a.md-two-line .headline,
176
.md-list a.md-three-line .headline {
177
 text-decoration: underline;
178
}
179
180
.md-list .headline {
181
 grid-area: headline;
182
 display: block;
183
 box-sizing: border-box;
184
 color: var(--md-sys-color-on-surface);
185
 font-family: var(--md-sys-typescale-body-large-font);
186
 font-weight: var(--md-sys-typescale-body-large-weight);
187
 font-size: var(--md-sys-typescale-body-large-size);
188
 font-style: var(--md-sys-typescale-body-large-font-style);
189
 letter-spacing: var(--md-sys-typescale-body-large-tracking);
190
 line-height: var(--md-sys-typescale-body-large-line-height);
191
 text-transform: var(--md-sys-typescale-body-large-text-transform);
192
 text-decoration: var(--md-sys-typescale-body-large-text-decoration);
193
 max-height: var(--md-sys-typescale-body-large-line-height);
194
 white-space: nowrap;
195
 text-overflow: ellipsis;
196
 overflow: hidden;
197
}
198
199
.md-list .md-two-line.icon .headline,
200
.md-list .md-two-line.avatar .headline,
201
.md-list .md-two-line.image .headline,
202
.md-list .md-two-line.video .headline,
203
.md-list .md-three-line.icon .headline,
204
.md-list .md-three-line.avatar .headline,
205
.md-list .md-three-line.image .headline,
206
.md-list .md-three-line.video .headline {
207
 align-self: end;
208
}
209
210
.md-list .supporting {
211
 grid-area: supporting;
212
 display: -webkit-box;
213
 -webkit-box-orient: vertical;
214
 overflow: hidden;
215
 box-sizing: border-box;
216
 align-self: start;
217
 font-family: var(--md-sys-typescale-body-medium-font);
218
 font-weight: var(--md-sys-typescale-body-medium-weight);
219
 font-size: var(--md-sys-typescale-body-medium-size);
220
 font-style: var(--md-sys-typescale-body-medium-font-style);
221
 letter-spacing: var(--md-sys-typescale-body-medium-tracking);
222
 line-height: var(--md-sys-typescale-body-medium-line-height);
223
 text-transform: var(--md-sys-typescale-body-medium-text-transform);
224
 text-decoration: var(--md-sys-typescale-body-medium-text-decoration);
225
}
226
227
.md-list .md-two-line .supporting {
228
 max-height: var(--md-sys-typescale-body-medium-line-height);
229
 line-clamp: 1;
230
 -webkit-line-clamp: 1;
231
}
232
233
.md-list .md-three-line .supporting {
234
 max-height: calc(2 * var(--md-sys-typescale-body-medium-line-height));
235
 line-clamp: 2;
236
 -webkit-line-clamp: 2;
237
}
238
239
.md-list .avatar img,
240
.md-list .avatar label,
241
.md-list .avatar .material-symbols-outlined:first-child {
242
 flex-shrink: 0;
243
 background-color: var(--md-sys-color-primary-container);
244
 color: var(--md-sys-color-on-primary-container);
245
 border-radius: 50%;
246
 width: var(--avatarSize);
247
 height: var(--avatarSize);
248
}
249
250
.md-list .avatar label {
251
 display: inline-block;
252
 font-family: var(--md-sys-typescale-title-medium-font);
253
 font-weight: var(--md-sys-typescale-title-medium-weight);
254
 font-size: var(--md-sys-typescale-title-medium-size);
255
 font-style: var(--md-sys-typescale-title-medium-font-style);
256
 letter-spacing: var(--md-sys-typescale-title-medium-tracking);
257
 line-height: var(--md-sys-typescale-title-medium-line-height);
258
 text-transform: var(--md-sys-typescale-title-medium-text-transform);
259
 text-decoration: var(--md-sys-typescale-title-medium-text-decoration);
260
 overflow: hidden;
261
}
262
263
.md-list .avatar .material-symbols-outlined:first-child {
264
 font-size: var(--avatarSize);
265
}
266
267
.md-list .avatar.md-two-line img,
268
.md-list .avatar.md-two-line label,
269
.md-list .avatar.md-two-line .material-symbols-outlined:first-child {
270
 grid-area: img;
271
 align-self: center;
272
}
273
274
.md-list .avatar.md-three-line img,
275
.md-list .avatar.md-three-line label,
276
.md-list .avatar.md-three-line .material-symbols-outlined:first-child {
277
 grid-area: img;
278
 align-self: start;
279
}
280
281
.md-list .icon img,
282
.md-list .icon .material-symbols-outlined:first-child {
283
 flex-shrink: 0;
284
 color: var(--md-sys-color-on-surface-variant);
285
 width: var(--iconSize);
286
 height: var(--iconSize);
287
}
288
289
.md-list .icon .material-symbols-outlined:first-child {
290
 font-size: var(--iconSize);
291
}
292
293
.md-list .icon.md-two-line img,
294
.md-list .icon.md-two-line .material-symbols-outlined:first-child {
295
 grid-area: img;
296
 align-self: center;
297
}
298
299
.md-list .icon.md-three-line img,
300
.md-list .icon.md-three-line .material-symbols-outlined:first-child {
301
 grid-area: img;
302
 align-self: start;
303
}
304
305
.md-list .video img {
306
 flex-shrink: 0;
307
 color: var(--md-sys-color-on-surface-variant);
308
 width: var(--videoWidth);
309
 height: var(--videoHeight);
310
}
311
312
.md-list .video.md-two-line img {
313
 grid-area: img;
314
 align-self: center;
315
}
316
317
.md-list .video.md-three-line img {
318
 grid-area: img;
319
 align-self: start;
320
}
321
322
.md-list .image img,
323
.md-list .image .material-symbols-outlined:first-child {
324
 flex-shrink: 0;
325
 color: var(--md-sys-color-on-surface-variant);
326
 width: var(--imageSize);
327
 height: var(--imageSize);
328
}
329
330
.md-list .image .material-symbols-outlined:first-child {
331
 font-size: var(--imageSize);
332
}
333
334
.md-list .image.md-two-line img,
335
.md-list .image.md-two-line .material-symbols-outlined:first-child {
336
 grid-area: img;
337
 align-self: center;
338
}
339
340
.md-list .image.md-three-line img,
341
.md-list .image.md-three-line .material-symbols-outlined:first-child {
342
 grid-area: img;
343
 align-self: start;
344
}

H. css / md-tab.css

1
.md-tab {
2
 display: flex;
3
 background-color: transparent;
4
 align-items: stretch;
5
 flex-wrap: nowrap;
6
 overflow-x: auto;
7
 position: sticky;
8
 z-index: 1;
9
}
10
11
.md-tab.fixed {
12
 justify-content: center;
13
}
14
15
.md-tab.scrollable {
16
 padding-left: 2rem;
17
 gap: 1rem;
18
}
19
20
.md-tab.scroll {
21
 background-color: var(--md-sys-color-surface-container-low);
22
}
23
24
.md-tab a {
25
 position: relative;
26
 display: flex;
27
 flex-direction: column;
28
 justify-content: start;
29
 align-items: center;
30
 color: var(--md-sys-color-on-surface-variant);
31
 font-family: var(--md-sys-typescale-title-small-font);
32
 font-weight: var(--md-sys-typescale-title-small-weight);
33
 font-size: var(--md-sys-typescale-title-small-size);
34
 font-style: var(--md-sys-typescale-title-small-font-style);
35
 letter-spacing: var(--md-sys-typescale-title-small-tracking);
36
 line-height: var(--md-sys-typescale-title-small-line-height);
37
 text-transform: var(--md-sys-typescale-title-small-text-transform);
38
 text-decoration: var(--md-sys-typescale-title-small-text-decoration);
39
 text-align: center;
40
 box-sizing: border-box;
41
 border-bottom: 0.1875rem solid var(--md-sys-color-surface);
42
}
43
44
.md-tab.fixed a {
45
 flex: 0 0 var(--tabWidth);
46
}
47
48
.md-tab.scrollable a {
49
 flex: 0 0 auto;
50
}
51
52
.md-tab a.active {
53
 border-bottom-color: var(--md-sys-color-primary);
54
}
55
56
/* state layer */
57
.md-tab a::after {
58
 content: "";
59
 position: absolute;
60
 z-index: -1;
61
 top: 0;
62
 right: 0;
63
 left: 0;
64
 bottom: 0;
65
 background-color: transparent;
66
}
67
68
.md-tab span {
69
 font-size: var(--iconSize);
70
 height: var(--iconSize);
71
 width: var(--iconSize);
72
 color: var(--md-sys-color-on-surface-variant);
73
}
74
75
.md-tab .active span {
76
 color: var(--md-sys-color-primary);
77
}
78
79
.md-tab a:hover {
80
 color: var(--md-sys-color-on-surface);
81
}
82
83
/* state layer */
84
.md-tab a:hover::after {
85
 background-color: var(--md-sys-color-on-surface);
86
 opacity: var(--md-sys-state-hover-state-layer-opacity);
87
}
88
89
.md-tab a.active:hover {
90
 color: var(--md-sys-color-primary);
91
}
92
93
/* state layer */
94
.md-tab a.active:hover::after {
95
 background-color: var(--md-sys-color-primary);
96
 opacity: var(--md-sys-state-hover-state-layer-opacity);
97
}
98
99
.md-tab a:hover span {
100
 color: var(--md-sys-color-on-surface);
101
}
102
103
.md-tab a.active:hover span {
104
 color: var(--md-sys-color-primary);
105
}
106
107
.md-tab a:focus {
108
 outline: none;
109
}
110
111
/* state layer */
112
.md-tab a:focus::after {
113
 background-color: var(--md-sys-color-on-surface);
114
 opacity: var(--md-sys-state-focus-state-layer-opacity);
115
}
116
117
/* state layer */
118
.md-tab a.active:focus::after {
119
 background-color: var(--md-sys-color-primary);
120
 opacity: var(--md-sys-state-hover-state-layer-opacity);
121
}
122
123
.md-tab a:active {
124
 background-position: center;
125
 background-image:
126
   radial-gradient(circle, var(--md-riple-color) 1%, transparent 1%);
127
 background-size: 100%;
128
 animation-name: md-ripple;
129
 animation-duration: var(--md-sys-motion-duration-500);
130
}
131
132
/* state layer */
133
.md-tab a:active::after {
134
 background-color: var(--md-sys-color-on-surface);
135
 opacity: var(--md-sys-state-pressed-state-layer-opacity);
136
}
137
138
/* state layer */
139
.md-tab a.active:active::after {
140
 background-color: var(--md-sys-color-primary);
141
 opacity: var(--md-sys-state-pressed-state-layer-opacity);
142
}

I. css / motion.css

1
/*
2
 Copyright 2016 Google Inc. All rights reserved.
3
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at
7
8
     http://www.apache.org/licenses/LICENSE-2.0
9
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
*/
16
17
:root {
18
  /* Emphasized decelerate easing (out) */
19
  --md-sys-motion-easing-emphasized-decelerate-x0: 0.05000000074505806;
20
  --md-sys-motion-easing-emphasized-decelerate-y0: 0.699999988079071;
21
  --md-sys-motion-easing-emphasized-decelerate-x1: 0.10000000149011612;
22
  --md-sys-motion-easing-emphasized-decelerate-y1: 1;
23
  /* Emphasized accelerate easing (in) */
24
  --md-sys-motion-easing-emphasized-accelerate-x0: 0.30000001192092896;
25
  --md-sys-motion-easing-emphasized-accelerate-y0: 0;
26
  --md-sys-motion-easing-emphasized-accelerate-x1: 0.800000011920929;
27
  --md-sys-motion-easing-emphasized-accelerate-y1: 0.15000000596046448;
28
  /* Standard decelerate easing (out) */
29
  --md-sys-motion-easing-standard-decelerate-x0: 0;
30
  --md-sys-motion-easing-standard-decelerate-y0: 0;
31
  --md-sys-motion-easing-standard-decelerate-x1: 0;
32
  --md-sys-motion-easing-standard-decelerate-y1: 1;
33
  /* Standard accelerate easing (in) */
34
  --md-sys-motion-easing-standard-accelerate-x0: 0.30000001192092896;
35
  --md-sys-motion-easing-standard-accelerate-y0: 0;
36
  --md-sys-motion-easing-standard-accelerate-x1: 1;
37
  --md-sys-motion-easing-standard-accelerate-y1: 1;
38
  /* Duration 1000ms */
39
  --md-sys-motion-duration-1000: 1000ms;
40
  /* Duration 900ms */
41
  --md-sys-motion-duration-900: 900ms;
42
  /* Duration 800ms */
43
  --md-sys-motion-duration-800: 800ms;
44
  /* Duration 700ms */
45
  --md-sys-motion-duration-700: 700ms;
46
  /* Duration 600ms */
47
  --md-sys-motion-duration-600: 600ms;
48
  /* Duration 550ms */
49
  --md-sys-motion-duration-550: 550ms;
50
  /* Duration 500ms */
51
  --md-sys-motion-duration-500: 500ms;
52
  /* Duration 450ms */
53
  --md-sys-motion-duration-450: 450ms;
54
  /* Duration 400ms */
55
  --md-sys-motion-duration-400: 400ms;
56
  /* Duration 350ms */
57
  --md-sys-motion-duration-350: 350ms;
58
  /* Duration 300ms */
59
  --md-sys-motion-duration-300: 300ms;
60
  /* Duration 250ms */
61
  --md-sys-motion-duration-250: 250ms;
62
  /* Duration 200ms */
63
  --md-sys-motion-duration-200: 200ms;
64
  /* Duration 150ms */
65
  --md-sys-motion-duration-150: 150ms;
66
  /* Duration 100ms */
67
  --md-sys-motion-duration-100: 100ms;
68
  /* Duration 50ms */
69
  --md-sys-motion-duration-50: 50ms;
70
  /* Standard easing (in and out) */
71
  --md-sys-motion-easing-standard-x0: 0.20000000298023224;
72
  --md-sys-motion-easing-standard-y0: 0;
73
  --md-sys-motion-easing-standard-x1: 0;
74
  --md-sys-motion-easing-standard-y1: 1;
75
  /* Linear easing */
76
  --md-sys-motion-easing-linear-x0: 0;
77
  --md-sys-motion-easing-linear-y0: 0;
78
  --md-sys-motion-easing-linear-x1: 1;
79
  --md-sys-motion-easing-linear-y1: 1;
80
  /* Emphasized */
81
  --md-sys-motion-easing-emphasized-x0: 0.20000000298023224;
82
  --md-sys-motion-easing-emphasized-y0: 0;
83
  --md-sys-motion-easing-emphasized-x1: 0;
84
  --md-sys-motion-easing-emphasized-y1: 1;
85
  /* Motion path */
86
  --md-sys-motion-path-standard-path: 1;
87
}
88
.duration-50 {
89
  transition-duration: var(--md-sys-motion-duration-50);
90
}
91
.duration-100 {
92
  transition-duration: var(--md-sys-motion-duration-100);
93
}
94
.duration-150 {
95
  transition-duration: var(--md-sys-motion-duration-150);
96
}
97
.duration-200 {
98
  transition-duration: var(--md-sys-motion-duration-200);
99
}
100
.duration-250 {
101
  transition-duration: var(--md-sys-motion-duration-250);
102
}
103
.duration-300 {
104
  transition-duration: var(--md-sys-motion-duration-300);
105
}
106
.duration-350 {
107
  transition-duration: var(--md-sys-motion-duration-350);
108
}
109
.duration-400 {
110
  transition-duration: var(--md-sys-motion-duration-400);
111
}
112
.duration-450 {
113
  transition-duration: var(--md-sys-motion-duration-450);
114
}
115
.duration-500 {
116
  transition-duration: var(--md-sys-motion-duration-500);
117
}
118
.duration-550 {
119
  transition-duration: var(--md-sys-motion-duration-550);
120
}
121
.duration-600 {
122
  transition-duration: var(--md-sys-motion-duration-600);
123
}
124
.duration-700 {
125
  transition-duration: var(--md-sys-motion-duration-700);
126
}
127
.duration-800 {
128
  transition-duration: var(--md-sys-motion-duration-800);
129
}
130
.duration-900 {
131
  transition-duration: var(--md-sys-motion-duration-900);
132
}
133
.duration-1000 {
134
  transition-duration: var(--md-sys-motion-duration-1000);
135
}
136
.easing-standard {
137
  transition-timing-function: cubic-bezier(
138
    var(--md-sys-motion-easing-standard-x0),
139
    var(--md-sys-motion-easing-standard-y0),
140
    var(--md-sys-motion-easing-standard-x1),
141
    var(--md-sys-motion-easing-standard-y1)
142
  );
143
}
144
.easing-linear {
145
  transition-timing-function: cubic-bezier(
146
    var(--md-sys-motion-easing-linear-x0),
147
    var(--md-sys-motion-easing-linear-y0),
148
    var(--md-sys-motion-easing-linear-x1),
149
    var(--md-sys-motion-easing-linear-y1)
150
  );
151
}
152
.easing-standard-accelerate {
153
  transition-timing-function: cubic-bezier(
154
    var(--md-sys-motion-easing-standard-accelerate-x0),
155
    var(--md-sys-motion-easing-standard-accelerate-y0),
156
    var(--md-sys-motion-easing-standard-accelerate-x1),
157
    var(--md-sys-motion-easing-standard-accelerate-y1)
158
  );
159
}
160
.easing-standard-decelerate {
161
  transition-timing-function: cubic-bezier(
162
    var(--md-sys-motion-easing-standard-decelerate-x0),
163
    var(--md-sys-motion-easing-standard-decelerate-y0),
164
    var(--md-sys-motion-easing-standard-decelerate-x1),
165
    var(--md-sys-motion-easing-standard-decelerate-y1)
166
  );
167
}
168
.easing-emphasized {
169
  transition-timing-function: cubic-bezier(
170
    var(--md-sys-motion-easing-emphasized-x0),
171
    var(--md-sys-motion-easing-emphasized-y0),
172
    var(--md-sys-motion-easing-emphasized-x1),
173
    var(--md-sys-motion-easing-emphasized-y1)
174
  );
175
}
176

J. css / palette.css

1
/*
2
 Copyright 2016 Google Inc. All rights reserved.
3
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at
7
8
     http://www.apache.org/licenses/LICENSE-2.0
9
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
*/
16
17
:root {
18
  /* Error 0 */
19
  --md-ref-palette-error0: #000000ff;
20
  /* Error 10 */
21
  --md-ref-palette-error10: #410e0bff;
22
  /* Error 20 */
23
  --md-ref-palette-error20: #601410ff;
24
  /* Error 30 */
25
  --md-ref-palette-error30: #8c1d18ff;
26
  /* Error 40 */
27
  --md-ref-palette-error40: #b3261eff;
28
  /* Error 50 */
29
  --md-ref-palette-error50: #dc362eff;
30
  /* Error 60 */
31
  --md-ref-palette-error60: #e46962ff;
32
  /* Error 70 */
33
  --md-ref-palette-error70: #ec928eff;
34
  /* Error 80 */
35
  --md-ref-palette-error80: #f2b8b5ff;
36
  /* Error 90 */
37
  --md-ref-palette-error90: #f9dedcff;
38
  /* Error 95 */
39
  --md-ref-palette-error95: #fceeeeff;
40
  /* Error 99 */
41
  --md-ref-palette-error99: #fffbf9ff;
42
  /* Error 100 */
43
  --md-ref-palette-error100: #ffffffff;
44
  /* Tertiary 0 */
45
  --md-ref-palette-tertiary0: #000000ff;
46
  /* Tertiary 10 */
47
  --md-ref-palette-tertiary10: #31111dff;
48
  /* Tertiary 20 */
49
  --md-ref-palette-tertiary20: #492532ff;
50
  /* Tertiary 30 */
51
  --md-ref-palette-tertiary30: #633b48ff;
52
  /* Tertiary 40 */
53
  --md-ref-palette-tertiary40: #7d5260ff;
54
  /* Tertiary 50 */
55
  --md-ref-palette-tertiary50: #986977ff;
56
  /* Tertiary 60 */
57
  --md-ref-palette-tertiary60: #b58392ff;
58
  /* Tertiary 70 */
59
  --md-ref-palette-tertiary70: #d29dacff;
60
  /* Tertiary 80 */
61
  --md-ref-palette-tertiary80: #efb8c8ff;
62
  /* Tertiary 90 */
63
  --md-ref-palette-tertiary90: #ffd8e4ff;
64
  /* Tertiary 95 */
65
  --md-ref-palette-tertiary95: #ffecf1ff;
66
  /* Tertiary 99 */
67
  --md-ref-palette-tertiary99: #fffbfaff;
68
  /* Tertiary 100 */
69
  --md-ref-palette-tertiary100: #ffffffff;
70
  /* Secondary 0 */
71
  --md-ref-palette-secondary0: #000000ff;
72
  /* Secondary 10 */
73
  --md-ref-palette-secondary10: #1d192bff;
74
  /* Secondary 20 */
75
  --md-ref-palette-secondary20: #332d41ff;
76
  /* Secondary 30 */
77
  --md-ref-palette-secondary30: #4a4458ff;
78
  /* Secondary 40 */
79
  --md-ref-palette-secondary40: #625b71ff;
80
  /* Secondary 50 */
81
  --md-ref-palette-secondary50: #7a7289ff;
82
  /* Secondary 60 */
83
  --md-ref-palette-secondary60: #958da5ff;
84
  /* Secondary 70 */
85
  --md-ref-palette-secondary70: #b0a7c0ff;
86
  /* Secondary 80 */
87
  --md-ref-palette-secondary80: #ccc2dcff;
88
  /* Secondary 90 */
89
  --md-ref-palette-secondary90: #e8def8ff;
90
  /* Secondary 95 */
91
  --md-ref-palette-secondary95: #f6edffff;
92
  /* Secondary 99 */
93
  --md-ref-palette-secondary99: #fffbfeff;
94
  /* Secondary 100 */
95
  --md-ref-palette-secondary100: #ffffffff;
96
  /* Primary 0 */
97
  --md-ref-palette-primary0: #000000ff;
98
  /* Primary 10 */
99
  --md-ref-palette-primary10: #21005dff;
100
  /* Primary 20 */
101
  --md-ref-palette-primary20: #381e72ff;
102
  /* Primary 30 */
103
  --md-ref-palette-primary30: #4f378bff;
104
  /* Primary 40 */
105
  --md-ref-palette-primary40: #6750a4ff;
106
  /* Primary 50 */
107
  --md-ref-palette-primary50: #7f67beff;
108
  /* Primary 60 */
109
  --md-ref-palette-primary60: #9a82dbff;
110
  /* Primary 70 */
111
  --md-ref-palette-primary70: #b69df8ff;
112
  /* Primary 80 */
113
  --md-ref-palette-primary80: #d0bcffff;
114
  /* Primary 90 */
115
  --md-ref-palette-primary90: #eaddffff;
116
  /* Primary 95 */
117
  --md-ref-palette-primary95: #f6edffff;
118
  /* Primary 99 */
119
  --md-ref-palette-primary99: #fffbfeff;
120
  /* Primary 100 */
121
  --md-ref-palette-primary100: #ffffffff;
122
  /* Neutral Variant 0 */
123
  --md-ref-palette-neutral-variant0: #000000ff;
124
  /* Neutral Variant 10 */
125
  --md-ref-palette-neutral-variant10: #1d1a22ff;
126
  /* Neutral Variant 20 */
127
  --md-ref-palette-neutral-variant20: #322f37ff;
128
  /* Neutral Variant 30 */
129
  --md-ref-palette-neutral-variant30: #49454fff;
130
  /* Neutral Variant 40 */
131
  --md-ref-palette-neutral-variant40: #605d66ff;
132
  /* Neutral Variant 50 */
133
  --md-ref-palette-neutral-variant50: #79747eff;
134
  /* Neutral Variant 60 */
135
  --md-ref-palette-neutral-variant60: #938f99ff;
136
  /* Neutral Variant 70 */
137
  --md-ref-palette-neutral-variant70: #aea9b4ff;
138
  /* Neutral Variant 80 */
139
  --md-ref-palette-neutral-variant80: #cac4d0ff;
140
  /* Neutral Variant 90 */
141
  --md-ref-palette-neutral-variant90: #e7e0ecff;
142
  /* Neutral Variant 95 */
143
  --md-ref-palette-neutral-variant95: #f5eefaff;
144
  /* Neutral Variant 99 */
145
  --md-ref-palette-neutral-variant99: #fffbfeff;
146
  /* Neutral Variant 100 */
147
  --md-ref-palette-neutral-variant100: #ffffffff;
148
  /* Neutral 0 */
149
  --md-ref-palette-neutral0: #000000ff;
150
  /* Neutral 10 */
151
  --md-ref-palette-neutral10: #1c1b1fff;
152
  /* Neutral 20 */
153
  --md-ref-palette-neutral20: #313033ff;
154
  /* Neutral 30 */
155
  --md-ref-palette-neutral30: #484649ff;
156
  /* Neutral 40 */
157
  --md-ref-palette-neutral40: #605d62ff;
158
  /* Neutral 50 */
159
  --md-ref-palette-neutral50: #787579ff;
160
  /* Neutral 60 */
161
  --md-ref-palette-neutral60: #939094ff;
162
  /* Neutral 70 */
163
  --md-ref-palette-neutral70: #aeaaaeff;
164
  /* Neutral 80 */
165
  --md-ref-palette-neutral80: #c9c5caff;
166
  /* Neutral 90 */
167
  --md-ref-palette-neutral90: #e6e1e5ff;
168
  /* Neutral 95 */
169
  --md-ref-palette-neutral95: #f4eff4ff;
170
  /* Neutral 99 */
171
  --md-ref-palette-neutral99: #fffbfeff;
172
  /* Neutral 100 */
173
  --md-ref-palette-neutral100: #ffffffff;
174
  /* Black */
175
  --md-ref-palette-black: #000000ff;
176
  /* White */
177
  --md-ref-palette-white: #ffffffff;
178
}
179

K. css / roboto.css

1
/* roboto-regular - latin */
2
@font-face {
3
 /* Revisa
4
  * https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display
5
  * para otras opciones. */
6
 font-display: swap;
7
 font-family: 'Roboto';
8
 font-style: normal;
9
 font-weight: 400;
10
 /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
11
 src: url('../fonts/roboto-v32-latin-regular.woff2') format('woff2');
12
}

L. css / shape.css

1
/*
2
 Copyright 2016 Google Inc. All rights reserved.
3
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at
7
8
     http://www.apache.org/licenses/LICENSE-2.0
9
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
*/
16
17
:root {
18
  /* Fully rounded */
19
  --md-sys-shape-corner-full-family: 3px;
20
  /* Extra large top rounding */
21
  --md-sys-shape-corner-extra-large-top-family: 1px;
22
  --md-sys-shape-corner-extra-large-top-default-size: 0px;
23
  --md-sys-shape-corner-extra-large-top-top-left: 28px;
24
  --md-sys-shape-corner-extra-large-top-top-right-unit: 1px;
25
  --md-sys-shape-corner-extra-large-top-top-right: 28px;
26
  /* Extra large rounding */
27
  --md-sys-shape-corner-extra-large-family: 1px;
28
  --md-sys-shape-corner-extra-large-default-size-unit: 1px;
29
  --md-sys-shape-corner-extra-large-default-size: 28px;
30
  /* Large top rounding */
31
  --md-sys-shape-corner-large-top-family: 1px;
32
  --md-sys-shape-corner-large-top-default-size-unit: 1px;
33
  --md-sys-shape-corner-large-top-default-size: 0px;
34
  --md-sys-shape-corner-large-top-top-left-unit: 1px;
35
  --md-sys-shape-corner-large-top-top-left: 16px;
36
  --md-sys-shape-corner-large-top-top-right-unit: 1px;
37
  --md-sys-shape-corner-large-top-top-right: 16px;
38
  /* Large end rounding */
39
  --md-sys-shape-corner-large-end-family: 1px;
40
  --md-sys-shape-corner-large-end-default-size-unit: 1px;
41
  --md-sys-shape-corner-large-end-default-size: 0px;
42
  --md-sys-shape-corner-large-end-top-right-unit: 1px;
43
  --md-sys-shape-corner-large-end-top-right: 16px;
44
  --md-sys-shape-corner-large-end-bottom-right-unit: 1px;
45
  --md-sys-shape-corner-large-end-bottom-right: 16px;
46
  /* Large rounding */
47
  --md-sys-shape-corner-large-family: 1px;
48
  --md-sys-shape-corner-large-default-size-unit: 1px;
49
  --md-sys-shape-corner-large-default-size: 16px;
50
  /* Medium rounding */
51
  --md-sys-shape-corner-medium-family: 1px;
52
  --md-sys-shape-corner-medium-default-size-unit: 1px;
53
  --md-sys-shape-corner-medium-default-size: 12px;
54
  /* Small rounding */
55
  --md-sys-shape-corner-small-family: 1px;
56
  --md-sys-shape-corner-small-default-size-unit: 1px;
57
  --md-sys-shape-corner-small-default-size: 8px;
58
  /* Extra small top rounding */
59
  --md-sys-shape-corner-extra-small-top-family: 1px;
60
  --md-sys-shape-corner-extra-small-top-default-size-unit: 1px;
61
  --md-sys-shape-corner-extra-small-top-default-size: 0px;
62
  --md-sys-shape-corner-extra-small-top-top-left-unit: 1px;
63
  --md-sys-shape-corner-extra-small-top-top-left: 4px;
64
  --md-sys-shape-corner-extra-small-top-top-right-unit: 1px;
65
  --md-sys-shape-corner-extra-small-top-top-right: 4px;
66
  /* Extra small rounding */
67
  --md-sys-shape-corner-extra-small-family: 1px;
68
  --md-sys-shape-corner-extra-small-default-size-unit: 1px;
69
  --md-sys-shape-corner-extra-small-default-size: 4px;
70
  /* No rounding */
71
  --md-sys-shape-corner-none-family: 1px;
72
  --md-sys-shape-corner-none-default-size-unit: 1px;
73
  --md-sys-shape-corner-none-default-size: 0px;
74
75
  --md-sys-shape-small: var(--md-sys-shape-corner-small-default-size);
76
  --md-sys-shape-medium: var(--md-sys-shape-corner-medium-default-size);
77
  --md-sys-shape-large: var(--md-sys-shape-corner-large-default-size);
78
}
79
80
.shape-none {
81
  border-radius: var(--md-sys-shape-corner-none-default-size);
82
}
83
.shape-extra-small {
84
  border-radius: var(--md-sys-shape-corner-extra-small-default-size);
85
}
86
.shape-small {
87
  border-radius: var(--md-sys-shape-corner-small-default-size);
88
}
89
.shape-medium {
90
  border-radius: var(--md-sys-shape-corner-medium-default-size);
91
}
92
.shape-large {
93
  border-radius: var(--md-sys-shape-corner-large-default-size);
94
}
95
.shape-extra-large {
96
  border-radius: var(--md-sys-shape-corner-extra-large-default-size);
97
}
98
.extra-small-top {
99
  border-top-left-radius: var(--md-sys-shape-corner-extra-small-top-top-left);
100
  border-top-right-radius: var(--md-sys-shape-corner-extra-small-top-top-right);
101
}
102
.large-end {
103
  border-top-right-radius: var(--md-sys-shape-corner-large-end-top-right);
104
  border-bottom-right-radius: var(--md-sys-shape-corner-large-end-bottom-right);
105
}
106
.large-top {
107
  border-top-left-radius: var(--md-sys-shape-corner-large-top-top-left);
108
  border-top-right-radius: var(--md-sys-shape-corner-large-top-top-right);
109
}
110
.extra-large-top {
111
  border-top-left-radius: var(--md-sys-shape-corner-extra-large-top-top-left);
112
  border-top-right-radius: var(--md-sys-shape-corner-extra-large-top-top-right);
113
}
114

M. css / state.css

1
/*
2
 Copyright 2016 Google Inc. All rights reserved.
3
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at
7
8
     http://www.apache.org/licenses/LICENSE-2.0
9
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
*/
16
17
:root {
18
  /* Dragged state layer opacity */
19
  --md-sys-state-dragged-state-layer-opacity: 0.1599999964237213;
20
  /* Pressed state layer opacity */
21
  --md-sys-state-pressed-state-layer-opacity: 0.11999999731779099;
22
  /* Focus state layer opacity */
23
  --md-sys-state-focus-state-layer-opacity: 0.11999999731779099;
24
  /* Hover state layer opacity */
25
  --md-sys-state-hover-state-layer-opacity: 0.07999999821186066;
26
}
27
.hover-state-layer {
28
  opacity: var(--md-sys-state-hover-state-layer-opacity);
29
}
30
.pressed-state-layer {
31
  opacity: var(--md-sys-state-pressed-state-layer-opacity);
32
}
33
.dragged-state-layer {
34
  opacity: var(--md-sys-state-dragged-state-layer-opacity);
35
}
36
.focus-state-layer {
37
  opacity: var(--md-sys-state-focus-state-layer-opacity);
38
}
39

N. css / transicion_pestanas.css

1
@view-transition {
2
 navigation: auto;
3
}
4
5
#headline {
6
 view-transition-name: encabezado;
7
}
8
9
main {
10
 view-transition-name: contenido;
11
}
12
13
::view-transition-group(encabezado) {
14
 animation-duration: var(--md-sys-motion-duration-1000);
15
}
16
17
::view-transition-group(contenido) {
18
 animation-duration: var(--md-sys-motion-duration-1000);
19
}
20
21
html::view-transition-old(encabezado) {
22
 animation-name: salePorLaIzquierda;
23
}
24
25
html::view-transition-new(encabezado) {
26
 animation-name: entraPorLaDerecha;
27
}
28
29
html::view-transition-old(contenido) {
30
 animation-name: salePorLaIzquierda;
31
}
32
33
html::view-transition-new(contenido) {
34
 animation-duration: var(--md-sys-motion-duration-700);
35
 animation-name: entraPorLaDerecha;
36
}

O. css / typography.css

1
/*
2
 Copyright 2016 Google Inc. All rights reserved.
3
4
 Licensed under the Apache License, Version 2.0 (the "License");
5
 you may not use this file except in compliance with the License.
6
 You may obtain a copy of the License at
7
8
     http://www.apache.org/licenses/LICENSE-2.0
9
10
 Unless required by applicable law or agreed to in writing, software
11
 distributed under the License is distributed on an "AS IS" BASIS,
12
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 See the License for the specific language governing permissions and
14
 limitations under the License.
15
*/
16
17
/* This file is generated */
18
19
/* DO NOT EDIT */
20
21
:root {
22
  /* Label Small */
23
  --md-sys-typescale-label-small-text-transform: unset;
24
  --md-sys-typescale-label-small-axis-value: unset;
25
  --md-sys-typescale-label-small-font-style: unset;
26
  --md-sys-typescale-label-small-text-decoration: unset;
27
  /* Label Small line height */
28
  --md-sys-typescale-label-small-line-height-value: 16px;
29
  --md-sys-typescale-label-small-line-height-unit: 2px;
30
  --md-sys-typescale-label-small-line-height: 16px;
31
  /* Label Small font tracking */
32
  --md-sys-typescale-label-small-tracking-value: 0.5px;
33
  --md-sys-typescale-label-small-tracking-unit: 2px;
34
  --md-sys-typescale-label-small-tracking: 0.5px;
35
  /* Label Small font size */
36
  --md-sys-typescale-label-small-size-value: 11px;
37
  --md-sys-typescale-label-small-size-unit: 2px;
38
  --md-sys-typescale-label-small-size: 11px;
39
  /* Label Small font weight */
40
  --md-sys-typescale-label-small-weight: var(--md-ref-typeface-weight-medium);
41
  /* Label Small font name */
42
  --md-sys-typescale-label-small-font: var(--md-ref-typeface-plain);
43
  /* Label Medium */
44
  --md-sys-typescale-label-medium-axis-value: unset;
45
  --md-sys-typescale-label-medium-font-style: unset;
46
  --md-sys-typescale-label-medium-text-decoration: unset;
47
  /* Label Medium text transform */
48
  --md-sys-typescale-label-medium-text-transform: 1;
49
  /* Label Medium line height */
50
  --md-sys-typescale-label-medium-line-height-value: 16px;
51
  --md-sys-typescale-label-medium-line-height-unit: 2px;
52
  --md-sys-typescale-label-medium-line-height: 16px;
53
  /* Label Medium font tracking */
54
  --md-sys-typescale-label-medium-tracking-value: 0.5px;
55
  --md-sys-typescale-label-medium-tracking-unit: 2px;
56
  --md-sys-typescale-label-medium-tracking: 0.5px;
57
  /* Label Medium font size */
58
  --md-sys-typescale-label-medium-size-value: 12px;
59
  --md-sys-typescale-label-medium-size-unit: 2px;
60
  --md-sys-typescale-label-medium-size: 12px;
61
  /* Label Medium font weight */
62
  --md-sys-typescale-label-medium-weight: var(--md-ref-typeface-weight-medium);
63
  /* Label Medium font name */
64
  --md-sys-typescale-label-medium-font: var(--md-ref-typeface-plain);
65
  /* Label Large */
66
  --md-sys-typescale-label-large-text-transform: unset;
67
  --md-sys-typescale-label-large-axis-value: unset;
68
  --md-sys-typescale-label-large-font-style: unset;
69
  --md-sys-typescale-label-large-text-decoration: unset;
70
  /* Label Large line height */
71
  --md-sys-typescale-label-large-line-height-value: 20px;
72
  --md-sys-typescale-label-large-line-height-unit: 2px;
73
  --md-sys-typescale-label-large-line-height: 20px;
74
  /* Label Large font tracking */
75
  --md-sys-typescale-label-large-tracking-value: 0.10000000149011612px;
76
  --md-sys-typescale-label-large-tracking-unit: 2px;
77
  --md-sys-typescale-label-large-tracking: 0.10000000149011612px;
78
  /* Label Large font size */
79
  --md-sys-typescale-label-large-size-value: 14px;
80
  --md-sys-typescale-label-large-size-unit: 2px;
81
  --md-sys-typescale-label-large-size: 14px;
82
  /* Label Large font weight */
83
  --md-sys-typescale-label-large-weight: var(--md-ref-typeface-weight-medium);
84
  /* Label Large font name */
85
  --md-sys-typescale-label-large-font: var(--md-ref-typeface-plain);
86
  /* Body Small */
87
  --md-sys-typescale-body-small-text-transform: unset;
88
  --md-sys-typescale-body-small-axis-value: unset;
89
  --md-sys-typescale-body-small-font-style: unset;
90
  --md-sys-typescale-body-small-text-decoration: unset;
91
  /* Body Small line height */
92
  --md-sys-typescale-body-small-line-height-value: 16px;
93
  --md-sys-typescale-body-small-line-height-unit: 2px;
94
  --md-sys-typescale-body-small-line-height: 16px;
95
  /* Body Small font tracking */
96
  --md-sys-typescale-body-small-tracking-value: 0.4000000059604645px;
97
  --md-sys-typescale-body-small-tracking-unit: 2px;
98
  --md-sys-typescale-body-small-tracking: 0.4000000059604645px;
99
  /* Body Small font size */
100
  --md-sys-typescale-body-small-size-value: 12px;
101
  --md-sys-typescale-body-small-size-unit: 2px;
102
  --md-sys-typescale-body-small-size: 12px;
103
  /* Body Small font weight */
104
  --md-sys-typescale-body-small-weight: var(--md-ref-typeface-weight-regular);
105
  /* Body Small font name */
106
  --md-sys-typescale-body-small-font: var(--md-ref-typeface-plain);
107
  /* Body Medium */
108
  --md-sys-typescale-body-medium-text-transform: unset;
109
  --md-sys-typescale-body-medium-axis-value: unset;
110
  --md-sys-typescale-body-medium-font-style: unset;
111
  --md-sys-typescale-body-medium-text-decoration: unset;
112
  /* Body Medium line height */
113
  --md-sys-typescale-body-medium-line-height-value: 20px;
114
  --md-sys-typescale-body-medium-line-height-unit: 2px;
115
  --md-sys-typescale-body-medium-line-height: 20px;
116
  /* Body Medium font tracking */
117
  --md-sys-typescale-body-medium-tracking-value: 0.25px;
118
  --md-sys-typescale-body-medium-tracking-unit: 2px;
119
  --md-sys-typescale-body-medium-tracking: 0.25px;
120
  /* Body Medium font size */
121
  --md-sys-typescale-body-medium-size-value: 14px;
122
  --md-sys-typescale-body-medium-size-unit: 2px;
123
  --md-sys-typescale-body-medium-size: 14px;
124
  /* Body Medium font weight */
125
  --md-sys-typescale-body-medium-weight: var(--md-ref-typeface-weight-regular);
126
  /* Body Medium font name */
127
  --md-sys-typescale-body-medium-font: var(--md-ref-typeface-plain);
128
  /* Body Large */
129
  --md-sys-typescale-body-large-text-transform: unset;
130
  --md-sys-typescale-body-large-axis-value: unset;
131
  --md-sys-typescale-body-large-font-style: unset;
132
  --md-sys-typescale-body-large-text-decoration: unset;
133
  /* Body Large line height */
134
  --md-sys-typescale-body-large-line-height-value: 24px;
135
  --md-sys-typescale-body-large-line-height-unit: 2px;
136
  --md-sys-typescale-body-large-line-height: 24px;
137
  /* Body Large font tracking */
138
  --md-sys-typescale-body-large-tracking-value: 0.5px;
139
  --md-sys-typescale-body-large-tracking-unit: 2px;
140
  --md-sys-typescale-body-large-tracking: 0.5px;
141
  /* Body Large font size */
142
  --md-sys-typescale-body-large-size-value: 16px;
143
  --md-sys-typescale-body-large-size-unit: 2px;
144
  --md-sys-typescale-body-large-size: 16px;
145
  /* Body Large font weight */
146
  --md-sys-typescale-body-large-weight: var(--md-ref-typeface-weight-regular);
147
  /* Body Large font name */
148
  --md-sys-typescale-body-large-font: var(--md-ref-typeface-plain);
149
  /* Title Small */
150
  --md-sys-typescale-title-small-text-transform: unset;
151
  --md-sys-typescale-title-small-axis-value: unset;
152
  --md-sys-typescale-title-small-font-style: unset;
153
  --md-sys-typescale-title-small-text-decoration: unset;
154
  /* Title Small line height */
155
  --md-sys-typescale-title-small-line-height-value: 20px;
156
  --md-sys-typescale-title-small-line-height-unit: 2px;
157
  --md-sys-typescale-title-small-line-height: 20px;
158
  /* Title Small font tracking */
159
  --md-sys-typescale-title-small-tracking-value: 0.10000000149011612px;
160
  --md-sys-typescale-title-small-tracking-unit: 2px;
161
  --md-sys-typescale-title-small-tracking: 0.10000000149011612px;
162
  /* Title Small font size */
163
  --md-sys-typescale-title-small-size-value: 14px;
164
  --md-sys-typescale-title-small-size-unit: 2px;
165
  --md-sys-typescale-title-small-size: 14px;
166
  /* Title Small font weight */
167
  --md-sys-typescale-title-small-weight: var(--md-ref-typeface-weight-medium);
168
  /* Title Small font name */
169
  --md-sys-typescale-title-small-font: var(--md-ref-typeface-plain);
170
  /* Title Medium */
171
  --md-sys-typescale-title-medium-text-transform: unset;
172
  --md-sys-typescale-title-medium-axis-value: unset;
173
  --md-sys-typescale-title-medium-font-style: unset;
174
  --md-sys-typescale-title-medium-text-decoration: unset;
175
  /* Title Medium line height */
176
  --md-sys-typescale-title-medium-line-height-value: 24px;
177
  --md-sys-typescale-title-medium-line-height-unit: 2px;
178
  --md-sys-typescale-title-medium-line-height: 24px;
179
  /* Title Medium font tracking */
180
  --md-sys-typescale-title-medium-tracking-value: 0.15000000596046448px;
181
  --md-sys-typescale-title-medium-tracking-unit: 2px;
182
  --md-sys-typescale-title-medium-tracking: 0.15000000596046448px;
183
  /* Title Medium font size */
184
  --md-sys-typescale-title-medium-size-value: 16px;
185
  --md-sys-typescale-title-medium-size-unit: 2px;
186
  --md-sys-typescale-title-medium-size: 16px;
187
  /* Title Medium font weight */
188
  --md-sys-typescale-title-medium-weight: var(--md-ref-typeface-weight-medium);
189
  /* Title Medium font name */
190
  --md-sys-typescale-title-medium-font: var(--md-ref-typeface-plain);
191
  /* Title Large */
192
  --md-sys-typescale-title-large-text-transform: unset;
193
  --md-sys-typescale-title-large-axis-value: unset;
194
  --md-sys-typescale-title-large-font-style: unset;
195
  --md-sys-typescale-title-large-text-decoration: unset;
196
  /* Title Large line height */
197
  --md-sys-typescale-title-large-line-height-value: 28px;
198
  --md-sys-typescale-title-large-line-height-unit: 2px;
199
  --md-sys-typescale-title-large-line-height: 28px;
200
  /* Title Large font tracking */
201
  --md-sys-typescale-title-large-tracking-value: 0px;
202
  --md-sys-typescale-title-large-tracking-unit: 2px;
203
  --md-sys-typescale-title-large-tracking: 0px;
204
  /* Title Large font size */
205
  --md-sys-typescale-title-large-size-value: 22px;
206
  --md-sys-typescale-title-large-size-unit: 2px;
207
  --md-sys-typescale-title-large-size: 22px;
208
  /* Title Large font weight */
209
  --md-sys-typescale-title-large-weight: var(--md-ref-typeface-weight-regular);
210
  /* Title Large font name */
211
  --md-sys-typescale-title-large-font: var(--md-ref-typeface-brand);
212
  /* Headline Small */
213
  --md-sys-typescale-headline-small-text-transform: unset;
214
  --md-sys-typescale-headline-small-axis-value: unset;
215
  --md-sys-typescale-headline-small-font-style: unset;
216
  --md-sys-typescale-headline-small-text-decoration: unset;
217
  /* Headline Small line height */
218
  --md-sys-typescale-headline-small-line-height-value: 32px;
219
  --md-sys-typescale-headline-small-line-height-unit: 2px;
220
  --md-sys-typescale-headline-small-line-height: 32px;
221
  /* Headline Small font tracking */
222
  --md-sys-typescale-headline-small-tracking-value: 0px;
223
  --md-sys-typescale-headline-small-tracking-unit: 2px;
224
  --md-sys-typescale-headline-small-tracking: 0px;
225
  /* Headline Small font size */
226
  --md-sys-typescale-headline-small-size-value: 24px;
227
  --md-sys-typescale-headline-small-size-unit: 2px;
228
  --md-sys-typescale-headline-small-size: 24px;
229
  /* Headline Small font weight */
230
  --md-sys-typescale-headline-small-weight: var(
231
    --md-ref-typeface-weight-regular
232
  );
233
  /* Headline Small font name */
234
  --md-sys-typescale-headline-small-font: var(--md-ref-typeface-brand);
235
  /* Headline Medium */
236
  --md-sys-typescale-headline-medium-text-transform: unset;
237
  --md-sys-typescale-headline-medium-axis-value: unset;
238
  --md-sys-typescale-headline-medium-font-style: unset;
239
  --md-sys-typescale-headline-medium-text-decoration: unset;
240
  /* Headline Medium line height */
241
  --md-sys-typescale-headline-medium-line-height-value: 36px;
242
  --md-sys-typescale-headline-medium-line-height-unit: 2px;
243
  --md-sys-typescale-headline-medium-line-height: 36px;
244
  /* Headline Medium font tracking */
245
  --md-sys-typescale-headline-medium-tracking-value: 0px;
246
  --md-sys-typescale-headline-medium-tracking-unit: 2px;
247
  --md-sys-typescale-headline-medium-tracking: 0px;
248
  /* Headline Medium font size */
249
  --md-sys-typescale-headline-medium-size-value: 28px;
250
  --md-sys-typescale-headline-medium-size-unit: 2px;
251
  --md-sys-typescale-headline-medium-size: 28px;
252
  /* Headline Medium font weight */
253
  --md-sys-typescale-headline-medium-weight: var(
254
    --md-ref-typeface-weight-regular
255
  );
256
  /* Headline Medium font name */
257
  --md-sys-typescale-headline-medium-font: var(--md-ref-typeface-brand);
258
  /* Headline Large */
259
  --md-sys-typescale-headline-large-text-transform: unset;
260
  --md-sys-typescale-headline-large-axis-value: unset;
261
  --md-sys-typescale-headline-large-font-style: unset;
262
  --md-sys-typescale-headline-large-text-decoration: unset;
263
  /* Headline Large line height */
264
  --md-sys-typescale-headline-large-line-height-value: 40px;
265
  --md-sys-typescale-headline-large-line-height-unit: 2px;
266
  --md-sys-typescale-headline-large-line-height: 40px;
267
  /* Headline Large font tracking */
268
  --md-sys-typescale-headline-large-tracking-value: 0px;
269
  --md-sys-typescale-headline-large-tracking-unit: 2px;
270
  --md-sys-typescale-headline-large-tracking: 0px;
271
  /* Headline Large font size */
272
  --md-sys-typescale-headline-large-size-value: 32px;
273
  --md-sys-typescale-headline-large-size-unit: 2px;
274
  --md-sys-typescale-headline-large-size: 32px;
275
  /* Headline Large font name */
276
  --md-sys-typescale-headline-large-font: var(--md-ref-typeface-brand);
277
  /* Headline Large font weight */
278
  --md-sys-typescale-headline-large-weight: var(
279
    --md-ref-typeface-weight-regular
280
  );
281
  /* Display Small */
282
  --md-sys-typescale-display-small-text-transform: unset;
283
  --md-sys-typescale-display-small-axis-value: unset;
284
  --md-sys-typescale-display-small-font-style: unset;
285
  --md-sys-typescale-display-small-text-decoration: unset;
286
  /* Display Small line height */
287
  --md-sys-typescale-display-small-line-height-value: 44px;
288
  --md-sys-typescale-display-small-line-height-unit: 2px;
289
  --md-sys-typescale-display-small-line-height: 44px;
290
  /* Display Small font tracking */
291
  --md-sys-typescale-display-small-tracking-value: 0px;
292
  --md-sys-typescale-display-small-tracking-unit: 2px;
293
  --md-sys-typescale-display-small-tracking: 0px;
294
  /* Display Small font size */
295
  --md-sys-typescale-display-small-size-value: 36px;
296
  --md-sys-typescale-display-small-size-unit: 2px;
297
  --md-sys-typescale-display-small-size: 36px;
298
  /* Display Small font weight */
299
  --md-sys-typescale-display-small-weight: var(
300
    --md-ref-typeface-weight-regular
301
  );
302
  /* Display Small font name */
303
  --md-sys-typescale-display-small-font: var(--md-ref-typeface-brand);
304
  /* Display Medium */
305
  --md-sys-typescale-display-medium-text-transform: unset;
306
  --md-sys-typescale-display-medium-axis-value: unset;
307
  --md-sys-typescale-display-medium-font-style: unset;
308
  --md-sys-typescale-display-medium-text-decoration: unset;
309
  /* Display Medium line height */
310
  --md-sys-typescale-display-medium-line-height-value: 52px;
311
  --md-sys-typescale-display-medium-line-height-unit: 2px;
312
  --md-sys-typescale-display-medium-line-height: 52px;
313
  /* Display Medium font tracking */
314
  --md-sys-typescale-display-medium-tracking-value: 0px;
315
  --md-sys-typescale-display-medium-tracking-unit: 2px;
316
  --md-sys-typescale-display-medium-tracking: 0px;
317
  /* Display Medium font size */
318
  --md-sys-typescale-display-medium-size-value: 45px;
319
  --md-sys-typescale-display-medium-size-unit: 2px;
320
  --md-sys-typescale-display-medium-size: 45px;
321
  /* Display Medium font weight */
322
  --md-sys-typescale-display-medium-weight: var(
323
    --md-ref-typeface-weight-regular
324
  );
325
  /* Display Medium font name */
326
  --md-sys-typescale-display-medium-font: var(--md-ref-typeface-brand);
327
  /* Display Large */
328
  --md-sys-typescale-display-large-text-transform: unset;
329
  --md-sys-typescale-display-large-axis-value: unset;
330
  --md-sys-typescale-display-large-font-style: unset;
331
  --md-sys-typescale-display-large-text-decoration: unset;
332
  /* Display Large line height */
333
  --md-sys-typescale-display-large-line-height-value: 64px;
334
  --md-sys-typescale-display-large-line-height-unit: 2px;
335
  --md-sys-typescale-display-large-line-height: 64px;
336
  /* Display Large font tracking */
337
  --md-sys-typescale-display-large-tracking-value: -0.25px;
338
  --md-sys-typescale-display-large-tracking-unit: 2px;
339
  --md-sys-typescale-display-large-tracking: -0.25px;
340
  /* Display Large font size */
341
  --md-sys-typescale-display-large-size-value: 57px;
342
  --md-sys-typescale-display-large-size-unit: 2px;
343
  --md-sys-typescale-display-large-size: 57px;
344
  /* Display Large font weight */
345
  --md-sys-typescale-display-large-weight: var(
346
    --md-ref-typeface-weight-regular
347
  );
348
  /* Display Large font name */
349
  --md-sys-typescale-display-large-font: var(--md-ref-typeface-brand);
350
  /* Plain typeface */
351
  --md-ref-typeface-plain: Roboto;
352
  /* Brand typeface */
353
  --md-ref-typeface-brand: Roboto;
354
  /* Bold weight */
355
  --md-ref-typeface-weight-bold: 700;
356
  /* Medium weight */
357
  --md-ref-typeface-weight-medium: 500;
358
  /* Regular weight */
359
  --md-ref-typeface-weight-regular: 400;
360
}
361
362
/* Label Small */
363
.label-small {
364
  font-family: var(--md-sys-typescale-label-small-font);
365
  font-weight: var(--md-sys-typescale-label-small-weight);
366
  font-size: var(--md-sys-typescale-label-small-size);
367
  font-style: var(--md-sys-typescale-label-small-font-style);
368
  letter-spacing: var(--md-sys-typescale-label-small-tracking);
369
  line-height: var(--md-sys-typescale-label-small-line-height);
370
  text-transform: var(--md-sys-typescale-label-small-text-transform);
371
  text-decoration: var(--md-sys-typescale-label-small-text-decoration);
372
}
373
/* Label Medium */
374
.label-medium {
375
  font-family: var(--md-sys-typescale-label-medium-font);
376
  font-weight: var(--md-sys-typescale-label-medium-weight);
377
  font-size: var(--md-sys-typescale-label-medium-size);
378
  font-style: var(--md-sys-typescale-label-medium-font-style);
379
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
380
  line-height: var(--md-sys-typescale-label-medium-line-height);
381
  text-transform: var(--md-sys-typescale-label-medium-text-transform);
382
  text-decoration: var(--md-sys-typescale-label-medium-text-decoration);
383
}
384
/* Label Large */
385
.label-large {
386
  font-family: var(--md-sys-typescale-label-large-font);
387
  font-weight: var(--md-sys-typescale-label-large-weight);
388
  font-size: var(--md-sys-typescale-label-large-size);
389
  font-style: var(--md-sys-typescale-label-large-font-style);
390
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
391
  line-height: var(--md-sys-typescale-label-large-line-height);
392
  text-transform: var(--md-sys-typescale-label-large-text-transform);
393
  text-decoration: var(--md-sys-typescale-label-large-text-decoration);
394
}
395
/* Body Small */
396
.body-small {
397
  font-family: var(--md-sys-typescale-body-small-font);
398
  font-weight: var(--md-sys-typescale-body-small-weight);
399
  font-size: var(--md-sys-typescale-body-small-size);
400
  font-style: var(--md-sys-typescale-body-small-font-style);
401
  letter-spacing: var(--md-sys-typescale-body-small-tracking);
402
  line-height: var(--md-sys-typescale-body-small-line-height);
403
  text-transform: var(--md-sys-typescale-body-small-text-transform);
404
  text-decoration: var(--md-sys-typescale-body-small-text-decoration);
405
}
406
/* Body Medium */
407
.body-medium {
408
  font-family: var(--md-sys-typescale-body-medium-font);
409
  font-weight: var(--md-sys-typescale-body-medium-weight);
410
  font-size: var(--md-sys-typescale-body-medium-size);
411
  font-style: var(--md-sys-typescale-body-medium-font-style);
412
  letter-spacing: var(--md-sys-typescale-body-medium-tracking);
413
  line-height: var(--md-sys-typescale-body-medium-line-height);
414
  text-transform: var(--md-sys-typescale-body-medium-text-transform);
415
  text-decoration: var(--md-sys-typescale-body-medium-text-decoration);
416
}
417
/* Body Large */
418
.body-large {
419
  font-family: var(--md-sys-typescale-body-large-font);
420
  font-weight: var(--md-sys-typescale-body-large-weight);
421
  font-size: var(--md-sys-typescale-body-large-size);
422
  font-style: var(--md-sys-typescale-body-large-font-style);
423
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
424
  line-height: var(--md-sys-typescale-body-large-line-height);
425
  text-transform: var(--md-sys-typescale-body-large-text-transform);
426
  text-decoration: var(--md-sys-typescale-body-large-text-decoration);
427
}
428
/* Title Small */
429
.title-small {
430
  font-family: var(--md-sys-typescale-title-small-font);
431
  font-weight: var(--md-sys-typescale-title-small-weight);
432
  font-size: var(--md-sys-typescale-title-small-size);
433
  font-style: var(--md-sys-typescale-title-small-font-style);
434
  letter-spacing: var(--md-sys-typescale-title-small-tracking);
435
  line-height: var(--md-sys-typescale-title-small-line-height);
436
  text-transform: var(--md-sys-typescale-title-small-text-transform);
437
  text-decoration: var(--md-sys-typescale-title-small-text-decoration);
438
}
439
/* Title Medium */
440
.title-medium {
441
  font-family: var(--md-sys-typescale-title-medium-font);
442
  font-weight: var(--md-sys-typescale-title-medium-weight);
443
  font-size: var(--md-sys-typescale-title-medium-size);
444
  font-style: var(--md-sys-typescale-title-medium-font-style);
445
  letter-spacing: var(--md-sys-typescale-title-medium-tracking);
446
  line-height: var(--md-sys-typescale-title-medium-line-height);
447
  text-transform: var(--md-sys-typescale-title-medium-text-transform);
448
  text-decoration: var(--md-sys-typescale-title-medium-text-decoration);
449
}
450
/* Title Large */
451
.title-large {
452
  font-family: var(--md-sys-typescale-title-large-font);
453
  font-weight: var(--md-sys-typescale-title-large-weight);
454
  font-size: var(--md-sys-typescale-title-large-size);
455
  font-style: var(--md-sys-typescale-title-large-font-style);
456
  letter-spacing: var(--md-sys-typescale-title-large-tracking);
457
  line-height: var(--md-sys-typescale-title-large-line-height);
458
  text-transform: var(--md-sys-typescale-title-large-text-transform);
459
  text-decoration: var(--md-sys-typescale-title-large-text-decoration);
460
}
461
/* Headline Small */
462
.headline-small {
463
  font-family: var(--md-sys-typescale-headline-small-font);
464
  font-weight: var(--md-sys-typescale-headline-small-weight);
465
  font-size: var(--md-sys-typescale-headline-small-size);
466
  font-style: var(--md-sys-typescale-headline-small-font-style);
467
  letter-spacing: var(--md-sys-typescale-headline-small-tracking);
468
  line-height: var(--md-sys-typescale-headline-small-line-height);
469
  text-transform: var(--md-sys-typescale-headline-small-text-transform);
470
  text-decoration: var(--md-sys-typescale-headline-small-text-decoration);
471
}
472
/* Headline Medium */
473
.headline-medium {
474
  font-family: var(--md-sys-typescale-headline-medium-font);
475
  font-weight: var(--md-sys-typescale-headline-medium-weight);
476
  font-size: var(--md-sys-typescale-headline-medium-size);
477
  font-style: var(--md-sys-typescale-headline-medium-font-style);
478
  letter-spacing: var(--md-sys-typescale-headline-medium-tracking);
479
  line-height: var(--md-sys-typescale-headline-medium-line-height);
480
  text-transform: var(--md-sys-typescale-headline-medium-text-transform);
481
  text-decoration: var(--md-sys-typescale-headline-medium-text-decoration);
482
}
483
/* Headline Large */
484
.headline-large {
485
  font-family: var(--md-sys-typescale-headline-large-font);
486
  font-weight: var(--md-sys-typescale-headline-large-weight);
487
  font-size: var(--md-sys-typescale-headline-large-size);
488
  font-style: var(--md-sys-typescale-headline-large-font-style);
489
  letter-spacing: var(--md-sys-typescale-headline-large-tracking);
490
  line-height: var(--md-sys-typescale-headline-large-line-height);
491
  text-transform: var(--md-sys-typescale-headline-large-text-transform);
492
  text-decoration: var(--md-sys-typescale-headline-large-text-decoration);
493
}
494
/* Display Small */
495
.display-small {
496
  font-family: var(--md-sys-typescale-display-small-font);
497
  font-weight: var(--md-sys-typescale-display-small-weight);
498
  font-size: var(--md-sys-typescale-display-small-size);
499
  font-style: var(--md-sys-typescale-display-small-font-style);
500
  letter-spacing: var(--md-sys-typescale-display-small-tracking);
501
  line-height: var(--md-sys-typescale-display-small-line-height);
502
  text-transform: var(--md-sys-typescale-display-small-text-transform);
503
  text-decoration: var(--md-sys-typescale-display-small-text-decoration);
504
}
505
/* Display Medium */
506
.display-medium {
507
  font-family: var(--md-sys-typescale-display-medium-font);
508
  font-weight: var(--md-sys-typescale-display-medium-weight);
509
  font-size: var(--md-sys-typescale-display-medium-size);
510
  font-style: var(--md-sys-typescale-display-medium-font-style);
511
  letter-spacing: var(--md-sys-typescale-display-medium-tracking);
512
  line-height: var(--md-sys-typescale-display-medium-line-height);
513
  text-transform: var(--md-sys-typescale-display-medium-text-transform);
514
  text-decoration: var(--md-sys-typescale-display-medium-text-decoration);
515
}
516
/* Display Large */
517
.display-large {
518
  font-family: var(--md-sys-typescale-display-large-font);
519
  font-weight: var(--md-sys-typescale-display-large-weight);
520
  font-size: var(--md-sys-typescale-display-large-size);
521
  font-style: var(--md-sys-typescale-display-large-font-style);
522
  letter-spacing: var(--md-sys-typescale-display-large-tracking);
523
  line-height: var(--md-sys-typescale-display-large-line-height);
524
  text-transform: var(--md-sys-typescale-display-large-text-transform);
525
  text-decoration: var(--md-sys-typescale-display-large-text-decoration);
526
}
527

P. Carpeta « css / theme »

1. css / theme / dark.css

1
.dark {
2
  --md-sys-color-primary: rgb(170 199 255);
3
  --md-sys-color-surface-tint: rgb(170 199 255);
4
  --md-sys-color-on-primary: rgb(10 48 95);
5
  --md-sys-color-primary-container: rgb(40 71 119);
6
  --md-sys-color-on-primary-container: rgb(214 227 255);
7
  --md-sys-color-secondary: rgb(190 198 220);
8
  --md-sys-color-on-secondary: rgb(40 49 65);
9
  --md-sys-color-secondary-container: rgb(62 71 89);
10
  --md-sys-color-on-secondary-container: rgb(218 226 249);
11
  --md-sys-color-tertiary: rgb(221 188 224);
12
  --md-sys-color-on-tertiary: rgb(63 40 68);
13
  --md-sys-color-tertiary-container: rgb(87 62 92);
14
  --md-sys-color-on-tertiary-container: rgb(250 216 253);
15
  --md-sys-color-error: rgb(255 180 171);
16
  --md-sys-color-on-error: rgb(105 0 5);
17
  --md-sys-color-error-container: rgb(147 0 10);
18
  --md-sys-color-on-error-container: rgb(255 218 214);
19
  --md-sys-color-background: rgb(17 19 24);
20
  --md-sys-color-on-background: rgb(226 226 233);
21
  --md-sys-color-surface: rgb(17 19 24);
22
  --md-sys-color-on-surface: rgb(226 226 233);
23
  --md-sys-color-surface-variant: rgb(68 71 78);
24
  --md-sys-color-on-surface-variant: rgb(196 198 208);
25
  --md-sys-color-outline: rgb(142 144 153);
26
  --md-sys-color-outline-variant: rgb(68 71 78);
27
  --md-sys-color-shadow: rgb(0 0 0);
28
  --md-sys-color-scrim: rgb(0 0 0);
29
  --md-sys-color-inverse-surface: rgb(226 226 233);
30
  --md-sys-color-inverse-on-surface: rgb(46 48 54);
31
  --md-sys-color-inverse-primary: rgb(65 95 145);
32
  --md-sys-color-primary-fixed: rgb(214 227 255);
33
  --md-sys-color-on-primary-fixed: rgb(0 27 62);
34
  --md-sys-color-primary-fixed-dim: rgb(170 199 255);
35
  --md-sys-color-on-primary-fixed-variant: rgb(40 71 119);
36
  --md-sys-color-secondary-fixed: rgb(218 226 249);
37
  --md-sys-color-on-secondary-fixed: rgb(19 28 43);
38
  --md-sys-color-secondary-fixed-dim: rgb(190 198 220);
39
  --md-sys-color-on-secondary-fixed-variant: rgb(62 71 89);
40
  --md-sys-color-tertiary-fixed: rgb(250 216 253);
41
  --md-sys-color-on-tertiary-fixed: rgb(40 19 46);
42
  --md-sys-color-tertiary-fixed-dim: rgb(221 188 224);
43
  --md-sys-color-on-tertiary-fixed-variant: rgb(87 62 92);
44
  --md-sys-color-surface-dim: rgb(17 19 24);
45
  --md-sys-color-surface-bright: rgb(55 57 62);
46
  --md-sys-color-surface-container-lowest: rgb(12 14 19);
47
  --md-sys-color-surface-container-low: rgb(25 28 32);
48
  --md-sys-color-surface-container: rgb(29 32 36);
49
  --md-sys-color-surface-container-high: rgb(40 42 47);
50
  --md-sys-color-surface-container-highest: rgb(51 53 58);
51
}
52

2. css / theme / light.css

1
.light {
2
  --md-sys-color-primary: rgb(65 95 145);
3
  --md-sys-color-surface-tint: rgb(65 95 145);
4
  --md-sys-color-on-primary: rgb(255 255 255);
5
  --md-sys-color-primary-container: rgb(214 227 255);
6
  --md-sys-color-on-primary-container: rgb(40 71 119);
7
  --md-sys-color-secondary: rgb(86 95 113);
8
  --md-sys-color-on-secondary: rgb(255 255 255);
9
  --md-sys-color-secondary-container: rgb(218 226 249);
10
  --md-sys-color-on-secondary-container: rgb(62 71 89);
11
  --md-sys-color-tertiary: rgb(112 85 117);
12
  --md-sys-color-on-tertiary: rgb(255 255 255);
13
  --md-sys-color-tertiary-container: rgb(250 216 253);
14
  --md-sys-color-on-tertiary-container: rgb(87 62 92);
15
  --md-sys-color-error: rgb(186 26 26);
16
  --md-sys-color-on-error: rgb(255 255 255);
17
  --md-sys-color-error-container: rgb(255 218 214);
18
  --md-sys-color-on-error-container: rgb(147 0 10);
19
  --md-sys-color-background: rgb(249 249 255);
20
  --md-sys-color-on-background: rgb(25 28 32);
21
  --md-sys-color-surface: rgb(249 249 255);
22
  --md-sys-color-on-surface: rgb(25 28 32);
23
  --md-sys-color-surface-variant: rgb(224 226 236);
24
  --md-sys-color-on-surface-variant: rgb(68 71 78);
25
  --md-sys-color-outline: rgb(116 119 127);
26
  --md-sys-color-outline-variant: rgb(196 198 208);
27
  --md-sys-color-shadow: rgb(0 0 0);
28
  --md-sys-color-scrim: rgb(0 0 0);
29
  --md-sys-color-inverse-surface: rgb(46 48 54);
30
  --md-sys-color-inverse-on-surface: rgb(240 240 247);
31
  --md-sys-color-inverse-primary: rgb(170 199 255);
32
  --md-sys-color-primary-fixed: rgb(214 227 255);
33
  --md-sys-color-on-primary-fixed: rgb(0 27 62);
34
  --md-sys-color-primary-fixed-dim: rgb(170 199 255);
35
  --md-sys-color-on-primary-fixed-variant: rgb(40 71 119);
36
  --md-sys-color-secondary-fixed: rgb(218 226 249);
37
  --md-sys-color-on-secondary-fixed: rgb(19 28 43);
38
  --md-sys-color-secondary-fixed-dim: rgb(190 198 220);
39
  --md-sys-color-on-secondary-fixed-variant: rgb(62 71 89);
40
  --md-sys-color-tertiary-fixed: rgb(250 216 253);
41
  --md-sys-color-on-tertiary-fixed: rgb(40 19 46);
42
  --md-sys-color-tertiary-fixed-dim: rgb(221 188 224);
43
  --md-sys-color-on-tertiary-fixed-variant: rgb(87 62 92);
44
  --md-sys-color-surface-dim: rgb(217 217 224);
45
  --md-sys-color-surface-bright: rgb(249 249 255);
46
  --md-sys-color-surface-container-lowest: rgb(255 255 255);
47
  --md-sys-color-surface-container-low: rgb(243 243 250);
48
  --md-sys-color-surface-container: rgb(237 237 244);
49
  --md-sys-color-surface-container-high: rgb(231 232 238);
50
  --md-sys-color-surface-container-highest: rgb(226 226 233);
51
}
52

K. Carpeta « fonts »

Versión para imprimir.

A. fonts / MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].codepoints

B. fonts / MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf

C. fonts / MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2

D. fonts / roboto-v32-latin-regular.woff2

L. Carpeta « img »

Versión para imprimir.

A. img / Escultura_de_coyote.jpeg

icono2048.png

B. img / icono2048.png

icono2048.png

C. img / maskable_icon.png

maskable_icon.png

D. img / maskable_icon_x128.png

maskable_icon_x128.png

E. img / maskable_icon_x192.png

maskable_icon_x192.png

F. img / maskable_icon_x384.png

maskable_icon_x384.png

G. img / maskable_icon_x48.png

maskable_icon_x48.png

H. img / maskable_icon_x512.png

maskable_icon_x512.png

I. img / maskable_icon_x72.png

maskable_icon_x72.png

J. img / maskable_icon_x96.png

maskable_icon_x96.png

K. img / pexels-craig-dennis-3701822.jpg

icono2048.png

L. img / pexels-moises-patrício-10961948.jpg

icono2048.png

M. img / screenshot_horizontal.png

screenshot_horizontal.png

N. img / screenshot_vertical.png

screenshot_vertical.png

M. Carpeta « js »

Versión para imprimir.

A. js / nav-tab-fixed.js

1
import { resaltaSiEstasEn } from "./lib/resaltaSiEstasEn.js"
2
3
export class NavTabFixed extends HTMLElement {
4
5
 constructor() {
6
  super()
7
  this.creado = false
8
 }
9
10
 connectedCallback() {
11
  this.classList.add("md-tab", "fixed")
12
13
  if (!this.creado) {
14
15
   this.innerHTML = /* HTML */`
16
    <a ${resaltaSiEstasEn(["/index.html", "", "/"])} href="index.html">
17
     <span class="material-symbols-outlined">home</span>
18
     Inicio
19
    </a>
20
 
21
    <a ${resaltaSiEstasEn(["/ayuda.html"])} href="ayuda.html">
22
     <span class="material-symbols-outlined">help</span>
23
     Ayuda
24
    </a>`
25
26
   this.creado = true
27
28
  }
29
30
 }
31
32
}
33
34
customElements.define("nav-tab-fixed", NavTabFixed)

B. Carpeta « js / lib »

1. js / lib / ES_APPLE.js

1
export const ES_APPLE = /.*(iPad|iPhone|iPod|Mac).*/.test(navigator.userAgent)

2. js / lib / getAttribute.js

1
/**
2
 * @param {HTMLElement} elementoHtml
3
 * @param {string} nombre
4
 * @returns {string}
5
 */
6
export function getAttribute(elementoHtml, nombre) {
7
 const valor = elementoHtml.getAttribute(nombre)
8
 return valor === null ? "" : valor
9
}

3. js / lib / querySelector.js

1
/**
2
 * @template { HTMLElement } T
3
 * @param { Document | Element | ShadowRoot } raiz
4
 * @param { string } query
5
 * @returns { T }
6
 */
7
export function querySelector(raiz, query) {
8
 /** @type { T | null } */
9
 const resutado = raiz.querySelector(query)
10
 if (resutado === null)
11
  throw new Error(`No se encuentra ${query}.`)
12
 return resutado
13
}

4. js / lib / registraServiceWorker.js

1
const nombreDeServiceWorker = "sw.js"
2
3
try {
4
 navigator.serviceWorker.register(nombreDeServiceWorker)
5
  .then(registro => {
6
   console.log(nombreDeServiceWorker, "registrado.")
7
   console.log(registro)
8
  })
9
  .catch(error => console.log(error))
10
} catch (error) {
11
 console.log(error)
12
}

5. js / lib / resaltaSiEstasEn.js

1
/**
2
 * @param {string[]} paginas
3
 */
4
export function resaltaSiEstasEn(paginas) {
5
6
 const pathname = location.pathname
7
8
 for (const pagina of paginas) {
9
10
  if (pathname === pagina) {
11
   queueMicrotask(() => {
12
    const tab = document.querySelector(".active")
13
    if (tab !== null && tab.closest(".scrollable") !== null) {
14
     tab.scrollIntoView({ inline: "center", block: "end" })
15
    }
16
   })
17
   return `class="active"`
18
  }
19
20
 }
21
22
 return ""
23
24
}

6. Carpeta « js / lib / custom »

A. js / lib / custom / md-app-bar.js

1
import { ES_APPLE } from "../ES_APPLE.js"
2
import { getAttribute } from "../getAttribute.js"
3
import { querySelector } from "../querySelector.js"
4
5
class MdAppBar extends HTMLElement {
6
7
 getContent() {
8
  return /* HTML */`
9
   <style>
10
11
    :host {
12
     display: flex;
13
     box-sizing: border-box;
14
     align-items: center;
15
     padding: 0 0.25rem;
16
     background-color: var(--md-sys-color-surface);
17
     position: sticky;
18
     z-index: 1;
19
     left: env(titlebar-area-x, 0);
20
     top: env(titlebar-area-y, 0);
21
     height: env(titlebar-area-height, 4rem);
22
     width: env(titlebar-area-width, 100%);
23
    }
24
    
25
    :host(.apple) {
26
     height: env(titlebar-area-height, 3rem);
27
    }
28
29
    :host(.scroll) {
30
     background-color: var(--md-sys-color-surface-container-low);
31
    }
32
33
    #navigation {
34
     flex: 0 0 auto;
35
     overflow: hidden
36
    }
37
38
    #navigation ::slotted(*) {
39
     color: var(--md-sys-color-on-surface);
40
    }
41
42
    #acciones {
43
     margin-left: auto;
44
     flex: 0 0 auto;
45
     overflow: hidden
46
    }
47
48
    :host(.centered) #navigation,
49
    :host(.centered) #acciones {
50
     flex: 0 0 6rem;
51
     overflow: hidden
52
    }
53
54
    #headline::slotted(*) {
55
     -webkit-app-region: drag;
56
     flex: 1 1 auto;
57
     white-space: nowrap;
58
     text-overflow: ellipsis;
59
     overflow: hidden;
60
     font-family: var(--md-sys-typescale-title-large-font);
61
     font-weight: var(--md-sys-typescale-title-large-weight);
62
     font-size: var(--md-sys-typescale-title-large-size);
63
     font-style: var(--md-sys-typescale-title-large-font-style);
64
     letter-spacing: var(--md-sys-typescale-title-large-tracking);
65
     line-height: var(--md-sys-typescale-title-large-line-height);
66
     text-transform: var(--md-sys-typescale-title-large-text-transform);
67
     text-decoration: var(--md-sys-typescale-title-large-text-decoration);
68
     color: var(--md-sys-color-on-surface);
69
    }
70
71
    :host(.centered) #headline::slotted(*) {
72
     flex: 1 1 auto;
73
     text-align: center
74
    }
75
76
   </style>
77
78
   <span id="navigation">
79
    <slot name="navigation"></slot>
80
   </span>
81
   <slot id="headline"></slot>
82
   <span id="acciones">
83
    <slot name="action"></slot>
84
   </span>`
85
 }
86
87
 constructor() {
88
  super()
89
  if (ES_APPLE) {
90
   document.body.classList.add("apple")
91
   document.body.classList.remove("material")
92
  } else {
93
   document.body.classList.add("material")
94
   document.body.classList.remove("apple")
95
  }
96
97
  /**
98
   * @private
99
   * @readonly
100
   */
101
  const shadow = this.attachShadow({ mode: "open" })
102
  shadow.innerHTML = this.getContent()
103
  this._configuraAction = this._configuraAction.bind(this)
104
  /**
105
   * @private
106
   * @type {number}
107
   */
108
  this._posY = 0
109
  /**
110
   * @private
111
   * @type {boolean}
112
   */
113
  this._scrolling = false
114
  /**
115
    * @private
116
    * @type { HTMLSlotElement }
117
    */
118
  this._navigation = querySelector(shadow, '[name="navigation"]')
119
  /**
120
    * @private
121
    * @type { HTMLSlotElement }
122
    */
123
  this._action = querySelector(shadow, '[name="action"]')
124
  /**
125
    * @private
126
    * @type { HTMLHeadingElement | null }
127
    */
128
  this._headline = null
129
  /**
130
    * @private
131
    * @type { HTMLElement | null }
132
    */
133
  this._adicional = null
134
  this._action.addEventListener("slotchange", this._configuraAction)
135
  addEventListener("scroll", () => this._onScroll())
136
  addEventListener("load", () => this.configurOtros())
137
 }
138
139
 connectedCallback() {
140
  this.role = "toolbar"
141
  this._configuraAction()
142
 }
143
144
 configurOtros() {
145
  const idHeadline = getAttribute(this, "headline")
146
  if (idHeadline !== "") {
147
   const headline = document.getElementById(idHeadline)
148
   if (headline instanceof HTMLHeadingElement) {
149
    this._headline = headline
150
    if (this.classList.contains("apple") || this.classList.contains("medium")) {
151
     headline.classList.add("md-headline", "headline-small")
152
    } else {
153
     headline.classList.add("md-headline", "headline-medium")
154
    }
155
   }
156
  }
157
  const idAdicional = getAttribute(this, "adicional")
158
  if (idAdicional !== "") {
159
   this._adicional = document.getElementById(idAdicional)
160
   if (this._adicional !== null) {
161
    if (this.classList.contains("apple")) {
162
     this._adicional.style.top = "env(titlebar-area-height, 3rem)"
163
    } else {
164
     this._adicional.style.top = "env(titlebar-area-height, 4rem)"
165
    }
166
   }
167
  }
168
 }
169
170
 _configuraAction() {
171
  const assignedElements = this._action.assignedElements()
172
  if (this.isConnected) {
173
   if (ES_APPLE) {
174
    this.classList.add("apple")
175
    this.classList.remove("material")
176
   } else {
177
    this.classList.add("material")
178
    this.classList.remove("apple")
179
   }
180
   if (this.classList.contains("centered")) {
181
    this.classList.remove("centrado")
182
    this.classList.remove("justificado")
183
   } else {
184
    if (ES_APPLE && assignedElements.length <= 1) {
185
     this.classList.add("centrado")
186
     this.classList.remove("justificado")
187
    } else {
188
     this.classList.add("justificado")
189
     this.classList.remove("centrado")
190
    }
191
   }
192
  }
193
 }
194
195
 /** @private */
196
 _onScroll() {
197
  this._posY = scrollY
198
  if (!this._scrolling) {
199
   requestAnimationFrame(() => this._avanza())
200
  }
201
  this._scrolling = true
202
 }
203
204
 /** @private */
205
 _avanza() {
206
  if (this._posY === 0) {
207
   this.classList.remove("scroll")
208
   if (this._headline !== null) {
209
    if (this._adicional === null) {
210
     this._headline.classList.remove("scroll")
211
    } else {
212
     this._headline.classList.remove("scroll-adicional")
213
    }
214
   }
215
   if (this._adicional !== null) {
216
    this._adicional.classList.remove("scroll")
217
   }
218
  } else {
219
   this.classList.add("scroll")
220
   if (this._headline !== null) {
221
    if (this._adicional === null) {
222
     this._headline.classList.add("scroll")
223
    } else {
224
     this._headline.classList.add("scroll-adicional")
225
    }
226
   }
227
   if (this._adicional !== null) {
228
    this._adicional.classList.add("scroll")
229
   }
230
  }
231
  this._scrolling = false
232
 }
233
234
}
235
236
customElements.define("md-app-bar", MdAppBar)

N. favicon.ico

favicon.ico

O. .htaccess

1
AddType application/manifest+json .webmanifest
2
3
ExpiresActive On
4
5
Header set Cache-Control "max-age=1, must-revalidate"
6

P. jsconfig.json

1
{
2
 "compilerOptions": {
3
  "checkJs": true,
4
  "strictNullChecks": true,
5
  "target": "ES6",
6
  "module": "Node16",
7
  "moduleResolution": "Node16",
8
  "lib": [
9
   "ES2017",
10
   "WebWorker",
11
   "DOM"
12
  ]
18
}

Q. instruccionesListadoSw.txt

1
Generar el listado de archivos del sw.js desde Visual Studio Code.
2
1. Abrir una terminal desde el menú 
3
    Terminal > New Terminal
4
5
2. Desde la terminal introducir la orden:
6
    Get-ChildItem -path . -Recurse | Select Directory,Name | Out-File archivos.txt
7
8
3. Abrir el archivo generado, que se llama
9
    archivos.txt
10
   y sobre este, realizar los pasos que siguen:
11
12
4. Quita del archivo archivos.txt:
13
    * el encabezado,
14
    * todas las carpetas,
15
    * todos los archivos dentro de .vscode como:
16
       * el archivo .vscode/settings.json,
17
       * el archivo .vscode/launch.json,
18
    * el archivo .htaccess,
19
    * el archivo archivos.txt,
20
    * este archivo (instruccionesListadoSw.txt),
21
    * el archivo jsconfig.json,
22
    * el archivo sw.js,
23
    * el archivo de la base de datos, que termina en ".db" y
24
      está en la carpeta php,
25
    * todos los archivos de php y
26
    * las líneas en blanco del final
27
28
5. Cambia los \ por / desde Visual Studio Code con las siguientes
29
   combinaciones de teclas:
30
31
    Ctrl+H En el diálogo que aparece introduce lo siguiente:
32
    Find:\
33
    Replace:/
34
35
    Clic en el icono Reemplaza todo o Replace All y luego teclea ESC
36
 
37
6. Coloca las comillas y coma del final de cada línea desde Visual
38
   Studio Code con las siguientes combinaciones de teclas:
39
40
    Ctrl+H En el diálogo que aparece, selecciona el botón
41
            ".*"
42
           e introduce lo siguiente:
43
    Find:\s*$
44
    Replace:",
45
46
    Clic en el icono Reemplaza todo o Replace All y luego teclea ESC
47
48
7. Marca la carpeta inicial, presiona la combinación de teclas:
49
50
    Shift+Ctrl+L
51
52
    borra la selección, teclea " y luego ESC
53
54
8. Cambia las secuencias de espacios por / con las siguientes
55
   combinaciones de teclas:
56
57
    Ctrl+H En el diálogo que aparece, selecciona el botón
58
            ".*"
59
           e introduce lo siguiente:
60
    Find:\s+
61
    Replace:/
62
63
    Clic en el icono Reemplaza todo o Replace All y luego teclea ESC
64
65
9. Cambia las "/ por " con las siguientes combinaciones de teclas:
66
67
    Ctrl+H En el diálogo que aparece, quita la selección del botón
68
            ".*"
69
           e introduce lo siguiente:
70
    Find:"/
71
    Replace:"
72
73
    Clic en el icono Reemplaza todo o Replace All y luego teclea ESC
74
75
10. Copia el texto al archivo
76
     sw.js
77
    en el contenido del arreglo llamado ARCHIVOS, pero recuerda
78
    mantener el último elemento, que dice:
79
     "/"

R. archivos.txt

1
"ayuda.html",
2
"favicon.ico",
3
"index.html",
4
"site.webmanifest",
5
"css/baseline.css",
6
"css/colors.css",
7
"css/elevation.css",
8
"css/estilos.css",
9
"css/material-symbols-outlined.css",
10
"css/md-headline.css",
11
"css/md-list.css",
12
"css/md-tab.css",
13
"css/motion.css",
14
"css/palette.css",
15
"css/roboto.css",
16
"css/shape.css",
17
"css/state.css",
18
"css/transicion_pestanas.css",
19
"css/typography.css",
20
"css/theme/dark.css",
21
"css/theme/light.css",
22
"fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].codepoints",
23
"fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf",
24
"fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2",
25
"fonts/roboto-v32-latin-regular.woff2",
26
"img/Escultura_de_coyote.jpeg",
27
"img/icono2048.png",
28
"img/maskable_icon.png",
29
"img/maskable_icon_x128.png",
30
"img/maskable_icon_x192.png",
31
"img/maskable_icon_x384.png",
32
"img/maskable_icon_x48.png",
33
"img/maskable_icon_x512.png",
34
"img/maskable_icon_x72.png",
35
"img/maskable_icon_x96.png",
36
"img/pexels-craig-dennis-3701822.jpg",
37
"img/pexels-moises-patrício-10961948.jpg",
38
"img/screenshot_horizontal.png",
39
"img/screenshot_vertical.png",
40
"js/nav-tab-fixed.js",
41
"js/lib/ES_APPLE.js",
42
"js/lib/getAttribute.js",
43
"js/lib/querySelector.js",
44
"js/lib/registraServiceWorker.js",
45
"js/lib/resaltaSiEstasEn.js",
46
"js/lib/custom/md-app-bar.js",
47
"ungap/custom-elements.js",

S. Carpeta « ungap »

Versión para imprimir.

A. ungap / custom-elements.js

T. Resumen