/* GENERATED by backend/build_assets.py. Edit brand/colors.css and backend/static/css/_panel.src.css instead. */
:root {
  /* Blue background of the logo composition (primary brand color). On the site
   * it is also the ground of everything that carries the wing: the header, the
   * hero and the footer, so they match the favicon. Nothing else is blue. */
  --color-background: #3166A7;

  /* Off-white of the wing shapes. */
  --color-logo: #EFEEEC;

  /* Black separations/shadows visible between the overlapping feathers. */
  --color-shadow: #000000;

  /* ---------------------------------------------------------------- website
   * Palette of the public site. build_logo.py ignores these; it only needs the
   * three above. Every contrast pair below was checked against WCAG AA
   * (4.5:1 for normal text, 3:1 for large text and UI borders).
   */

  /* Sky blues: action and emphasis only. The surfaces are greys. */
  --color-accent: #31A9E8;        /* buttons, icons, marks. Use --color-ink on top */
  --color-accent-strong: #136A9B; /* links and hover; 5.9:1 on white and under white */
  --color-accent-soft: #EDEDEF;   /* chips, badges, quiet highlights */
  --color-accent-light: #CFEBFA;  /* accents over the brand blue; 4.7:1 */

  /* Dark grey for the bands with no wing on them; white on it reaches 14.9:1. */
  --color-deep: #27272A;

  /* La línea que separa la fila legal del resto del pie. El mismo valor en los
   * dos temas, porque el pie es azul en los dos, y no es un hex a propósito:
   * tiene que dejar ver ese azul. */
  --color-footer-edge: rgba(255, 255, 255, .18);


  /* Text and surfaces. */
  --color-ink: #18181B;           /* body text; 17.7:1 on white */
  --color-ink-soft: #52525B;      /* secondary text; 7.7:1 on white */
  --color-page: #FFFFFF;          /* page background */
  --color-surface: #FFFFFF;       /* cards and panels sitting on the page */
  --color-surface-alt: #F4F4F5;   /* alternating section background */
  --color-border: #CFCFD4;    /* lineas que separan: tarjetas, filas, bloques */
  /* Lo que se marca al pasar el ratón por una fila de un menú. Más oscuro que
   * las secciones alternas: sobre el blanco del menú aquel no se distinguía. */
  --color-hover: #E4E4E7;
  /* El contorno de un campo tiene que verse, y --color-border no llega: un
   * borde de control necesita 3:1. Este da 3.42:1 sobre blanco. Va aparte para
   * que oscurecer los campos no oscurezca cada linea de la pagina. */
  --color-field: #8A8A93;

  /* Text and light chips placed ON the dark blue surfaces: header, hero, deep
   * sections and footer. Separate from --color-surface because in dark mode the
   * cards go dark while this has to stay near-white. */
  --color-on-dark: #FFFFFF;
  /* Secondary text on those same surfaces: subtitles, the footer, the steps.
   * 4.7:1 on --color-background, the lightest of them. */
  --color-on-dark-soft: #E6E6E9;

  /* Text on the sky-blue accent (buttons, badges, step numbers). Dark in BOTH
   * themes: the accent stays light, so this cannot follow --color-ink. */
  --color-on-accent: #0E1B2A;

  /* ------------------------------------------------------------ ilustraciones
   * Las cuatro de «El problema», en la portada. Estos colores salen de las
   * imágenes de referencia que se dieron para ellas, muestreados punto por
   * punto: por eso no son los de la marca, y es a propósito. Viven aquí y no en
   * el SVG porque un atributo no puede leer una variable, y así la escena de
   * noche es solo otra lista de valores en colors-dark.css. build_logo.py no
   * los lee: read_colors() se queda solo con sus tres claves. */
  --art-stage: #E1EEFD;        /* el fondo de cada escena */
  --art-glow: #F4F9FF;         /* el resplandor del centro */
  --art-floor: #EAF2FE;        /* la mesa */
  --art-card: #F7FAFF;         /* tablero, bandeja, disco, fichas */
  --art-card-edge: #C9DAF8;
  --art-paper: #FFFFFF;        /* sobres, esfera del reloj, libreta */
  --art-paper-shade: #D6E3F7;
  --art-line: #CEDCF5;         /* las rayas que hacen de texto */
  --art-dash: #A9CBF7;         /* las flechas de puntos */
  --art-ink: #2A3F68;          /* las cifras de las fichas */
  --art-shadow: rgba(51, 99, 181, .22);
  --art-blue: #3D8BF5;
  --art-blue-deep: #2A68D8;
  --art-blue-soft: #8CBEF9;
  --art-green: #34C5A0;
  --art-purple: #A08BFA;
  --art-amber: #FDC074;
  --art-red: #EF5F6A;
  --art-navy: #2F4675;         /* la papelera, las agujas, el boli */
  --art-sweater: #1F3461;
  --art-silver: #B9C6E6;       /* el portátil de quien trabaja a mano */
  --art-skin: #F2AC8E;
  --art-skin-shade: #DE9677;
  --art-hair: #2E2C3E;
  --art-ginger: #CE723D;
  --art-yellow: #FDBF77;
  --art-pink: #F997AF;
  --art-leaf: #4DB38D;
  --art-leaf-deep: #2F8F75;

  /* Elevation. Here rather than in site.css so the dark palette can restate
   * them: a translucent black shadow is invisible on a dark page. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .06), 0 1px 3px rgba(0, 0, 0, .08);
  --shadow: 0 6px 20px rgba(0, 0, 0, .10);
  --shadow-lg: 0 18px 48px rgba(0, 0, 0, .16);
}

:root[data-theme="dark"] {
  /* Header, hero and footer: everything that carries the wing. The brand blue,
   * darkened so it does not glare at night. */
  --color-background: #245285;

  /* The wing keeps its own colors in both themes: it is the logo. */
  --color-logo: #EFEEEC;
  --color-shadow: #000000;

  /* Sky blues. The accent is unchanged; the link tone is lifted, because the
   * light-mode one (#136A9B) is too dark to read on a dark background. */
  --color-accent: #31A9E8;        /* buttons and marks; --color-ink goes on top */
  --color-accent-strong: #5CBDF0; /* links and hover; 8.8:1 on the page */
  --color-accent-soft: #26262A;   /* chips and quiet highlights */
  --color-accent-light: #CFEBFA;  /* text over the brand blue; 6.5:1 */

  /* Bands with no wing on them: the four-steps section, the table head. */
  --color-deep: #232326;

  /* La línea que separa la fila legal del resto del pie. El mismo valor que en
   * el tema claro: el pie es azul en los dos. */
  --color-footer-edge: rgba(255, 255, 255, .18);


  /* Text and surfaces. */
  --color-ink: #EDEDEF;           /* body text; 17.6:1 on the page */
  --color-ink-soft: #A1A1AA;      /* secondary text; 7.7:1 on the page */
  --color-page: #0B0B0C;          /* page background */
  --color-surface: #1B1B1E;       /* cards, a visible step above the page */
  --color-surface-alt: #121214;   /* alternating section background */
  --color-border: #34343A;
  --color-hover: #2C2C31;
  /* Mismo problema de noche: el borde de arriba no llega a 3:1 sobre las
   * tarjetas. Este da 3.4:1. */
  --color-field: #6E6E77;

  /* Stays near-white: it is the text on the blue and deep surfaces. */
  --color-on-dark: #F3F7FB;
  --color-on-dark-soft: #E6E6E9;

  /* Las ilustraciones de noche. Su fondo es el mismo de la sección, así que no
   * se ve recuadro y los dibujos flotan sobre la página; hubo un azul noche y
   * se quitó, porque teñía de azul toda la escena. Lo que es tarjeta (tablero,
   * bandeja, disco, fichas) pasa a los grises de las tarjetas del sitio, y el
   * papel baja un poco para no deslumbrar. Lo de color apenas sube, para
   * leerse sobre el fondo, y las personas no cambian: la piel, el pelo
   * pelirrojo y las camisas amarilla y rosa no se repiten aquí. Lo que va
   * dibujado encima del papel (agujas, boli) usa --art-navy y no --art-ink,
   * que de noche es claro. */
  --art-stage: var(--color-surface-alt);
  --art-glow: var(--color-surface-alt);  /* sin resplandor: de noche es una mancha */
  --art-floor: var(--color-surface-alt); /* la mesa tampoco: sus esquinas dibujaban media caja */
  --art-card: var(--color-surface);
  --art-card-edge: var(--color-border);
  --art-paper: #D9E3F2;
  --art-paper-shade: #9FB1CE;
  --art-line: #3C3C44;
  --art-dash: #4D73AB;
  --art-ink: #DCE5F3;
  --art-shadow: rgba(0, 0, 0, .55);
  --art-blue: #4C95F7;
  --art-blue-deep: #3A75E0;
  --art-blue-soft: #5F8FD4;
  --art-green: #3DD0AB;
  --art-purple: #AE9BFB;
  --art-amber: #FDC57F;
  --art-red: #F2747C;
  --art-navy: #3A5589;
  --art-sweater: #2C4A86;
  --art-silver: #8595B8;
  --art-hair: #3B3850;
  --art-leaf: #52BD95;
  --art-leaf-deep: #3AA083;

  /* Black shadows disappear on a dark page, so they are deeper and a soft ring
   * of light does the lifting instead. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .40);
  --shadow: 0 8px 24px rgba(0, 0, 0, .48);
  --shadow-lg: 0 20px 52px rgba(0, 0, 0, .60);
}

@font-face {
  font-family: "Changa One";
  src: url("/static/fonts/ChangaOne-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Sora";
  src: url("/static/fonts/Sora-VariableFont_wght.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

/* Panel and account pages. Colours come from the brand variables that
   build_assets.py prepends; there is not one hex code in this file. */

:root {
  /* Same two stacks as landing/src/site.css, so the mark in the bar is the
     same mark the visitor just saw on the public site. */
  --font-body: "Sora", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-brand: "Changa One", "Sora", system-ui, sans-serif;
  --ease: cubic-bezier(.2, .7, .2, 1); --fast: 160ms;
}

*, *::before, *::after { box-sizing: border-box; }

/* Same as the public site: someone who asked their system for less movement
   gets the theme change without the reveal. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0ms !important; animation: none !important; }
}

/* Same reason as on the public site: .field__eye sets a display, so without
   this the button would show even while marked hidden. */
[hidden] { display: none !important; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem; line-height: 1.6;
  color: var(--color-ink); background: var(--color-surface-alt);
  -webkit-font-smoothing: antialiased;
}
h1 { margin: 0 0 10px; font-size: 1.55rem; line-height: 1.2; letter-spacing: -.01em; }
p { margin: 0; }
a { color: var(--color-accent-strong); }
/* Un solo anillo al enfocar. Antes se dibujaban dos: el borde del elemento
   cambiaba a azul y encima aparecía un contorno separado por un hueco de 3 px.
   Ahora el contorno se pega al borde y los dos son del mismo azul, así que se
   leen como una sola línea gruesa.

   Sin border-radius aquí: el contorno ya sigue el del elemento, y ponerlo
   cuadraba las píldoras justo al enfocarlas. */
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 0; }

