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://pwamdel.web.app/.

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

  3. Crea una cuenta de email de Google por ejemplo, juanito@google.com

  4. En https://console.firebase.google.com/ selecciona la cuenta de email que acabas de crear, por ejemplo, juanito@google.com

  5. Crea un proyecto de Firebase nuevo. Por ejemplo, pwamdel. No uses IA ni Amalytics.

  6. 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 juanito.

  7. Crea un repositorio nuevo. En el nombre del repositorio, pon el nombre del proyecto de firebase, por ejemplo pwamdel

  8. Importa el proyecto de GitHub a Visual Studio Code

  9. En la consola de firebase, en el costado izquierdo, en la opción Hosting y sin servidores selecciona Hosting. Añade hosting a ti sitio (Sin usar IA ni Amalytics) y sigue las instrucciones que se indican para para la consola, que básicamente son

    1. firebase login
      Si no has iniciado sesión, se abre el navegador y tienes que entrar a sesión con tu cuenta de Firebase.
    2. firebase init
      Selecciona el proyecto que ya está creado en Firebase, solo ponle hosting y emulador de hosting (selecciona que lo descargue.) Selecciona que no sea una Single page app.
  10. Edita los archivos que desees.

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

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

  13. Coloca el archivo favicon.ico en la carpeta /public del proyecto.

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

  15. El proyecto usa algunas librerías ya existentes para realizar algunas partes del proyecto. Ya están incluidos en el archivo zip, pero a continuación se indica como se incluyeron.

    Ungap custom elements
    Se descarga el archivo es.js del repositorio https://github.com/ungap/custom-elements y se coloca en la carpeta /public/ungap del proyecto
    material-tokens
    Se descarga el repositorio https://github.com/material-foundation/material-tokens y copia el contenido de la cerpeta css a la carpeta /public/material-tokens/css del proyecto, sustituyendo todo el contenido de esta última carpeta. A los temas les faltan algunos tokens más nuevos, por lo que debes hacer el siguiente paso.
  16. Para cambiar los colores, entra al sitio https://material-foundation.github.io/material-theme-builder/, selecciona los colores de tu aplicación, haz clic en Pick your fonts →. Elige font Roboto, haz clic en Export theme →. Haz clic en Export y selecciona Web (CSS) para descargar el zip que contiene los estilos que generan los colores. Descompacta el zip y copia los archivos de la carpeta css a la carpeta /public/material-tokens/css del proyecto, sobreescribiendo los archivos dark.css, para el tema oscuro y light.css para el tema claro.

  17. El archivo /public/sw.js tiene una lista de los archivos que se instalan. Puedes generar la lista abriendo una terminal en Visual Studio Code e introducir la orden
    node generar-listado-sw.js
    se genera el archivo /lista_archivos_sw.txt con el listado que se puede copiar al archivo /public/sw.js.

  18. Para depurar localmente tu aplicación, teclea en la terminal
    firebase emulators:start
    Lo puedes ver en la dirección http://localhost:5000. Para detener el servidor local, en la terminal debes presionar Ctrl+C En el siguiente enlace se muestra como probar la aplicación. La forma de levantar el servidor es diferente, pero la forma de usar el navegador es la misma. Prueba tu PWA.

  19. Cada vez que vayas a publicar cambios, debes modificar el valor de VERSION en el archivo /public/sw.js para poder ver los cambios en el navegador.

  20. 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.

    7. El archivo .htaccess Solo se utiliza en servidores compatibles con apache, como Ngnx o infinity free. Sirve para quitar el cache de http y declarar el mime type de los archivos .manifest

    8. Para publicar tu aplicación, teclea en la terminal
      firebase deploy
      Te va a indicar la dirección para ver tu sitio en internet.

    9. Si quieres cerrar tu sesión de deasarrollo, teclea en la terminal: firebase logout
    10. 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.

    11. 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.

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

D. Archivos

Haz clic en los triángulos para expandir las carpetas

E. Carpeta « public »

Versión para imprimir.

A. public / .htaccess

  • Este archivo configura las respuestas del servidor..

  • Lo utilizan principalmente servidores como Apache o Nginx.

  • Configura el mime type para el archivo de manifiesto y sedhabilita el uso de la cache general de http..

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

B. public / 404.html

1
<!DOCTYPE html>
2
<html>
3
  <head>
4
    <meta charset="utf-8">
5
    <meta name="viewport" content="width=device-width, initial-scale=1">
6
    <title>Page Not Found</title>
7
8
    <style media="screen">
9
      body { background: #ECEFF1; color: rgba(0,0,0,0.87); font-family: Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 0; }
10
      #message { background: white; max-width: 360px; margin: 100px auto 16px; padding: 32px 24px 16px; border-radius: 3px; }
11
      #message h3 { color: #888; font-weight: normal; font-size: 16px; margin: 16px 0 12px; }
12
      #message h2 { color: #ffa100; font-weight: bold; font-size: 16px; margin: 0 0 8px; }
13
      #message h1 { font-size: 22px; font-weight: 300; color: rgba(0,0,0,0.6); margin: 0 0 16px;}
14
      #message p { line-height: 140%; margin: 16px 0 24px; font-size: 14px; }
15
      #message a { display: block; text-align: center; background: #039be5; text-transform: uppercase; text-decoration: none; color: white; padding: 16px; border-radius: 4px; }
16
      #message, #message a { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); }
17
      #load { color: rgba(0,0,0,0.4); text-align: center; font-size: 13px; }
18
      @media (max-width: 600px) {
19
        body, #message { margin-top: 0; background: white; box-shadow: none; }
20
        body { border-top: 16px solid #ffa100; }
21
      }
22
    </style>
23
  </head>
24
  <body>
25
    <div id="message">
26
      <h2>404</h2>
27
      <h1>Page Not Found</h1>
28
      <p>The specified file was not found on this website. Please check the URL for mistakes and try again.</p>
29
      <h3>Why am I seeing this?</h3>
30
      <p>This page was generated by the Firebase Command-Line Interface. To modify it, edit the <code>404.html</code> file in your project's configured <code>public</code> directory.</p>
31
    </div>
32
  </body>
33
</html>
34

C. public / 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/registraServiceWorker.js"></script>
11
 <script type="module" src="libclienteweb/manejaErrores.js"></script>
12
13
 <meta name="viewport" content="width=device-width">
14
 <meta name="theme-color" content="#fffbfe">
15
16
 <link rel="icon" sizes="32x32" href="favicon.ico">
17
 <link rel="manifest" href="site.webmanifest">
18
 <link rel="stylesheet" href="css/material-symbols-outlined.css">
19
 <link rel="stylesheet" href="material-tokens/css/baseline.css">
20
 <link rel="stylesheet" href="css/estilos.css">
21
 <script src="ungap/es.js"></script>
22
23
 <script type="module" src="libmde/md-app-bar.js"></script>
24
 <script type="module" src="js/nav-tab-fixed.js"></script>
25
26
 <link rel="stylesheet" href="libmde/md-tab.css">
27
 <link rel="stylesheet" href="libmde/md-list.css">
28
 <link rel="stylesheet" href="css/transicion_pestanas.css">
29
30
</head>
31
32
<body>
33
34
 <md-app-bar adicional="tab">
35
36
  <h1>Ayuda</h1>
37
38
 </md-app-bar>
39
40
 <nav-tab-fixed id="tab"></nav-tab-fixed>
41
42
 <section>
43
44
  <ul class="md-list">
45
   <li class="md-two-line">
46
    <span class="headline">
47
     Título
48
    </span>
49
    <span class="supporting">
50
     PWA con Material Design
51
    </span>
52
   </li>
53
   <li class="md-two-line">
54
    <span class="headline">
55
     Descripción
56
    </span>
57
    <span class="supporting">
58
     Ejemplos de vistas móviles con listas.
59
    </span>
60
   </li>
61
   <li class="md-two-line">
62
    <span class="headline">
63
     Autor
64
    </span>
65
    <span class="supporting">
66
     Gilberto Pacheco Gallegos
67
    </span>
68
   </li>
69
   <li class="md-two-line">
70
    <span class="headline">
71
     Derechos de autor
72
    </span>
73
    <span class="supporting">
74
     © 2026 Gilberto Pacheco Gallegos
75
    </span>
76
   </li>
77
   <li class="md-three-line">
78
    <span class="headline">
79
     Este software usa las librerías libclienteweb y libmde.
80
    </span>
81
    <span class="supporting">
82
     Estas obras de Gilberto Pacheco Gallegos están bajo una
83
     <a target="_blank" rel="license noreferrer"
84
      href="http://creativecommons.org/licenses/by/4.0/">
85
      Licencia Creative Commons Atribución 4.0 Internacional</a></span>
86
   </li>
87
   <li>
88
    <a class="md-three-line" target="_blank" rel=”noreferrer”
89
     href="https://fonts.google.com/icons">
90
     <span class="headline">
91
      También usa Material Symbols
92
     </span>
93
     <span class="supporting">
94
      Desarrollada por Google bajo licencia Apache 2.0
95
     </span>
96
    </a>
97
   </li>
98
   <li>
99
    <a class="md-three-line" target="_blank" rel=”noreferrer”
100
     href="https://github.com/material-foundation/material-tokens">
101
     <span class="headline">
102
      También usa Material Tokens
103
     </span>
104
     <span class="supporting">
105
      Desarrollada por Google bajo licencia Apache 2.0
106
     </span>
107
    </a>
108
   </li>
109
   <li>
110
    <a class="md-three-line" target="_blank" rel=”noreferrer”
111
     href="https://github.com/ungap/custom-elements">
112
     <span class="headline">
113
      También usa Custom Elements Polyfill
114
     </span>
115
     <span class="supporting">
116
      Desarrollada por ungap bajo licencia ISC
117
     </span>
118
    </a>
119
   </li>
120
  </ul>
121
122
 </section>
123
124
 <nav-drw></nav-drw>
125
126
</body>
127
128
</html>

D. public / favicon.ico

favicon.ico

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

F. public / 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": "595x644",
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": "3413x3413",
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": "3413x3413",
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
}

G. public / 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.0"
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
 "css/estilos.css",
32
 "css/material-symbols-outlined.css",
33
 "css/transicion_pestanas.css",
34
 "favicon.ico",
35
 "fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].codepoints",
36
 "fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf",
37
 "fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2",
38
 "fonts/Roboto-Italic-VariableFont_wdth,wght.ttf",
39
 "fonts/Roboto-VariableFont_wdth,wght.ttf",
40
 "img/Escultura_de_coyote.jpeg",
41
 "img/icono2048.png",
42
 "img/maskable_icon.png",
43
 "img/maskable_icon_x128.png",
44
 "img/maskable_icon_x192.png",
45
 "img/maskable_icon_x384.png",
46
 "img/maskable_icon_x48.png",
47
 "img/maskable_icon_x512.png",
48
 "img/maskable_icon_x72.png",
49
 "img/maskable_icon_x96.png",
50
 "img/pexels-craig-dennis-3701822.jpg",
51
 "img/pexels-moises-patrício-10961948.jpg",
52
 "img/screenshot_horizontal.png",
53
 "img/screenshot_vertical.png",
54
 "index.html",
55
 "js/nav-tab-fixed.js",
56
 "js/registraServiceWorker.js",
57
 "libclienteweb/ES_APPLE.js",
58
 "libclienteweb/getAttribute.js",
59
 "libclienteweb/manejaErrores.js",
60
 "libclienteweb/muestraError.js",
61
 "libclienteweb/ProblemDetailsError.js",
62
 "libclienteweb/querySelector.js",
63
 "libclienteweb/resaltaSiEstasEn.js",
64
 "libmde/md-app-bar.js",
65
 "libmde/md-list.css",
66
 "libmde/md-tab.css",
67
 "material-tokens/css/baseline.css",
68
 "material-tokens/css/colors.css",
69
 "material-tokens/css/elevation.css",
70
 "material-tokens/css/motion.css",
71
 "material-tokens/css/palette.css",
72
 "material-tokens/css/shape.css",
73
 "material-tokens/css/state.css",
74
 "material-tokens/css/theme/dark.css",
75
 "material-tokens/css/theme/light.css",
76
 "material-tokens/css/typography.css",
77
 "site.webmanifest",
78
 "ungap/es.js",
79
 "/"
80
]
81
82
// Verifica si el código corre dentro de un service worker.
83
if (self instanceof ServiceWorkerGlobalScope) {
84
 // Evento al empezar a instalar el servide worker,
85
 self.addEventListener("install",
86
  (/** @type {ExtendableEvent} */ evt) => {
87
   console.log("El service worker se está instalando.")
88
   evt.waitUntil(llenaElCache())
89
  })
90
91
 // Evento al solicitar información a la red.
92
 self.addEventListener("fetch", (/** @type {FetchEvent} */ evt) => {
93
  if (evt.request.method === "GET") {
94
   evt.respondWith(buscaLaRespuestaEnElCache(evt))
95
  }
96
 })
97
98
 // Evento cuando el service worker se vuelve activo.
99
 self.addEventListener("activate",
100
  () => console.log("El service worker está activo."))
101
}
102
103
async function llenaElCache() {
104
 console.log("Intentando cargar caché:", CACHE)
105
 // Borra todos los cachés.
106
 const keys = await caches.keys()
107
 for (const key of keys) {
108
  await caches.delete(key)
109
 }
110
 // Abre el caché de este service worker.
111
 const cache = await caches.open(CACHE)
112
 // Carga el listado de ARCHIVOS.
113
 await cache.addAll(ARCHIVOS)
114
 console.log("Cache cargado:", CACHE)
115
 console.log("Versión:", VERSION)
116
}
117
118
/** @param {FetchEvent} evt */
119
async function buscaLaRespuestaEnElCache(evt) {
120
 // Abre el caché.
121
 const cache = await caches.open(CACHE)
122
 const request = evt.request
123
 /* Busca la respuesta a la solicitud en el contenido del caché, sin
124
  * tomar en cuenta la parte después del símbolo "?" en la URL. */
125
 const response = await cache.match(request, { ignoreSearch: true })
126
 if (response === undefined) {
127
  /* Si no la encuentra, empieza a descargar de la red y devuelve
128
   * la promesa. */
129
  return fetch(request)
130
 } else {
131
  // Si la encuentra, devuelve la respuesta encontrada en el caché.
132
  return response
133
 }
134
}