.bar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px clamp(16px, 4vw, 28px);
  background: var(--color-background); color: var(--color-on-dark);
}
/* The brand block is the one from the public site, gap and all: same wing at
   the same size, same wordmark in the same typeface. */
.bar__brand {
  display: inline-flex; align-items: center; gap: 12px;
  color: inherit; text-decoration: none;
}
.bar__brand:hover { text-decoration: none; }
.bar__name {
  font-family: var(--font-brand); font-size: 1.7rem; line-height: 1;
  letter-spacing: .01em; color: var(--color-logo);
}
.bar__wing { display: block; width: 52px; flex: none; }
.bar__wing svg { display: block; width: 100%; height: auto; }
/* The two halves of the mark follow the theme, which is the whole reason the
   wing is inlined instead of loaded as an image. */
.bar__wing .wing-fill { fill: var(--color-logo); }
.bar__wing .wing-shadow { fill: var(--color-shadow); }
.bar__actions { display: flex; align-items: center; gap: 10px; }

/* The one control in the bar: a <details>, so it opens with no JavaScript.
   Signed in it wears the company's name; signed out, three lines. */
.menu { position: relative; }
.menu__button {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 8px 12px;
  font-weight: 600; font-size: .95rem; color: inherit;
  border: 1px solid rgba(255, 255, 255, .4); border-radius: 11px;
  cursor: pointer; list-style: none;
  transition: background-color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.menu__button::-webkit-details-marker { display: none; }
.menu__button:hover { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .7); }
/* A long company name shortens instead of pushing the bar out of shape. */
.menu__who { max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu__bars { display: grid; gap: 4px; width: 20px; }
.menu__bars span { display: block; height: 2px; background: currentColor; border-radius: 2px; }
.menu__caret { display: grid; transition: transform var(--fast) var(--ease); }
.menu[open] > summary .menu__caret { transform: rotate(180deg); }

.menu__panel {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 60;
  min-width: 232px; padding: 8px;
  color: var(--color-ink); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: 14px;
  box-shadow: var(--shadow-lg);
}
.menu__form { margin: 0; }
.menu__item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  margin: 0; padding: 10px 12px;
  font: inherit; font-size: .95rem; text-align: left; text-decoration: none;
  color: var(--color-ink); background: transparent;
  border: 0; border-radius: 9px; cursor: pointer;
  transition: background-color var(--fast) var(--ease);
}
a.menu__item:hover, button.menu__item:hover { background: var(--color-hover); text-decoration: none; }
.menu__icons {
  display: inline-grid; place-items: center; flex: none; width: 20px; height: 20px;
  color: var(--color-ink-soft);
}
.menu__icons > span { display: none; grid-area: 1 / 1; }
.menu__group { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--color-border); }
/* El idioma, desplegado dentro del menú. La flecha del de fuera se escoge con
   el hijo directo: sin eso, abrir el menú giraba también la de esta fila. */
.menu__sub > summary { list-style: none; }
.menu__sub > summary::-webkit-details-marker { display: none; }
.menu__value { margin-left: auto; font-size: .88rem; color: var(--color-ink-soft); }
.menu__sub[open] > summary .menu__caret { transform: rotate(180deg); }
.menu__subpanel { padding-left: 18px; }
.menu__title {
  padding: 6px 12px 2px; font-size: .78rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--color-ink-soft);
}
/* The language that works, and the one that is only announced. */
.menu__item.is-on { cursor: default; font-weight: 600; }
.menu__item.is-off { cursor: default; color: var(--color-ink-soft); }
.menu__item.is-on .menu__icons { color: var(--color-accent-strong); }

/* Theme toggle. The icon shows the action, not the state: a sun while dark
   (press to go light) and a moon while light, same as the public site. */
:root[data-theme="dark"] .theme-toggle__sun { display: grid; }
:root:not([data-theme="dark"]) .theme-toggle__moon { display: grid; }

/* Circular reveal: the incoming theme grows over the outgoing one, so only the
   new snapshot is animated and the old one stays put underneath. */
::view-transition-old(root) { animation: none; mix-blend-mode: normal; }
::view-transition-new(root) { animation: none; mix-blend-mode: normal; }

.wrap { width: min(100% - 32px, 620px); margin: clamp(24px, 6vw, 56px) auto; }
/* Las pantallas con menú de secciones al lado —Configuración, Contactos,
   Administración— y las que enseñan gráficas o tablas. 620 px no da para las
   dos columnas, y 980 dejaba la mitad de un monitor en blanco: el menú flotando
   lejos del borde y la gráfica de envíos dibujada en un cuarto de la pantalla.

   El tope no es adorno. Sin él, en un monitor ancho una línea de texto se
   estira hasta hacerse ilegible y la tabla de contactos separa tanto sus
   columnas que hay que recorrerla con la cabeza. */
.wrap--wide { width: min(100% - 32px, 1400px); }
/* La lista de contactos es la pantalla con más columnas de todas, así que no
   puede ser más estrecha que el resto. Hoy vale lo mismo que --wide; queda como
   clase aparte porque la nombra su plantilla. */