H. Carpeta « public / css »

1. public / css / estilos.css

1
html {
2
 /* Indica los temas del sistema operativo que son soportados. */
3
 color-scheme: light dark;
4
 --tabWidth: 3.75rem;
5
 --anchoNav: 22.5rem;
6
}
7
8
body>section,
9
form>section {
10
 max-width: 600px;
11
 margin-left: auto;
12
 margin-right: auto;
13
}
14
15
/* Fonts utilizados */
16
17
/* Definición de Roboto Variable (Normal) */
18
@font-face {
19
 font-family: 'Roboto';
20
 src: url('../fonts/Roboto-VariableFont_wdth,wght.ttf') format('truetype');
21
 /* Rango del eje de peso (wght) */
22
 font-weight: 100 900;
23
 /* Rango del eje de anchura (wdth) */
24
 font-stretch: 75% 100%;
25
 font-style: normal;
26
 /* Mejora el rendimiento de carga de texto */
27
 font-display: swap;
28
}
29
30
/* Definición de Roboto Variable (Itálica) */
31
@font-face {
32
 font-family: 'Roboto';
33
 src: url('../fonts/Roboto-Italic-VariableFont_wdth,wght.ttf') format('truetype');
34
 font-weight: 100 900;
35
 font-stretch: 75% 100%;
36
 font-style: italic;
37
 font-display: swap;
38
}
39
40
html {
41
 --Font: -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
42
 --colIntIos: white;
43
 --colIntIosOnBk: #2acc2a;
44
 --colIntIosOnBkFc: #1bbb1b;
45
 --colIntIosOffBk: #dbdbdb;
46
 --colIntIosOffBkFc: #BDBDBD;
47
 /* Plain typeface */
48
 --md-ref-typeface-plain: var(--Font);
49
 /* Brand typeface */
50
 --md-ref-typeface-brand: var(--Font);
51
 --md-sys-typescale-label-large-weight-prominent:
52
  var(--md-ref-typeface-weight-bold);
53
 --md-box_shadow_level4:
54
  0 var(--md-sys-elevation-level4) var(--md-sys-elevation-level4) var(--md-sys-color-shadow);
55
 --md-box_shadow_level3:
56
  0 var(--md-sys-elevation-level3) var(--md-sys-elevation-level3) var(--md-sys-color-shadow);
57
 --md-box_shadow_level2:
58
  0 var(--md-sys-elevation-level2) var(--md-sys-elevation-level2) var(--md-sys-color-shadow);
59
 --md-box_shadow_level1:
60
  0 var(--md-sys-elevation-level1) var(--md-sys-elevation-level1) var(--md-sys-color-shadow);
61
 --md-box_shadow_level0: none;
62
 --iconSize: 1.5rem;
63
 --avatarSize: 2.5rem;
64
 --imageSize: 3.5rem;
65
 --videoWidth: 7.125rem;
66
 --videoHeight: 4rem;
67
 --md-sys-state-focus-indicator-outer-offset: 0.125rem;
68
 --md-sys-state-focus-indicator-thickness: 0.1875rem;
69
 /* Pressed state layer opacity */
70
 --state-pressed-transparency-percentage: 84%;
71
 /* Focus state layer opacity */
72
 --state-focus-transparency-percentage: 88%;
73
 /* Hover state layer opacity */
74
 --state-hover-transparency-percentage: 92%;
75
 background-color: var(--md-sys-color-background);
76
}
77
78
/* Quita un borde rojo que coloca Firefox. */
79
:-moz-ui-invalid {
80
 box-shadow: none;
81
}
82
83
body {
84
 margin: 0;
85
 font-family: var(--md-sys-typescale-body-large-font);
86
 font-weight: var(--md-sys-typescale-body-large-weight);
87
 font-size: var(--md-sys-typescale-body-large-size);
88
 font-style: var(--md-sys-typescale-body-large-font-style);
89
 letter-spacing: var(--md-sys-typescale-body-large-tracking);
90
 line-height: var(--md-sys-typescale-body-large-line-height);
91
 text-transform: var(--md-sys-typescale-body-large-text-transform);
92
 text-decoration: var(--md-sys-typescale-body-large-text-decoration);
93
 color: var(--md-sys-color-on-background);
94
 background-color: var(--md-sys-color-background);
95
}
96
97
p {
98
 margin: 1rem;
99
}
100
101
a {
102
 color: var(--md-sys-color-on-background);
103
}
104
105
@media (prefers-color-scheme: light) {
106
 html {
107
  --md-riple-color: #00000020;
108
 }
109
}
110
111
@media (prefers-color-scheme: dark) {
112
 html {
113
  --md-riple-color: #ffffff40;
114
 }
115
}
116
117
@keyframes md-ripple {
118
119
 from {
120
  background-size: 100%;
121
 }
122
123
 to {
124
  background-size: 15000%;
125
 }
126
127
}