.wrap--table { width: min(100% - 32px, 1400px); }
/* Las tablas, las gráficas y las listas de cifras llenan el ancho, que es para
   lo que se ensanchó. Los campos de escribir no: un cuadro de mil cuatrocientos
   píxeles para un motivo o un nombre es peor de leer y de apuntar que uno de la
   medida del dato que va dentro.

   Cuelga del contenedor y no de la tarjeta blanca: Plantillas y Estadísticas no
   tienen tarjeta, y atarlo a ella dejaba sus campos estirados de lado a lado. El
   contenedor estrecho —entrar, registrarse, contratar— no lleva tope: mide
   620 px y ahí ocupar todo el ancho es lo correcto. */
.wrap--wide input, .wrap--wide select, .wrap--wide textarea,
.wrap--table input, .wrap--table select, .wrap--table textarea {
  max-width: 560px;
}

.card {
  padding: clamp(22px, 4vw, 32px); border-radius: 16px;
  background: var(--color-surface); border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}
.card--narrow { max-width: 460px; margin-inline: auto; }
.lead { margin-bottom: 6px; color: var(--color-ink-soft); }
.status { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--color-border); }

label { display: block; margin-top: 18px; margin-bottom: 6px; font-weight: 600; font-size: .95rem; }
/* --color-field y no --color-border: el contorno de un campo tiene que verse
   contra el fondo, y el de las lineas que separan no llega. */
input {
  width: 100%; padding: 11px 13px; font: inherit;
  color: var(--color-ink); background: var(--color-surface);
  border: 1px solid var(--color-field); border-radius: 8px;
}
select {
  width: 100%; padding: 11px 13px; font: inherit;
  color: var(--color-ink); background: var(--color-surface);
  border: 1px solid var(--color-field); border-radius: 8px;
}
/* El texto largo de una plantilla. Lo mismo que un campo, salvo que crece a lo
   alto y solo a lo alto: a lo ancho se saldria de la columna. */
textarea {
  width: 100%; padding: 11px 13px; font: inherit; resize: vertical;
  color: var(--color-ink); background: var(--color-surface);
  border: 1px solid var(--color-field); border-radius: 8px;
}
input[type="file"] { padding: 9px 11px; cursor: pointer; }
input:focus, select:focus, textarea:focus { border-color: var(--color-accent); }
/* One box per digit. Monospace and centred, so the six read as six. */
.code { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; max-width: 320px; }
.code__box {
  width: 100%; padding: 12px 0;
  font-family: Consolas, Menlo, monospace; font-size: 1.5rem; font-weight: 700;
  text-align: center; caret-color: var(--color-accent);
}
.code__box:disabled, .btn:disabled {
  opacity: .5; cursor: not-allowed; filter: grayscale(.4);
}
.btn:disabled:hover { transform: none; filter: grayscale(.4); }

/* How long the code has left. What it says decides nothing: the expiry that
   counts is the one in the database. */
.countdown {
  margin-top: 14px; font-size: .95rem; font-weight: 600;
  color: var(--color-accent-strong);
}
.countdown.is-expired { color: var(--color-ink-soft); font-weight: 500; }
.hint { margin-top: 6px; font-size: .85rem; color: var(--color-ink-soft); }

/* A field with a button inside it: the eye that reveals the password. */
.field { position: relative; }
.field input { padding-right: 48px; }
.field__eye {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center; width: 36px; height: 36px; padding: 0;
  color: var(--color-ink-soft); background: transparent; cursor: pointer;
  border: 0; border-radius: 8px;
  transition: color var(--fast) var(--ease), background-color var(--fast) var(--ease);
}
.field__eye:hover { color: var(--color-ink); background: var(--color-surface-alt); }
.field__eye > span { display: none; grid-area: 1 / 1; }
.field__eye[aria-pressed="false"] .field__eye-on { display: grid; }
.field__eye[aria-pressed="true"] .field__eye-off { display: grid; }
.field__eye[aria-pressed="true"] { color: var(--color-accent-strong); }

/* The four password rules. The tick stays grey while the rule is unmet and
   turns brand blue once it is: the progress reads without reading a word. */
.rules__title { margin-top: 10px; font-size: .85rem; color: var(--color-ink-soft); }
.rules { margin: 6px 0 0; padding: 0; list-style: none; display: grid; gap: 4px; }
.rules__item {
  display: flex; align-items: center; gap: 8px;
  font-size: .85rem; color: var(--color-ink-soft);
  transition: color var(--fast) var(--ease);
}
.rules__check {
  display: grid; place-items: center; flex: none; width: 18px; height: 18px;
  /* Inherits the muted colour of its row: a border colour was nearly
     invisible against the dark background. */
  color: inherit; opacity: .55;
  transition: color var(--fast) var(--ease), opacity var(--fast) var(--ease),
              transform var(--fast) var(--ease);
}
.rules__item.is-met { color: var(--color-ink); }
.rules__item.is-met .rules__check {
  color: var(--color-accent); opacity: 1; transform: scale(1.12);
}
.hint--legal { margin-top: 14px; text-align: center; }

.btn {
  display: inline-block; margin-top: 22px; padding: 12px 22px;
  font: inherit; font-weight: 600; text-align: center; text-decoration: none;
  color: var(--color-on-accent); background: var(--color-accent);
  border: 0; border-radius: 8px; cursor: pointer;
  transition: transform 160ms ease, filter 160ms ease;
}
.btn:hover { transform: translateY(-1px); filter: brightness(1.06); }
/* El sólido no tiene borde y su fondo ya es azul: un anillo azul encima
   no se vería, así que lleva el azul oscuro. */
.btn:focus-visible { outline-color: var(--color-accent-strong); }
.btn--small { margin-top: 12px; padding: 8px 14px; font-size: .9rem; }
/* For buttons inside a card, where the white-on-blue quiet button would be
   invisible. */
.btn--outline {
  background: transparent; color: var(--color-accent-strong);
  border: 1px solid var(--color-border);
}
.btn--outline:hover { background: var(--color-surface-alt); filter: none; transform: none; }

/* Elegir archivo. El control del navegador no se puede pintar; se esconde sin
   quitarle el foco y la etiqueta hace de botón. El anillo se dibuja alrededor
   de la etiqueta cuando el campo escondido tiene el foco del teclado. */
.filepick { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; }
/* Dos clases y no una: `input[type="file"]` de arriba tiene más peso que una
   clase suelta y le devolvía el relleno, dejando una caja de 24x20 escondida. */
.filepick .filepick__input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: 0;
  border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.filepick label { margin-top: 14px; }
.filepick__input:focus-visible + label {
  outline: 2px solid var(--color-accent-strong); outline-offset: 2px;
}
.filepick__name {
  margin-top: 14px; font-size: .9rem; color: var(--color-ink-soft);
  overflow-wrap: anywhere;
}
.filepick__name.is-set { color: var(--color-ink); font-weight: 600; }

/* El nombre del campo cuando no hay un <label> que apunte a él, porque quien
   apunta al campo es el botón. */
.field-label { margin: 18px 0 0; font-weight: 600; font-size: .95rem; }

/* "Keep me signed in": a checkbox, not a field, so it does not inherit the
   full-width input rules above. */
.check { display: flex; align-items: center; gap: 10px; margin-top: 18px;
         font-weight: 500; font-size: .95rem; cursor: pointer; }
.check input { width: auto; margin: 0; accent-color: var(--color-accent); }