2. public / css / material-symbols-outlined.css

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

3. public / css / transicion_pestanas.css

1
@view-transition {
2
 navigation: auto;
3
}
4
5
md-app-bar {
6
 view-transition-name: encabezado;
7
 background-color: var(--md-sys-color-surface);
8
 contain: layout;
9
}
10
11
section {
12
 view-transition-name: contenido;
13
 background-color: var(--md-sys-color-background);
14
 contain: layout;
15
}
16
17
@keyframes salePorLaIzquierda {
18
 from {
19
  transform: translateX(0);
20
  opacity: 1;
21
 }
22
23
 to {
24
  transform: translateX(-100%);
25
  opacity: 1;
26
 }
27
}
28
29
@keyframes entraPorLaDerecha {
30
 from {
31
  transform: translateX(100%);
32
  opacity: 1;
33
 }
34
35
 to {
36
  transform: translateX(0);
37
  opacity: 1;
38
 }
39
}
40
41
::view-transition-old(root),
42
::view-transition-new(root) {
43
 animation: none;
44
 mix-blend-mode: normal;
45
 opacity: 1 !important;
46
}
47
48
::view-transition-group(encabezado) {
49
 background-color: var(--md-sys-color-surface) !important;
50
}
51
52
::view-transition-group(contenido) {
53
 background-color: var(--md-sys-color-background) !important;
54
}
55
56
::view-transition-group(encabezado),
57
::view-transition-group(contenido) {
58
 animation-duration: var(--md-sys-motion-duration-1000);
59
 mix-blend-mode: normal !important;
60
 opacity: 1 !important;
61
 animation-fill-mode: both;
62
 overflow: hidden;
63
}
64
65
html::view-transition-old(encabezado) {
66
 animation-name: salePorLaIzquierda;
67
}
68
69
html::view-transition-new(encabezado) {
70
 animation-name: entraPorLaDerecha;
71
}
72
73
html::view-transition-old(contenido) {
74
 animation-name: salePorLaIzquierda;
75
}
76
77
html::view-transition-new(contenido) {
78
 animation-name: entraPorLaDerecha;
79
}

I. Carpeta « public / fonts »

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

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

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

4. public / fonts / Roboto-Italic-VariableFont_wdth,wght.ttf

5. public / fonts / Roboto-VariableFont_wdth,wght.ttf

J. Carpeta « public / img »

1. public / img / Escultura_de_coyote.jpeg

Escultura_de_coyote.jpeg

2. public / img / icono2048.png

icono2048.png

3. public / img / maskable_icon.png

maskable_icon.png

4. public / img / maskable_icon_x128.png

maskable_icon_x128.png

5. public / img / maskable_icon_x192.png

maskable_icon_x192.png

6. public / img / maskable_icon_x384.png

maskable_icon_x384.png

7. public / img / maskable_icon_x48.png

maskable_icon_x48.png

8. public / img / maskable_icon_x512.png

maskable_icon_x512.png

9. public / img / maskable_icon_x72.png

maskable_icon_x72.png

10. public / img / maskable_icon_x96.png

maskable_icon_x96.png

11. public / img / pexels-craig-dennis-3701822.jpg

pexels-craig-dennis-3701822.jpg

12. public / img / pexels-moises-patrício-10961948.jpg

pexels-moises-patrício-10961948.jpg

13. public / img / screenshot_horizontal.png

screenshot_horizontal.png

14. public / img / screenshot_vertical.png

screenshot_vertical.png

K. Carpeta « public / js »

1. public / js / nav-tab-fixed.js

1
import { resaltaSiEstasEn } from "../libclienteweb/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)

2. public / js / 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
}

L. Carpeta « public / libclienteweb »

1. public / libclienteweb / ES_APPLE.js

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

2. public / libclienteweb / 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. public / libclienteweb / manejaErrores.js

1
import { muestraError } from "./muestraError.js"
2
3
/**
4
 * Intercepta Response.prototype.json para capturar errores de parseo
5
 * y asegurar que se reporten correctamente en navegadores Chromium.
6
 */
7
{
8
 const originalJson = Response.prototype.json
9
10
 Response.prototype.json = function () {
11
  // Llamamos al método original usando el contexto (this) de la respuesta
12
  return originalJson.call(this)
13
   .catch((/** @type {any} */ error) => {
14
    // Corrige un error de Chrome que evita el manejo correcto de errores.
15
    throw new Error(error)
16
   })
17
 }
18
}
19
20
window.onerror = function (
21
 /** @type {Event | string} */ _event,
22
 /** @type {string | undefined} */ _fuente,
23
 /** @type {number | undefined} */ _numeroDeLinea,
24
 /** @type {number | undefined} */ _numeroDeColumna,
25
 /** @type {Error | undefined} */ error
26
) {
27
 muestraError(error)
28
 return true
29
}
30
31
window.addEventListener('unhandledrejection', event => {
32
 muestraError(event.reason)
33
 event.preventDefault()
34
})

4. public / libclienteweb / muestraError.js

1
import { ProblemDetailsError } from "./ProblemDetailsError.js"
2
3
/**
4
 * Muestra los datos de una Error en la consola y en un cuadro de alerta.
5
 * @param { unknown } error descripción del error.
6
 */
7
export function muestraError(error) {
8
9
 if (error instanceof ProblemDetailsError) {
10
11
  const problemDetails = error.problemDetails
12
13
  let mensaje =
14
   typeof problemDetails["title"] === "string" ? problemDetails["title"] : ""
15
  if (typeof problemDetails["detail"] === "string") {
16
   if (mensaje !== "") {
17
    mensaje += "\n"
18
   }
19
   mensaje += problemDetails["detail"]
20
  }
21
  if (mensaje === "") {
22
   mensaje = "Error"
23
  }
24
  console.error(error, problemDetails)
25
  alert(mensaje)
26
27
 } else if (
28
  typeof error === "object" && error !== null && "message" in error
29
 ) {
30
31
  console.error(error)
32
  alert(error.message)
33
34
 } else {
35
36
  console.error("Error", error)
37
  alert("Error")
38
39
 }
40
41
}

5. public / libclienteweb / ProblemDetailsError.js

1
export class ProblemDetailsError extends Error {
2
3
 /**
4
  * Detalle de los errores devueltos por un servicio.
5
  * Crea una instancia de ProblemDetailsError.
6
  * @param {any} problemDetails Objeto con la descripcipon del error.
7
  */
8
 constructor(problemDetails) {
9
10
  super(
11
   typeof problemDetails["detail"] === "string"
12
    ? problemDetails["detail"]
13
    : (
14
     typeof problemDetails["title"] === "string"
15
      ? problemDetails["title"]
16
      : "Error"
17
    )
18
  )
19
20
  this.problemDetails = problemDetails
21
22
 }
23
24
}

6. public / libclienteweb / 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
}

7. public / libclienteweb / 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
}

M. Carpeta « public / libmde »

1. public / libmde / md-app-bar.js

1
import { ES_APPLE } from "../libclienteweb/ES_APPLE.js"
2
import { getAttribute } from "../libclienteweb/getAttribute.js"
3
import { querySelector } from "../libclienteweb/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 idAdicional = getAttribute(this, "adicional")
146
  if (idAdicional !== "") {
147
   this._adicional = document.getElementById(idAdicional)
148
   if (this._adicional !== null) {
149
    if (this.classList.contains("apple")) {
150
     this._adicional.style.top = "env(titlebar-area-height, 3rem)"
151
    } else {
152
     this._adicional.style.top = "env(titlebar-area-height, 4rem)"
153
    }
154
   }
155
  }
156
 }