/* The devices an account is open on. */
.card--loose { margin-top: 18px; }
.card__title { margin: 0 0 8px; font-size: 1.2rem; font-weight: 700; }
.devices { margin: 16px 0 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.device {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 14px; border: 1px solid var(--color-border); border-radius: 12px;
}
.device__name { font-weight: 600; }
.device__meta { margin-top: 2px; font-size: .85rem; color: var(--color-ink-soft); }
.device form { margin: 0; }
.device .btn { margin-top: 0; }
.tag {
  display: inline-block; margin-left: 8px; padding: 2px 8px; vertical-align: middle;
  font-size: .75rem; font-weight: 600; border-radius: 999px;
  /* Un óvalo partido en dos líneas no se lee como una etiqueta: «Junta
     directiva» tiene que caber entera o no caber. */
  white-space: nowrap;
  color: var(--color-on-accent); background: var(--color-accent);
}
.tag--quiet {
  color: var(--color-ink-soft); background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
}
.tag--on { color: var(--color-on-accent); background: var(--color-accent); }
.tag--warn { color: var(--color-accent-strong); background: var(--color-accent-soft); }
.notice--ok { border-color: var(--color-accent); }
/* Un aviso que no impide nada, pero que conviene leer. */
.notice--warn { border-color: #D97706; }

/* ------------------------------------------------------------- settings
   The shape of YouTube's settings screen —sections down the left, rows of
   "what it is / what you can do" on the right— in this project's colours. */
.settings__heading { margin-bottom: 18px; }
.settings { display: grid; gap: 22px; align-items: start; }
/* El menú, pegado a la izquierda y estrecho: lo que gana de ancho se lo lleva
   el contenido, que es a lo que se viene. Por debajo de 780 px cae en
   horizontal, que es lo que lo hace usable en un teléfono. */
@media (min-width: 780px) { .settings { grid-template-columns: 190px 1fr; gap: 24px; } }

.settings__nav { display: flex; gap: 6px; overflow-x: auto; }
@media (min-width: 780px) {
  .settings__nav { position: sticky; top: 20px; flex-direction: column; overflow: visible; }
}
.settings__tab {
  padding: 11px 14px; border-radius: 10px; white-space: nowrap;
  font-weight: 600; font-size: .95rem; text-decoration: none;
  color: var(--color-ink-soft);
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.settings__tab:hover { background: var(--color-surface-alt); color: var(--color-ink); text-decoration: none; }
.settings__tab.is-current { background: var(--color-accent-soft); color: var(--color-accent-strong); }

.settings__pane {
  padding: clamp(20px, 3.5vw, 30px); border-radius: 16px;
  background: var(--color-surface); border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
}
.settings__title { margin: 0 0 6px; font-size: 1.3rem; font-weight: 700; }
.settings__subtitle {
  margin: 30px 0 4px; padding-top: 22px; font-size: 1.05rem; font-weight: 700;
  border-top: 1px solid var(--color-border);
}
/* Una fila ya trae su propia línea abajo: sin esto quedaban dos rayas
   seguidas donde una sección empieza justo después de una. */
.setting + .settings__subtitle { padding-top: 14px; border-top: 0; }
.settings__lead { margin-bottom: 6px; color: var(--color-ink-soft); font-size: .95rem; }
/* La raya bajo el título de una sección que no lleva frase debajo. */
.settings__rule { margin: 14px 0 0; border: 0; border-top: 1px solid var(--color-border); }
.settings__pane form { margin: 0; }


/* One row. The action sits at the right edge, whatever it is: a button, a
   value, a tag or a switch. */
.setting {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 16px 0; border-bottom: 1px solid var(--color-border);
}
.setting:last-child { border-bottom: 0; padding-bottom: 0; }
.setting__text { flex: 1 1 260px; min-width: 0; }
.setting__title { margin: 0; font-size: 1rem; font-weight: 600; }
.setting__desc { margin-top: 3px; font-size: .88rem; color: var(--color-ink-soft); }
.setting__action { display: flex; align-items: center; gap: 10px; flex: none; }
.setting__action .btn { margin-top: 0; }
/* Un campo que se guarda en la misma fila, como la dirección postal. */
.setting__form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
                 justify-content: flex-end; }
.setting__form input[type="text"] { margin: 0; width: min(340px, 100%); }
.setting__form .error { flex: 1 1 100%; margin: 0; text-align: right; }
.setting__value { font-weight: 600; word-break: break-word; }
.setting__value--muted { font-weight: 500; color: var(--color-ink-soft); }

/* The notices that carry no switch, and say so. */
.fixed { margin: 14px 0 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.fixed__item {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; font-size: .93rem;
  background: var(--color-surface-alt); border-radius: 10px;
}
.fixed__icon { display: grid; flex: none; color: var(--color-ink-soft); }
.fixed__item .tag { margin-left: auto; }

/* A checkbox drawn as a switch. It is a real checkbox underneath, so it works
   with the keyboard and without any script. */
.switch { display: inline-flex; margin: 0; cursor: pointer; }
.switch input {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.switch__track {
  display: block; width: 46px; height: 26px; padding: 3px;
  background: var(--color-field); border-radius: 999px;
  transition: background-color var(--fast) var(--ease);
}
.switch__knob {
  display: block; width: 20px; height: 20px;
  background: var(--color-surface); border-radius: 50%;
  box-shadow: var(--shadow-sm);
  transition: transform var(--fast) var(--ease);
}
.switch input:checked + .switch__track { background: var(--color-accent); }
.switch input:checked + .switch__track .switch__knob { transform: translateX(20px); }
/* Encendido y bloqueado: un aviso que siempre sale. Se ve apagado de
   color para que se lea como algo que no se toca. */
.switch--locked { cursor: not-allowed; }
.switch--locked input:checked + .switch__track { background: var(--color-field); opacity: .7; }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--color-accent-strong); outline-offset: 2px; }

/* Two-step verification: the QR, the secret to type by hand, and the recovery
   codes. The QR keeps its white box in both themes, because a scanner needs
   the contrast more than the page needs to match. */
.qr {
  display: inline-block; margin-top: 16px; padding: 10px;
  background: #FFFFFF; border-radius: 12px; line-height: 0;
}
.secret {
  margin-top: 6px; padding: 10px 12px; border-radius: 8px;
  font-family: Consolas, Menlo, monospace; font-size: 1rem; letter-spacing: .08em;
  word-break: break-all; background: var(--color-surface-alt);
}
.steps { margin: 14px 0 0; padding-left: 20px; display: grid; gap: 6px;
         color: var(--color-ink-soft); }
.codes {
  margin: 16px 0 0; padding: 16px; list-style: none;
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px;
  font-family: Consolas, Menlo, monospace; font-size: 1.05rem; font-weight: 700;
  text-align: center; background: var(--color-surface-alt); border-radius: 12px;
}
.recovery { margin-top: 18px; }
.recovery summary { cursor: pointer; color: var(--color-accent-strong);
                    font-size: .9rem; }
/* Meter contactos y buscar entre los que hay son dos cosas distintas: los
   botones no se pegan entre sí ni al buscador de abajo. */
.row { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 4px; }
.row .btn { margin-top: 14px; }

/* --------------------------------------------------------------- contactos
   La misma pantalla que configuración, más una tabla y un contador. */

/* Cuánto cabe todavía. Vive bajo las pestañas porque es la misma cifra en las
   tres y es la que decide si se puede seguir subiendo gente. */
.quota {
  margin-top: 14px; padding: 12px 14px; border-radius: 10px;
  font-size: .88rem; line-height: 1.5; color: var(--color-ink-soft);
  background: var(--color-surface-alt); border: 1px solid var(--color-border);
}
.quota.is-full { border-color: var(--color-accent); }
.quota b { color: var(--color-ink); }

/* Buscar y filtrar, en una línea que se parte sola en el teléfono. */
/* Meter contactos y buscar entre los que hay son dos cosas distintas, así que
   se separan en vez de leerse como una sola barra de botones. */
.filters { display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
           margin: 26px 0 16px; }
.filters input, .filters select { width: auto; flex: 1 1 180px; min-width: 0; }
.filters .btn { margin-top: 0; }
.filters .hint { margin-top: 0; flex: 1 1 100%; }

/* Una tabla ancha se desplaza dentro de su caja: la página nunca se va de
   lado, que en el teléfono rompe todo lo demás. */
.table-wrap { margin-top: 16px; overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.table th {
  padding: 8px 12px 8px 0; text-align: left; font-size: .78rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--color-ink-soft);
  border-bottom: 1px solid var(--color-border); white-space: nowrap;
}
.table td {
  padding: 12px 12px 12px 0; vertical-align: middle;
  /* Ninguna celda se parte en dos líneas: si no cabe, la tabla se desliza
     dentro de su caja, que es lo que ya hace, y la página nunca se va de lado. */
  white-space: nowrap;
  border-bottom: 1px solid var(--color-border);
}
/* Los dos botones de cada fila, juntos y sin que la fila crezca. */
.table__actions { display: flex; gap: 8px; }
.table tr:last-child td { border-bottom: 0; }
.table__quiet { color: var(--color-ink-soft); font-size: .85rem; white-space: nowrap; }
.table form { margin: 0; }
.table .btn { margin-top: 0; }
.table .tag { margin-left: 0; margin-right: 6px; }

/* Lo que pasó con un archivo: una cifra por línea, y la cifra a la derecha. */
/* ------------------------------------------------------------ estadísticas
   La gráfica se dibuja en SVG desde la plantilla, sin JavaScript: la cabecera
   del panel solo deja cargar guiones propios, así que una librería de fuera no
   se cargaría, y traerse una al repositorio sería algo que mantener y auditar
   para pintar unos rectángulos.

   Los dos colores salen de la marca; no se inventa ninguno. El color no es lo
   único que distingue las series: cada barra lleva su título y debajo va la
   leyenda con los nombres. */
.chart { margin-top: 14px; }
/* La escala a la izquierda, la gráfica al lado, y debajo de la gráfica su eje. */
.chart__frame {
  display: grid; grid-template-columns: 44px minmax(0, 1fr); column-gap: 8px;
}
.chart__scale {
  display: flex; flex-direction: column; justify-content: space-between;
  height: 220px; text-align: right; font-size: .75rem; line-height: 1;
  color: var(--color-ink-soft); font-variant-numeric: tabular-nums;
}
.chart__scale span { transform: translateY(-50%); }
.chart__scale span:first-child { transform: none; }
.chart__scale span:last-child { transform: translateY(-100%); }
.chart__plot { position: relative; height: 220px; }
.chart__svg {
  display: block; width: 100%; height: 220px;
  background: var(--color-surface-alt); border-radius: 10px;
}
.chart__grid { stroke: var(--color-border); stroke-width: 1; }
.chart__axis { stroke: var(--color-field); stroke-width: 1.5; }
/* Dos colores para todo: el de la marca para lo que se busca (envíos,
   aperturas, altas) y el apagado para lo que no (rebotes, clics, bajas). Las
   barras de «Cuándo abren» y las líneas del crecimiento usan las mismas
   claves, así que van aquí y no en reglas aparte. */
.chart__bar--sent, .chart__bar--open, .chart__bar--added { fill: var(--color-accent); }
.chart__bar--bounce, .chart__bar--click, .chart__bar--left { fill: var(--color-ink-soft); }
.chart__line--added, .chart__dot--added { stroke: var(--color-accent); }
.chart__line--left, .chart__dot--left { stroke: var(--color-ink-soft); }
.chart__line { stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.chart__line--open, .chart__dot--open { stroke: var(--color-accent); }
.chart__line--click, .chart__dot--click { stroke: var(--color-ink-soft); }
.chart__dot { stroke-width: 7; stroke-linecap: round; }

/* Una columna transparente por tramo. Señalarla (con el ratón, un dedo o el
   teclado) la marca y abre su cuadrito. */
.chart__cols { position: absolute; inset: 0; display: flex; }
.chart__col { position: relative; flex: 1 1 0; outline: none; border-radius: 4px; }
.chart__col:hover, .chart__col:focus-visible { background: rgba(127, 127, 127, .12); }
.chart__tip {
  display: none; position: absolute; z-index: 5; bottom: calc(100% + 6px);
  left: 50%; transform: translateX(-50%); min-width: 150px; padding: 8px 10px;
  background: var(--color-surface); color: var(--color-ink);
  border: 1px solid var(--color-border); border-radius: 8px; box-shadow: var(--shadow);
  font-size: .8rem; line-height: 1.4; white-space: nowrap; pointer-events: none;
}
.chart__col:hover .chart__tip, .chart__col:focus-visible .chart__tip { display: grid; gap: 2px; }
/* Los de las orillas se abren hacia dentro para no salirse de la pantalla. */
.chart__col:first-child .chart__tip, .chart__col:nth-child(2) .chart__tip { left: 0; transform: none; }
.chart__col:last-child .chart__tip, .chart__col:nth-last-child(2) .chart__tip {
  left: auto; right: 0; transform: none; }
.chart__tip-row { display: inline-flex; align-items: center; gap: 6px; }
.chart__tip-row::before { content: ""; width: 9px; height: 9px; border-radius: 2px; }

/* El eje del tiempo: una casilla por tramo, del ancho de su barra. */
.chart__axis-x {
  display: flex; margin: 6px 0 0; height: 1.2em;
  font-size: .75rem; color: var(--color-ink-soft);
}
.chart__axis-x span { flex: 1 1 0; min-width: 0; text-align: center;
                      white-space: nowrap; overflow: visible; }
.chart__legend { display: flex; flex-wrap: wrap; gap: 16px; margin: 10px 0 0 52px;
                 font-size: .88rem; }
.filters__export { display: flex; gap: 8px; margin-top: 10px; }

/* Una dirección larga parte donde haga falta en vez de estirar la tabla. */
.table__wrap { overflow-wrap: anywhere; max-width: 520px; }

.chart__key { display: inline-flex; align-items: center; gap: 7px; }
.chart__key::before {
  content: ""; width: 12px; height: 12px; border-radius: 3px;
}
.chart__key--sent::before, .chart__key--open::before,
.chart__key--added::before { background: var(--color-accent); }
.chart__key--bounce::before, .chart__key--click::before,
.chart__key--left::before { background: var(--color-ink-soft); }
/* Cuando no hay nada, el cuadro se dibuja igual y la frase va encima: enseña de
   antemano la forma que va a tener, que es más de lo que dice un hueco. */
.chart__nothing {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  margin: 0; padding: 0 24px; text-align: center;
  font-size: .92rem; color: var(--color-ink-soft);
}

/* Cómo le fue: una tarjeta por cifra, el porcentaje grande y de cuántos. */
.rates {
  margin: 12px 0 0; padding: 0; list-style: none; display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}
.rates__one {
  display: grid; gap: 2px; padding: 12px 14px; border-radius: 12px;
  background: var(--color-surface); border: 1px solid var(--color-border);
}
.rates__name { font-size: .8rem; font-weight: 600; color: var(--color-ink-soft); }
.rates__big { font-size: 1.5rem; line-height: 1.2; font-variant-numeric: tabular-nums; }
.rates__of { font-size: .8rem; color: var(--color-ink-soft); font-variant-numeric: tabular-nums; }
/* La cifra y su pastilla en la misma línea; si no cabe, la pastilla baja. */
.rates__line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* El cambio contra el periodo anterior. Verde es que mejoró y rojo que
   empeoró, no que subiera: más rebotes va en rojo con la flecha hacia arriba.
   Los dos colores son los del resto del panel (el rojo de peligro y un verde
   que se lee igual sobre blanco y sobre el fondo oscuro). */
.trend {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 999px;
  font-size: .8rem; font-weight: 700; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.trend .icon { flex: none; }
.trend.is-good { color: #067647; background: rgba(6, 118, 71, .12); }
.trend.is-bad { color: #B42318; background: rgba(180, 35, 24, .12); }
:root[data-theme="dark"] .trend.is-good { color: #4ADE80; background: rgba(74, 222, 128, .14); }
:root[data-theme="dark"] .trend.is-bad { color: #FCA5A5; background: rgba(252, 165, 165, .14); }

.counts--wide { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                gap: 6px 24px; }

.counts { margin: 10px 0 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.counts li {
  display: flex; justify-content: space-between; gap: 16px;
  font-size: .92rem; padding-bottom: 6px;
  border-bottom: 1px solid var(--color-border);
}
.counts li:last-child { border-bottom: 0; padding-bottom: 0; }

/* Una pregunta aparte dentro de un formulario, enmarcada: de dónde salió la
   lista, y qué etiquetas lleva. */
.fieldset {
  margin-top: 22px; padding: 14px 16px 18px;
  border: 1px solid var(--color-border); border-radius: 12px;
}
.fieldset legend { padding: 0 6px; font-weight: 700; font-size: .95rem; }
.fieldset label:first-of-type { margin-top: 10px; }

/* Las etiquetas se marcan, no se escriben. En rejilla para que veinte quepan
   sin convertir el formulario en una lista interminable. */
.picker { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.picker__item {
  display: inline-flex; align-items: center; gap: 8px; margin: 0;
  padding: 8px 12px; font-weight: 500; font-size: .92rem; cursor: pointer;
  border: 1px solid var(--color-field); border-radius: 999px;
  transition: background-color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.picker__item:hover { background: var(--color-surface-alt); }
.picker__item input { width: auto; margin: 0; accent-color: var(--color-accent); }
.picker__item:has(input:checked) {
  background: var(--color-accent-soft); border-color: var(--color-accent);
}

.error { margin-top: 6px; font-size: .9rem; font-weight: 600; color: var(--color-accent-strong); }
.error--form {
  margin: 0 0 6px; padding: 12px 14px; border-radius: 8px;
  background: var(--color-accent-soft); color: var(--color-accent-strong);
}
.notice {
  margin-bottom: 18px; padding: 16px 18px; border-radius: 12px;
  background: var(--color-accent-soft); color: var(--color-ink);
  border: 1px solid var(--color-accent);
}
.foot { margin-top: 20px; font-size: .95rem; color: var(--color-ink-soft); }

/* --------------------------------------------------------------- plantillas
   Los dos caminos arriba, las notas, y la lista. */

/* Crear y cargar: las dos cosas que se vienen a hacer aquí, del mismo tamaño
   y lado a lado. Estrecha la pantalla, una debajo de otra. */
.start { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 22px; }
.start__one {
  flex: 1 1 240px; justify-content: center; text-align: center;
  padding: 18px 22px; font-size: 1.05rem;
}
.start__soon { font-weight: 500; font-size: .85rem; opacity: .8; }
/* Apagado sobre el fondo de la página se perdía: lleva su borde. */
.start__one.btn--off, .start__one.btn--off:hover {
  background: var(--color-surface); border: 1px solid var(--color-border);
}

/* Lo que conviene saber antes de empezar, en dos líneas y no en un párrafo. */
.notes {
  margin: 22px 0 0; padding: 16px 18px 16px 34px; display: grid; gap: 8px;
  background: var(--color-surface-alt); border: 1px solid var(--color-border);
  border-radius: 12px; color: var(--color-ink-soft); font-size: .95rem;
}
.notes code, .notes__marks code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: .88rem;
  color: var(--color-ink); background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: 6px; padding: 1px 6px;
}
.notes__marks { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: 6px; }

/* Las plantillas, en tarjetas: lo primero que se busca es cuál era, y eso se
   reconoce mirándolo. Arriba el correo de verdad, achicado en su marco. */
.cards {
  list-style: none; margin: 14px 0 0; padding: 0;
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.card-piece {
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: 14px; box-shadow: var(--shadow-sm);
}
.card-piece__view {
  height: 210px; overflow: hidden; background: #FFFFFF;
  border-bottom: 1px solid var(--color-border);
}
/* Un correo mide 600 px: se dibuja entero y se achica, sin que el marco reciba
   clics (la tarjeta entera no es un enlace, los botones sí). Centrado desde su
   propio medio: achicándolo desde la esquina se quedaba pegado a la izquierda
   en una tarjeta más ancha que los 228 px que mide ya achicado. */
.card-piece__view iframe {
  width: 600px; height: 700px; border: 0; pointer-events: none;
  position: relative; left: 50%; margin-left: -300px;
  transform: scale(.38); transform-origin: top center;
}
.card-piece__body { display: grid; gap: 6px; padding: 12px 14px 14px; }
.card-piece__name { overflow-wrap: anywhere; }
.card-piece__what { font-size: .82rem; color: var(--color-ink-soft); }
.card-piece__doing { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.card-piece__doing form { margin: 0; }
.card-piece__doing .btn { margin-top: 0; }

/* La bandeja de cargar: sale de la derecha, encima de la lista. */
.drawer {
  margin: 0 0 0 auto; height: 100%; max-height: 100%; width: min(480px, 100%);
  padding: 22px 24px; border: 0; border-left: 1px solid var(--color-border);
  background: var(--color-surface); color: var(--color-ink);
  box-shadow: var(--shadow-lg);
}
.drawer::backdrop { background: rgba(0, 0, 0, .45); }
/* Las dos del lienzo (la vista previa y los atajos) piden más ancho: un correo
   mide 600 px y los atajos van en dos columnas. */
.drawer--wide { width: min(860px, 100%); overflow-y: auto; }
.drawer__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.drawer__head .settings__subtitle { margin: 0; padding-top: 0; border-top: 0; }
.drawer__close {
  width: 36px; height: 36px; border-radius: 9px; border: 1px solid var(--color-border);
  background: transparent; color: var(--color-ink); font-size: 1.3rem; line-height: 1;
  cursor: pointer;
}
.drawer__close:hover { background: var(--color-surface-alt); }

/* El código de una pieza: se lee en monoespaciada y no se parte en renglones,
   que en HTML cambiaría lo que se ve al editarlo. */
.code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: .85rem; line-height: 1.5; white-space: pre; overflow: auto;
  tab-size: 2; min-height: 420px;
}

/* ------------------------------------------------------------- el lienzo
   Dos columnas: lo que se agrega y la hoja. La vista previa vive en su
   ventana. En un teléfono la hoja se desplaza de lado,
   porque tiene los 600 px de un correo. */
.editor__head {
  display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between;
  gap: 14px; margin-top: 18px;
}
.editor__name { flex: 1 1 280px; max-width: 420px; }
.editor__actions { display: flex; flex-wrap: wrap; gap: 10px; }
.editor__actions .btn { margin-top: 0; }
.editor__narrow { display: none; }
@media (max-width: 760px) { .editor__narrow { display: block; } }

/* Dos columnas: las herramientas y la hoja. La vista previa se fue a su
   ventana, que es donde no le quita ancho al lienzo. */
.editor {
  display: grid; gap: 22px; margin-top: 18px; align-items: start;
  grid-template-columns: 170px minmax(0, 1fr);
}
@media (max-width: 760px) { .editor { grid-template-columns: 1fr; } }

.editor__tools { position: sticky; top: 18px; display: grid; gap: 10px; }
.editor__adds { display: grid; gap: 8px; }
.tool {
  padding: 10px 12px; border-radius: 10px; border: 1px solid var(--color-border);
  background: var(--color-surface); color: var(--color-ink); font: inherit;
  font-weight: 600; text-align: left; cursor: pointer;
}
.tool:hover { border-color: var(--color-accent); color: var(--color-accent-strong); }
/* Geometría: un menú que abre sin guion, con las seis figuras en dos columnas. */
.geo > summary { list-style: none; }
.geo > summary::-webkit-details-marker { display: none; }
.geo[open] > summary { border-color: var(--color-accent); color: var(--color-accent-strong); }
.geo__list { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-top: 6px; }
.geo__one { padding: 7px 8px; font-size: .8rem; }

/* Alto fijo: si creciera o encogiera según lo elegido, la hoja de abajo se
   movería justo mientras se hace clic en ella. */
.props {
  position: sticky; top: 0; z-index: 40; padding: 10px 12px; height: 158px;
  overflow-y: auto; box-sizing: border-box;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: 12px;
}
.props__none { margin: 8px 0; color: var(--color-ink-soft); font-size: .92rem; }
.props__row { display: flex; flex-wrap: wrap; align-items: end; gap: 10px 12px; }
.props__row .btn { margin-top: 0; }
.props__field { display: grid; gap: 2px; font-size: .75rem; font-weight: 600;
                color: var(--color-ink-soft); margin: 0; }
.props__field input, .props__field select { margin: 0; min-width: 120px; padding: 6px 8px; }
.props__field--small input, .props__field--small select { min-width: 0; width: 76px; }
.props__field--color input { min-width: 0; width: 46px; height: 34px; padding: 2px; }
.props__check { display: inline-flex; align-items: center; gap: 6px; font-size: .9rem;
                margin: 0 0 8px; }
.props__row .props__none { flex: 1 1 100%; }
.props__tip { flex: 1 1 100%; margin: 0; font-size: .8rem; color: var(--color-ink-soft); }
/* Separa los grupos de botones de la barra de varios elegidos. */
.props__sep { width: 1px; align-self: stretch; background: var(--color-border); }
.props__row .field-label { margin: 0; align-self: center; }

/* `safe` y no `center` a secas: con `overflow-x`, en una ventana más angosta
   que la hoja el centrado normal corta el borde izquierdo.
   El aire de arriba es el sitio del tirador del giro, que sale 32 px por
   encima de la caja: sin él, el de un elemento pegado al borde de arriba caía
   debajo de la barra de propiedades y no se podía agarrar. */
.stage { display: grid; justify-items: safe center; margin-top: 14px; overflow-x: auto;
         padding: 36px 8px 12px; }

/* La hoja mide lo que mide en el correo: 600 px de ancho. */
/* `isolation` encierra las capas de dentro: sin eso, un texto o un botón de
   la hoja pasaba por encima de la barra al desplazarse. Sin overflow
   escondido, para que los tiradores de una caja pegada al borde se vean. */
.cv-sheet {
  position: relative; flex: none; isolation: isolate;
  box-shadow: 0 0 0 1px var(--color-border), var(--shadow-sm);
  touch-action: none; user-select: none;
}
.cv-item { position: absolute; box-sizing: border-box; cursor: move;
           white-space: pre-wrap; overflow-wrap: break-word; }
.cv-item--image { background-position: center; background-repeat: no-repeat;
                  background-color: rgba(0, 0, 0, .04); z-index: 1; }
.cv-item--shape { z-index: 1; }
/* El color de una figura, en un hijo: recortar la caja recortaría también sus
   tiradores. */
.cv-fill { position: absolute; inset: 0; }
.cv-item--text, .cv-item--button { z-index: 10; }
/* Los tiradores de lo elegido, en su propia capa encima de la hoja y no dentro
   del elemento: los hijos de un `.cv-item` no pueden escaparse de su z-index, y
   el del giro sale 30 px por encima de la caja. Subir el elemento elegido los
   dejaba agarrables, pero una figura de atrás saltaba delante de todo al
   tocarla. Sin ratón para que un clic en el hueco llegue a lo de debajo. */
.cv-chrome { position: absolute; z-index: 45; pointer-events: none; }
.cv-chrome .cv-handle, .cv-chrome .cv-turn { pointer-events: auto; }
/* Sin overflow escondido: taparía los tiradores de las esquinas. */
.cv-item--button { text-align: center; white-space: nowrap; }
.cv-item:hover { outline: 1px dashed var(--color-accent); }
.cv-item.is-sel { outline: 2px solid var(--color-accent); }
.cv-item.is-bad { outline: 2px solid #D92D20; background-color: rgba(217, 45, 32, .08); }
.cv-item.is-editing { cursor: text; user-select: text; outline: 2px solid var(--color-accent);
                      background: rgba(255, 255, 255, .6); }
.cv-probe { visibility: hidden; left: 0; top: 0; }
/* Un texto con viñetas: cada renglón, un bloque con la suya delante y sangría
   francesa. La columna mide lo mismo que en el correo (`canvas.dot_px()`), y
   mientras se escribe el texto va plano con la misma sangría, así que se
   parte igual. */
.cv-li { position: relative; padding-left: var(--cv-dot, 19px); }
.cv-li::before { content: "\2022"; position: absolute; left: 0; width: var(--cv-dot, 19px);
                 text-align: center; }
.cv-li--blank::before { content: none; }
.cv-item--list.is-editing { padding-left: var(--cv-dot, 19px); }
/* Una línea puede medir 1 px: una franja invisible arriba y abajo deja
   pulsarla sin apuntar al píxel. Gira con ella. */
.cv-item--line::after { content: ""; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px; }
.cv-handle {
  position: absolute; width: 12px; height: 12px; border-radius: 3px;
  background: #FFFFFF; border: 2px solid var(--color-accent); z-index: 20;
}
.cv-handle--nw { left: -7px; top: -7px; cursor: nwse-resize; }
.cv-handle--ne { right: -7px; top: -7px; cursor: nesw-resize; }
.cv-handle--sw { left: -7px; bottom: -7px; cursor: nesw-resize; }
.cv-handle--se { right: -7px; bottom: -7px; cursor: nwse-resize; }
/* Los lados: en una foto recortan, en un rectángulo estiran. */
.cv-handle--n { left: calc(50% - 6px); top: -7px; cursor: ns-resize; }
.cv-handle--s { left: calc(50% - 6px); bottom: -7px; cursor: ns-resize; }
.cv-handle--e { right: -7px; top: calc(50% - 6px); cursor: ew-resize; }
.cv-handle--w { left: -7px; top: calc(50% - 6px); cursor: ew-resize; }
/* Los atajos del teclado, detrás de un botón: un <details>, así que abre sin
   JavaScript. */
.keys > summary { list-style: none; cursor: pointer; }
.keys > summary::-webkit-details-marker { display: none; }
/* En la ventana caben dos columnas de pares; en una pantalla angosta, una. */
.keys__list {
  display: grid; grid-template-columns: 1fr auto; gap: 6px 14px;
  margin: 10px 0 0; font-size: .9rem;
}
@media (min-width: 720px) {
  .keys__list { grid-template-columns: 1fr auto 1fr auto; column-gap: 26px; }
}
.keys__list dd { padding-right: 2px; }
.keys__list dt { color: var(--color-ink-soft); }
.keys__list dd {
  margin: 0; font-weight: 600; text-align: right;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
}

/* Recortar: la foto entera bajo un velo y, encima, el pedazo que se ve. El
   recuadro guarda la proporción de la caja, así que nada sale deformado. */
.cv-crop {
  position: absolute; z-index: 28;
  background-size: contain; background-repeat: no-repeat; background-position: center;
  background-color: var(--color-surface-alt);
}
.cv-crop__frame {
  position: absolute; box-sizing: border-box;
  border: 2px solid var(--color-accent);
  box-shadow: 0 0 0 9999px rgba(24, 24, 27, .45);
  cursor: move;
}

/* El recuadro con el que se encierran varios elementos de una vez. */
.cv-marquee {
  position: absolute; z-index: 25; pointer-events: none;
  border: 1px dashed var(--color-accent);
  background: var(--color-accent-soft); opacity: .45;
}
/* El tirador de giro, encima de la caja y unido a ella por una rayita, como
   en un editor de diapositivas. Dentro, la flecha que cierra un círculo: un
   punto blanco y solo no dice qué hace. */
.cv-turn {
  position: absolute; left: calc(50% - 9px); top: -32px;
  width: 18px; height: 18px; border-radius: 50%; cursor: grab;
  display: flex; align-items: center; justify-content: center;
  background: #FFFFFF; border: 2px solid var(--color-accent); z-index: 21;
  color: var(--color-accent);
}
.cv-turn svg { display: block; }
.cv-turn::before {
  content: ""; position: absolute; left: 50%; top: 100%;
  width: 2px; height: 12px; background: var(--color-accent);
}
.cv-guide { position: absolute; background: #E0368C; z-index: 30; pointer-events: none; }
.cv-guide--x { top: 0; bottom: 0; width: 1px; }
.cv-guide--y { left: 0; right: 0; height: 1px; }
.cv-grip {
  width: 600px; height: 12px; border-radius: 0 0 8px 8px; cursor: ns-resize;
  background: var(--color-surface-alt); border: 1px solid var(--color-border); border-top: 0;
  box-sizing: border-box;
}
.cv-grip:hover { background: var(--color-accent-soft); }

/* El peso del correo y la revisión antispam, encima del lienzo. Su propia
   clase: `.check` es la de las casillas del panel, y compartirla les ponía
   borde y fondo de recuadro a todas. */
.review {
  display: grid; gap: 10px; margin-top: 14px; padding: 12px 14px;
  border: 1px solid var(--color-border); border-radius: 12px;
  background: var(--color-surface);
}
.meter { display: grid; gap: 6px; }
.meter__label { margin: 0; font-size: .85rem; color: var(--color-ink-soft); }
.meter__label b { color: var(--color-ink); font-variant-numeric: tabular-nums; }
.meter__bar { height: 8px; border-radius: 99px; background: var(--color-surface-alt);
              border: 1px solid var(--color-border); overflow: hidden; }
.meter__bar span { display: block; height: 100%; width: 0; background: var(--color-accent);
                   transition: width .3s ease; }
.meter__bar span.is-high { background: #D97706; }
.meter__bar span.is-full { background: #D92D20; }
/* La de la cuota es un SVG: sin guion que le ponga el ancho. */
.meter--quota { max-width: 560px; }
.meter__svg { display: block; width: 100%; height: 100%; }
.meter__used { fill: var(--color-accent); }
.meter__svg.is-high .meter__used { fill: #D97706; }
.meter__svg.is-full .meter__used { fill: #D92D20; }
.review__ok { margin: 0; font-size: .9rem; font-weight: 600; color: #15803D; }
.review__title { margin: 0 0 4px; font-size: .9rem; font-weight: 700; color: #B42318; }
.review__bad ul { margin: 0; padding-left: 18px; display: grid; gap: 4px; font-size: .88rem; }
.review__rules { justify-self: start; margin-top: 0; }
/* Las imágenes de un HTML cargado: las que no son de la cuenta, en ámbar. */
.pictures { margin-top: 14px; padding: 12px 14px; border: 1px solid var(--color-border);
            border-radius: 12px; background: var(--color-surface); }
.pictures .field-label { margin-top: 0; }
.pictures__warn { margin: 4px 0 8px; font-size: .88rem; font-weight: 600; color: #B45309; }
.pictures__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.pictures__one { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
                 font-size: .85rem; }
.pictures__one .btn { margin-top: 0; }
.pictures__src { flex: 1 1 100%; overflow-wrap: anywhere; color: var(--color-ink-soft); }
.pictures__one.is-ok .pictures__state { color: #15803D; }
.pictures__one:not(.is-ok) .pictures__state { color: #B45309; font-weight: 600; }
/* La ventana de requisitos: cada regla con su marca, en los mismos colores que
   la revisión de encima del lienzo. */
.rules__count { margin: 12px 0 0; font-weight: 700; }
.rules__title { margin: 18px 0 6px; font-size: .95rem; }
.rules { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font-size: .9rem; }
.rules__one { display: grid; grid-template-columns: 18px 1fr; gap: 6px; align-items: start; }
.rules__mark { font-weight: 700; text-align: center; }
.rules__one.is-ok .rules__mark { color: #15803D; }
.rules__one.is-bad .rules__mark { color: #D92D20; }
.rules__one.is-bad { font-weight: 600; }

/* La vista previa: el correo a su tamaño de 600, achicado para caber. */
.editor__side { position: sticky; top: 18px; }
.editor__frame {
  width: 450px; max-width: 100%; height: 720px; overflow: hidden; margin-top: 12px;
  border: 1px solid var(--color-border); border-radius: 12px; background: #FFFFFF;
}
.editor__frame iframe {
  width: 600px; height: 960px; border: 0; transform: scale(.75); transform-origin: 0 0;
}
/* El teléfono: un correo de 600 achicado a 375, que es lo que hace Gmail en
   la pantalla de un teléfono. Sirve para ver si la letra queda muy chica. */
.editor__frame.is-phone { width: 375px; }
.editor__frame.is-phone iframe { height: 1152px; transform: scale(.625); }
.compose__preview.is-phone { width: 375px; margin-inline: auto; }

.preview-tools { display: flex; flex-wrap: wrap; align-items: end; gap: 10px 14px;
                 margin-top: 10px; }
.preview-tools__who { display: grid; gap: 2px; margin: 0; font-size: .75rem;
                      font-weight: 600; color: var(--color-ink-soft); }
.preview-tools__who select { margin: 0; padding: 6px 8px; max-width: 280px; }
.preview-tools__view { display: inline-flex; border: 1px solid var(--color-border);
                       border-radius: 10px; overflow: hidden; }
.chip { padding: 7px 12px; border: 0; background: var(--color-surface);
        color: var(--color-ink-soft); font: inherit; font-size: .85rem; cursor: pointer; }
.chip + .chip { border-left: 1px solid var(--color-border); }
.chip.is-on { background: var(--color-accent-soft); color: var(--color-accent-strong);
              font-weight: 700; }

/* De antes: las prediseñadas en tarjetas. Ya no se ofrecen, pero las clases
   siguen por si vuelven a hacer falta en el editor. */

/* Una tarjeta por plantilla: se eligen mirándolas, no leyendo una lista. */
.picks { display: grid; gap: 14px; margin-top: 14px;
         grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.picks__one {
  padding: 18px; border-radius: 12px; background: var(--color-surface);
  border: 1px solid var(--color-border);
}
/* .table__quiet no envuelve porque en una tabla no debe; aquí sí. */
.picks__one p { margin: 6px 0 0; white-space: normal; }
.picks__one .btn { margin-top: 14px; }

/* El formulario a la izquierda y cómo va quedando a la derecha. Estrecha la
   pantalla, se apilan y la vista previa cae debajo. */
.compose {
  display: grid; gap: 28px; margin-top: 18px; align-items: start;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
.compose__side { position: sticky; top: 24px; }
.compose__preview {
  display: block; width: 100%; height: 620px; margin-top: 12px;
  border: 1px solid var(--color-border); border-radius: 12px;
  background: #FFFFFF;
}
.compose__thumb {
  display: block; margin-top: 12px; width: 100%; max-width: 320px;
  height: auto; border-radius: 10px; border: 1px solid var(--color-border);
}
.compose__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.compose__actions .btn { margin-top: 18px; }

@media (max-width: 900px) {
  .compose { grid-template-columns: 1fr; }
  .compose__side { position: static; }
}


/* ------------------------------------------------------- cuentas abiertas
   Las que este navegador tiene abiertas a la vez, para saltar entre ellas. */
.switcher { margin: 18px 0 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.switcher__item {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  padding: 12px 14px; border-radius: 12px;
  border: 1px solid var(--color-border); background: var(--color-surface);
}
/* La que se está usando ahora mismo, marcada para no tener que leerlas. */
.switcher__item.is-on {
  border-color: var(--color-accent); background: var(--color-accent-soft);
}
.switcher__icon { display: inline-flex; color: var(--color-ink-soft); }
.switcher__who { display: grid; gap: 2px; margin-right: auto; min-width: 0; }
.switcher__who b { overflow-wrap: anywhere; }
.switcher__mail {
  font-size: .85rem; color: var(--color-ink-soft); overflow-wrap: anywhere;
}
/* Los botones de una fila van juntos: si no caben al lado del nombre bajan
   como un bloque, no uno a cada lado de la tarjeta. */
.switcher__do {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin-left: auto;
}
.switcher form { margin: 0; }
.switcher .btn { margin-top: 0; }
.switcher__add { margin: 18px 0 0; }
.switcher__add .btn { margin-top: 0; }

/* Las columnas propias del contacto. La marca se enseña tal cual se escribe
   dentro de una pieza, en monoespaciada, porque es algo que se copia. */
.mark {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .88rem; padding: 2px 6px; border-radius: 6px;
  background: var(--color-surface-alt); overflow-wrap: anywhere;
}

/* Elegir qué columna del archivo va a cuál, al importar. Una fila por columna
   del archivo: su título a la izquierda y a dónde va, a la derecha. */
.mapcols { margin: 20px 0; }
.mapcols__row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-bottom: 8px;
}
.mapcols__name { flex: 1 1 150px; min-width: 0; font-weight: 600; overflow-wrap: anywhere; }
.mapcols__row select { flex: 1 1 150px; width: auto; margin: 0; }
.mapcols [data-map-room].is-full { color: var(--color-accent); font-weight: 600; }

/* Las marcas de las columnas, dentro del editor de una pieza. */
.marks { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 10px; }
button.mark { border: 1px solid var(--color-border); cursor: pointer; color: inherit; }
button.mark:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* Rojo: para lo que no tiene vuelta atrás, como borrar. Solo en la pantalla
   que ya preguntó, no en la lista. */
.btn--danger { background: #D92D20; color: #FFFFFF; border-color: #D92D20; }
.btn--danger:hover { background: #B42318; border-color: #B42318; }

/* Un botón apagado: el plan no da para más. No es un enlace, así que no lleva
   a ningún sitio; y sin hover ni transición, para que la mano no espere nada.
   Lo que dice por qué va al lado, no escondido en un title. */
.btn--off {
  background: var(--color-surface-alt); color: var(--color-ink-soft);
  border-color: var(--color-border); cursor: not-allowed;
  transform: none; box-shadow: none; transition: none;
}
.btn--off:hover, .btn--off:focus {
  background: var(--color-surface-alt); color: var(--color-ink-soft);
  border-color: var(--color-border); transform: none; box-shadow: none;
}