157
158
 _configuraAction() {
159
  const assignedElements = this._action.assignedElements()
160
  if (this.isConnected) {
161
   if (ES_APPLE) {
162
    this.classList.add("apple")
163
    this.classList.remove("material")
164
   } else {
165
    this.classList.add("material")
166
    this.classList.remove("apple")
167
   }
168
   if (this.classList.contains("centered")) {
169
    this.classList.remove("centrado")
170
    this.classList.remove("justificado")
171
   } else {
172
    if (ES_APPLE && assignedElements.length <= 1) {
173
     this.classList.add("centrado")
174
     this.classList.remove("justificado")
175
    } else {
176
     this.classList.add("justificado")
177
     this.classList.remove("centrado")
178
    }
179
   }
180
  }
181
 }
182
183
 /** @private */
184
 _onScroll() {
185
  this._posY = scrollY
186
  if (!this._scrolling) {
187
   requestAnimationFrame(() => this._avanza())
188
  }
189
  this._scrolling = true
190
 }
191
192
 /** @private */
193
 _avanza() {
194
  if (this._posY === 0) {
195
   this.classList.remove("scroll")
196
   if (this._headline !== null) {
197
    if (this._adicional === null) {
198
     this._headline.classList.remove("scroll")
199
    } else {
200
     this._headline.classList.remove("scroll-adicional")
201
    }
202
   }
203
   if (this._adicional !== null) {
204
    this._adicional.classList.remove("scroll")
205
   }
206
  } else {
207
   this.classList.add("scroll")
208
   if (this._headline !== null) {
209
    if (this._adicional === null) {
210
     this._headline.classList.add("scroll")
211
    } else {
212
     this._headline.classList.add("scroll-adicional")
213
    }
214
   }
215
   if (this._adicional !== null) {
216
    this._adicional.classList.add("scroll")
217
   }
218
  }
219
  this._scrolling = false
220
 }
221
222
}
223
224
customElements.define("md-app-bar", MdAppBar)

2. public / libmde / 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
}

3. public / libmde / 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
 font-variation-settings: 'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 48;
78
}
79
80
.md-tab a:hover {
81
 color: var(--md-sys-color-on-surface);
82
}
83
84
/* state layer */
85
.md-tab a:hover::after {
86
 background-color: var(--md-sys-color-on-surface);
87
 opacity: var(--md-sys-state-hover-state-layer-opacity);
88
}
89
90
.md-tab a.active:hover {
91
 color: var(--md-sys-color-primary);
92
}
93
94
/* state layer */
95
.md-tab a.active:hover::after {
96
 background-color: var(--md-sys-color-primary);
97
 opacity: var(--md-sys-state-hover-state-layer-opacity);
98
}
99
100
.md-tab a:hover span {
101
 color: var(--md-sys-color-on-surface);
102
}
103
104
.md-tab a.active:hover span {
105
 color: var(--md-sys-color-primary);
106
}
107
108
.md-tab a:focus {
109
 outline: none;
110
}
111
112
/* state layer */
113
.md-tab a:focus::after {
114
 background-color: var(--md-sys-color-on-surface);
115
 opacity: var(--md-sys-state-focus-state-layer-opacity);
116
}
117
118
/* state layer */
119
.md-tab a.active:focus::after {
120
 background-color: var(--md-sys-color-primary);
121
 opacity: var(--md-sys-state-hover-state-layer-opacity);
122
}
123
124
.md-tab a:active {
125
 background-position: center;
126
 background-image:
127
   radial-gradient(circle, var(--md-riple-color) 1%, transparent 1%);
128
 background-size: 100%;
129
 animation-name: md-ripple;
130
 animation-duration: var(--md-sys-motion-duration-500);
131
}
132
133
/* state layer */
134
.md-tab a:active::after {
135
 background-color: var(--md-sys-color-on-surface);
136
 opacity: var(--md-sys-state-pressed-state-layer-opacity);
137
}
138
139
/* state layer */
140
.md-tab a.active:active::after {
141
 background-color: var(--md-sys-color-primary);
142
 opacity: var(--md-sys-state-pressed-state-layer-opacity);
143
}

N. Carpeta « public / material-tokens »

1. Carpeta « public / material-tokens / css »

A. public / material-tokens / 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. public / material-tokens / 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. public / material-tokens / 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. public / material-tokens / 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

E. public / material-tokens / 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

F. public / material-tokens / 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

G. public / material-tokens / 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

H. public / material-tokens / 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

I. Carpeta « public / material-tokens / css / theme »

1. public / material-tokens / 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. public / material-tokens / 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

O. Carpeta « public / ungap »

1. public / ungap / es.js

F. .firebaserc

1
{
2
  "projects": {
3
    "default": "pwamdel"
4
  }
5
}
6

G. firebase.json

1
{
2
  "hosting": {
3
    "public": "public",
4
    "headers": [
5
     {
6
      "source": "**",
7
      "headers": [
8
       {
9
        "key": "Cache-Control",
10
        "value": "no-cache, no-store, must-revalidate"
11
       },
12
       {
13
        "key": "Pragma",
14
        "value": "no-cache"
15
       },
16
       {
17
        "key": "Expires",
18
        "value": "0"
19
       }
20
      ]
21
     }
22
    ],
23
    "ignore": [
24
      "firebase.json",
25
      "**/.*",
26
      "**/node_modules/**"
27
    ]
28
  },
29
  "emulators": {
30
    "hosting": {
31
      "port": 5000
32
    },
33
    "ui": {
34
      "enabled": true
35
    },
36
    "singleProjectMode": true
37
  }
38
}
39

H. LICENSE

1
Creative Commons Legal Code
2
3
CC0 1.0 Universal
4
5
    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
6
    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
7
    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
8
    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
9
    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
10
    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
11
    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
12
    HEREUNDER.
13
14
Statement of Purpose
15
16
The laws of most jurisdictions throughout the world automatically confer
17
exclusive Copyright and Related Rights (defined below) upon the creator
18
and subsequent owner(s) (each and all, an "owner") of an original work of
19
authorship and/or a database (each, a "Work").
20
21
Certain owners wish to permanently relinquish those rights to a Work for
22
the purpose of contributing to a commons of creative, cultural and
23
scientific works ("Commons") that the public can reliably and without fear
24
of later claims of infringement build upon, modify, incorporate in other
25
works, reuse and redistribute as freely as possible in any form whatsoever
26
and for any purposes, including without limitation commercial purposes.
27
These owners may contribute to the Commons to promote the ideal of a free
28
culture and the further production of creative, cultural and scientific
29
works, or to gain reputation or greater distribution for their Work in
30
part through the use and efforts of others.
31
32
For these and/or other purposes and motivations, and without any
33
expectation of additional consideration or compensation, the person
34
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
35
is an owner of Copyright and Related Rights in the Work, voluntarily
36
elects to apply CC0 to the Work and publicly distribute the Work under its
37
terms, with knowledge of his or her Copyright and Related Rights in the
38
Work and the meaning and intended legal effect of CC0 on those rights.
39
40
1. Copyright and Related Rights. A Work made available under CC0 may be
41
protected by copyright and related or neighboring rights ("Copyright and
42
Related Rights"). Copyright and Related Rights include, but are not
43
limited to, the following:
44
45
  i. the right to reproduce, adapt, distribute, perform, display,
46
     communicate, and translate a Work;
47
 ii. moral rights retained by the original author(s) and/or performer(s);
48
iii. publicity and privacy rights pertaining to a person's image or
49
     likeness depicted in a Work;
50
 iv. rights protecting against unfair competition in regards to a Work,
51
     subject to the limitations in paragraph 4(a), below;
52
  v. rights protecting the extraction, dissemination, use and reuse of data
53
     in a Work;
54
 vi. database rights (such as those arising under Directive 96/9/EC of the
55
     European Parliament and of the Council of 11 March 1996 on the legal
56
     protection of databases, and under any national implementation
57
     thereof, including any amended or successor version of such
58
     directive); and
59
vii. other similar, equivalent or corresponding rights throughout the
60
     world based on applicable law or treaty, and any national
61
     implementations thereof.
62
63
2. Waiver. To the greatest extent permitted by, but not in contravention
64
of, applicable law, Affirmer hereby overtly, fully, permanently,
65
irrevocably and unconditionally waives, abandons, and surrenders all of
66
Affirmer's Copyright and Related Rights and associated claims and causes
67
of action, whether now known or unknown (including existing as well as
68
future claims and causes of action), in the Work (i) in all territories
69
worldwide, (ii) for the maximum duration provided by applicable law or
70
treaty (including future time extensions), (iii) in any current or future
71
medium and for any number of copies, and (iv) for any purpose whatsoever,
72
including without limitation commercial, advertising or promotional
73
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
74
member of the public at large and to the detriment of Affirmer's heirs and
75
successors, fully intending that such Waiver shall not be subject to
76
revocation, rescission, cancellation, termination, or any other legal or
77
equitable action to disrupt the quiet enjoyment of the Work by the public
78
as contemplated by Affirmer's express Statement of Purpose.
79
80
3. Public License Fallback. Should any part of the Waiver for any reason
81
be judged legally invalid or ineffective under applicable law, then the
82
Waiver shall be preserved to the maximum extent permitted taking into
83
account Affirmer's express Statement of Purpose. In addition, to the
84
extent the Waiver is so judged Affirmer hereby grants to each affected
85
person a royalty-free, non transferable, non sublicensable, non exclusive,
86
irrevocable and unconditional license to exercise Affirmer's Copyright and
87
Related Rights in the Work (i) in all territories worldwide, (ii) for the
88
maximum duration provided by applicable law or treaty (including future
89
time extensions), (iii) in any current or future medium and for any number
90
of copies, and (iv) for any purpose whatsoever, including without
91
limitation commercial, advertising or promotional purposes (the
92
"License"). The License shall be deemed effective as of the date CC0 was
93
applied by Affirmer to the Work. Should any part of the License for any
94
reason be judged legally invalid or ineffective under applicable law, such
95
partial invalidity or ineffectiveness shall not invalidate the remainder
96
of the License, and in such case Affirmer hereby affirms that he or she
97
will not (i) exercise any of his or her remaining Copyright and Related
98
Rights in the Work or (ii) assert any associated claims and causes of
99
action with respect to the Work, in either case contrary to Affirmer's
100
express Statement of Purpose.
101
102
4. Limitations and Disclaimers.
103
104
 a. No trademark or patent rights held by Affirmer are waived, abandoned,
105
    surrendered, licensed or otherwise affected by this document.
106
 b. Affirmer offers the Work as-is and makes no representations or
107
    warranties of any kind concerning the Work, express, implied,
108
    statutory or otherwise, including without limitation warranties of
109
    title, merchantability, fitness for a particular purpose, non
110
    infringement, or the absence of latent or other defects, accuracy, or
111
    the present or absence of errors, whether or not discoverable, all to
112
    the greatest extent permissible under applicable law.
113
 c. Affirmer disclaims responsibility for clearing rights of other persons
114
    that may apply to the Work or any use thereof, including without
115
    limitation any person's Copyright and Related Rights in the Work.
116
    Further, Affirmer disclaims responsibility for obtaining any necessary
117
    consents, permissions or other rights required for any use of the
118
    Work.
119
 d. Affirmer understands and acknowledges that Creative Commons is not a
120
    party to this document and has no duty or obligation with respect to
121
    this CC0 or use of the Work.
122

I. README.md

1
# pwamdel
2
PWA con listas y Material Deseign 3 Expressive 
3

J. 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
}

K. .gitignore

1
# Logs
2
logs
3
*.log
4
npm-debug.log*
5
yarn-debug.log*
6
yarn-error.log*
7
firebase-debug.log*
8
firebase-debug.*.log*
9
10
# Firebase cache
11
.firebase/
12
13
# Firebase config
14
15
# Uncomment this if you'd like others to create their own Firebase project.
16
# For a team working on the same Firebase project(s), it is recommended to leave
17
# it commented so all members can deploy to the same project(s) in .firebaserc.
18
# .firebaserc
19
20
# Runtime data
21
pids
22
*.pid
23
*.seed
24
*.pid.lock
25
26
# Directory for instrumented libs generated by jscoverage/JSCover
27
lib-cov
28
29
# Coverage directory used by tools like istanbul
30
coverage
31
32
# nyc test coverage
33
.nyc_output
34
35
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
36
.grunt
37
38
# Bower dependency directory (https://bower.io/)
39
bower_components
40
41
# node-waf configuration
42
.lock-wscript
43
44
# Compiled binary addons (http://nodejs.org/api/addons.html)
45
build/Release
46
47
# Dependency directories
48
node_modules/
49
50
# Optional npm cache directory
51
.npm
52
53
# Optional eslint cache
54
.eslintcache
55
56
# Optional REPL history
57
.node_repl_history
58
59
# Output of 'npm pack'
60
*.tgz
61
62
# Yarn Integrity file
63
.yarn-integrity
64
65
# dotenv environment variables file
66
.env
67
68
# dataconnect generated files
69
.dataconnect
70

L. generar-listado-sw.js

1
const fs = require('fs/promises');
2
const path = require('path');
3
4
// Configuración de rutas
5
const PUBLIC_DIR = 'public';
6
const OUTPUT_FILE = 'lista_archivos_sw.txt';
7
8
// Restricciones basadas en tus instrucciones (Paso 4)
9
const EXCLUDED_DIRS = ['.vscode'];
10
const EXCLUDED_FILES = [
11
 '.firebaserc',
12
 '.gitignore',
13
 '.htaccess',
14
 '404.html',
15
 'sw.js',
16
 'lista_archivos_sw.txt',
17
 'generar-listado-sw.js',
18
 'firebase.json',
19
 'jsconfig.json',
20
 'LICENSE',
21
 'README.md',
22
];
23
const EXCLUDED_EXTENSIONS = ['.php', '.db'];
24
25
/**
26
 * Función recursiva para obtener todos los archivos de un directorio
27
 * @param {import("node:fs").PathLike} dir
28
 */
29
async function getFiles(dir) {
30
 /**
31
  * @type {any[]}
32
  */
33
 let results = [];
34
 const list = await fs.readdir(dir, { withFileTypes: true });
35
36
 for (const dirent of list) {
37
  const fullPath = path.join(dir, dirent.name);
38
39
  if (dirent.isDirectory()) {
40
   // Ignorar carpetas excluidas como .vscode
41
   if (!EXCLUDED_DIRS.includes(dirent.name)) {
42
    results = results.concat(await getFiles(fullPath));
43
   }
44
  } else {
45
   const fileName = dirent.name;
46
   const ext = path.extname(fileName).toLowerCase();
47
48
   // Filtrar archivos específicos y extensiones (.php, .db)
49
   if (!EXCLUDED_FILES.includes(fileName) && !EXCLUDED_EXTENSIONS.includes(ext)) {
50
51
    // Obtener ruta relativa respecto a la carpeta 'public'
52
    let relativePath = path.relative(PUBLIC_DIR, fullPath);
53
54
    // Convertir barras invertidas de Windows (\) a barras normales (/) (Paso 5 y 8)
55
    relativePath = relativePath.split(path.sep).join('/');
56
57
    // Guardar la ruta con el formato adecuado
58
    results.push(`"${ relativePath }"`);
59
   }
60
  }
61
 }
62
 return results;
63
}
64
65
/**
66
 * Función principal para generar el archivo
67
 */
68
async function generateSWList() {
69
 try {
70
  console.log(`Explorando la carpeta "${ PUBLIC_DIR }"...`);
71
  const files = await getFiles(PUBLIC_DIR);
72
73
  // Mantener el último elemento requerido por el Service Worker (Paso 10)
74
  files.push('"/"');
75
76
  // Dar formato de arreglo de JavaScript con saltos de línea y sangría (Paso 6 y 9)
77
  const arrayContent = `const ARCHIVOS = [\n  ${ files.join(',\n  ') }\n]`;
78
79
  // Escribir el resultado en un archivo de texto
80
  await fs.writeFile(OUTPUT_FILE, arrayContent, 'utf-8');
81
82
  console.log(`¡Éxito! El listado se ha generado correctamente.`);
83
  console.log(`Revisa el archivo "${ OUTPUT_FILE }" y copia el contenido a tu public/sw.js.`);
84
85
 } catch (error) {
86
  console.error('Error al generar el listado:', error.message);
87
 }
88
}
89
90
generateSWList();

M. lista_archivos_sw.txt

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

N. Resumen