/* =============================================================================
   Iluena — design system.
   One coherent identity: warm-neutral paper grounds + a jewel-teal accent,
   a serif display voice for headlines, a clean sans for the tool.
   Adaptive, automatic light/dark, tasteful motion. Hand-written, no CDN.
   Per-tenant public themes plug in later by overriding the accent/hero tokens.
   ============================================================================= */

:root {
  /* — type — */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;
  --font-display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
    "Times New Roman", serif;
  --font-mono: "SF Mono", ui-monospace, "Cascadia Mono", "Segoe UI Mono",
    Consolas, monospace;

  /* — warm-neutral grounds (biased slightly warm, chosen not defaulted) — */
  --bg: #f4f2ec;
  --bg-elevated: #ffffff;
  --surface: #ffffff;
  --surface-2: #efece3;
  --text: #1b1a16;
  --text-secondary: #5e5c54;
  /* Quietest step of the text scale. Chosen to clear AA (4.5:1) on the paper
     ground, so it can carry small labels and not only decorative marks. */
  --text-tertiary: #6f6c62;

  /* — jewel-teal accent (the Iluena signature) — */
  --accent: #0e857a;          /* fills, buttons */
  --accent-hover: #0b6f66;
  --accent-strong: #0a5f57;   /* text/links on paper (AA on white) */
  --accent-contrast: #ffffff;
  --accent-soft: color-mix(in srgb, var(--accent) 12%, var(--surface));

  /* — the mark's own three colours —
     Fixed values, not derived from the accent: a business can repaint its
     booking page, and Iluena's logo is not its to repaint. The left circle is
     the business, the right one is what runs on its own, and the I between
     them is the paper they sit on. */
  --logo-a: #0f5951;
  --logo-b: #0e857a;
  --logo-i: #f4f2ec;

  /* — semantic (separate from the accent hue) — */
  --danger: #cf4636;
  --success: #2f8f5b;
  --warn: #c98a1f;

  --border: #e5e0d4;
  --border-strong: #d4cdbd;
  --ring: color-mix(in srgb, var(--accent) 32%, transparent);

  --shadow-sm: 0 1px 2px rgba(38, 34, 24, 0.06);
  --shadow: 0 8px 28px -12px rgba(38, 34, 24, 0.18);
  --shadow-lg: 0 28px 60px -24px rgba(38, 34, 24, 0.28);

  --radius-sm: 10px;
  --radius: 14px;
  --radius-lg: 20px;
  --radius-xl: 28px;

  --header-blur: saturate(160%) blur(18px);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --nav-bg: color-mix(in srgb, var(--bg) 82%, transparent);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1012;
    --bg-elevated: #17181b;
    --surface: #17181b;
    --surface-2: #202226;
    --text: #ecebe4;
    --text-secondary: #a7a49b;
    --text-tertiary: #918f86;   /* AA on the dark ground, same role as above */

    --accent: #23b3a4;
    --accent-hover: #35c2b3;
    --accent-strong: #4fcdbe;

    /* On near-black the deep teal turns into a smudge, so both circles come
       up a step. Their relationship —one darker, one brighter— is what the
       mark is made of, and that survives. The I stays paper. */
    --logo-a: #16786d;
    --logo-b: #23b3a4;
    --accent-contrast: #04231f;
    --accent-soft: color-mix(in srgb, var(--accent) 16%, var(--surface));

    --danger: #e2604f;
    --success: #46b377;
    --warn: #e0a63c;

    --border: rgba(255, 255, 255, 0.10);
    --border-strong: rgba(255, 255, 255, 0.18);
    --ring: color-mix(in srgb, var(--accent) 40%, transparent);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow: 0 10px 30px -14px rgba(0, 0, 0, 0.6);
    --shadow-lg: 0 30px 60px -24px rgba(0, 0, 0, 0.7);

    --nav-bg: color-mix(in srgb, var(--bg) 78%, transparent);
  }
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100dvh;
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.47;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3 {
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0;
}

h1 {
  font-size: clamp(1.75rem, 4vw, 2.6rem);
}

p {
  margin: 0;
  color: var(--text-secondary);
}

a {
  color: var(--accent-strong);
  text-decoration: none;
  transition: color 0.2s var(--ease);
}

a:hover {
  color: var(--accent-hover);
}

/* --------------------------------------------------------------- header -- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem clamp(1rem, 5vw, 2.5rem);
  background: var(--nav-bg);
  -webkit-backdrop-filter: var(--header-blur);
  backdrop-filter: var(--header-blur);
  border-bottom: 1px solid var(--border);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  color: var(--text);
}

/* The name is set in the display serif, the same one the mark's own I is
   drawn from: symbol and word have to read as one thing. */
.brand > span,
.auth-brand__logo > span,
.lp-foot__brand {
  font-family: var(--font-display);
  font-size: 1.12em;
  letter-spacing: -0.015em;
}

/* The mark. Its three parts are filled from tokens rather than from the
   accent, because the accent belongs to whoever is being served — a business
   can theme its own booking page — and this drawing is Iluena's own and must
   not change with it. */
.logo {
  display: block;
  flex: none;
  height: 26px;
  width: auto;
}

.logo__a { fill: var(--logo-a); }
.logo__b { fill: var(--logo-b); }
.logo__i { fill: var(--logo-i); }

.brand__mark { height: 24px; }

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  margin-left: auto;
}

/* Where you are, in the header. A tool with five sections has to say so. */
.navlink.is-current {
  color: var(--accent-strong);
  background: var(--accent-soft);
}

/* On a phone the sections take a full-width second row and scroll sideways if
   they have to, so they are never squeezed or wrapped onto a third line while
   the brand and Salir stay together on the first. */
@media (max-width: 760px) {
  .site-header {
    flex-wrap: wrap;
    row-gap: 0.5rem;
    padding: 0.7rem clamp(0.9rem, 4vw, 1.5rem);
  }
  .site-nav {
    order: 3;
    width: 100%;
    margin-left: 0;
    gap: 0.15rem;
    overflow-x: auto;
    scrollbar-width: none;
    /* Bleed to the header edges so a scrolled item is not clipped mid-padding. */
    margin-inline: calc(-1 * clamp(0.9rem, 4vw, 1.5rem));
    padding-inline: clamp(0.9rem, 4vw, 1.5rem);
  }
  .site-nav::-webkit-scrollbar {
    display: none;
  }
  .site-nav .navlink {
    white-space: nowrap;
    padding: 0.3rem 0.55rem;
  }
}

/* ----------------------------------------------------------------- main -- */
.page {
  max-width: 1080px;
  margin: 0 auto;
  padding: clamp(1.5rem, 5vw, 3.5rem) clamp(1rem, 5vw, 2.5rem);
}

.page--centered {
  min-height: calc(100dvh - 62px);
  display: grid;
  place-items: center;
}

/* ---------------------------------------------------------------- cards -- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: clamp(1.5rem, 4vw, 2.5rem);
}

.card--auth {
  width: min(100%, 400px);
}

.card__title {
  margin-bottom: 0.35rem;
}

.card__subtitle {
  margin-bottom: 1.75rem;
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------- forms -- */
.field {
  margin-bottom: 1.1rem;
}

.field label {
  display: block;
  margin-bottom: 0.4rem;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-secondary);
}

.input {
  width: 100%;
  padding: 0.8rem 0.95rem;
  font-size: 1rem;
  font-family: inherit;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease),
    background 0.2s var(--ease);
}

.input::placeholder {
  color: var(--text-tertiary);
}

.input:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--ring);
}

.field-error {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.85rem;
  color: var(--danger);
}

.checkbox {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.92rem;
  color: var(--text-secondary);
  margin-bottom: 1.25rem;
}

.checkbox input {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--accent);
}

/* File inputs: style the button so it matches the design (the browser default
   looks unfinished). The "no file" text stays browser-controlled. */
input[type="file"] {
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text-secondary);
  max-width: 100%;
}
input[type="file"]::file-selector-button {
  font-family: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--accent-strong);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 0.5rem 1.1rem;
  margin-right: 0.85rem;
  cursor: pointer;
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease);
}
input[type="file"]::file-selector-button:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* -------------------------------------------------------------- buttons -- */
.btn {
  --btn-bg: var(--accent);
  --btn-fg: var(--accent-contrast);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.72rem 1.4rem;
  font-size: 1rem;
  font-weight: 500;
  font-family: inherit;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: none;
  /* pill by default; per-tenant themes retune this via --btn-radius */
  border-radius: var(--btn-radius, 980px);
  letter-spacing: var(--btn-spacing, 0);
  text-transform: var(--btn-transform, none);
  cursor: pointer;
  transition: transform 0.18s var(--ease), background 0.18s var(--ease),
    box-shadow 0.18s var(--ease), opacity 0.18s var(--ease);
}

.btn:hover {
  /* Keep the button's own text colour on hover: without this, an <a class="btn">
     inherits the global a:hover colour and the white label turns blue-on-blue. */
  color: var(--btn-fg);
  background: var(--accent-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow);
}

.btn:active {
  transform: translateY(0) scale(0.98);
}

.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px var(--ring);
}

.btn--block {
  width: 100%;
}

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--accent);
  border: 1px solid var(--border-strong);
}

.btn--ghost:hover {
  background: var(--surface-2);
  box-shadow: none;
}

/* ---------------------------------------------------------------- flash -- */
.flashes {
  list-style: none;
  margin: 0 0 1.25rem;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.flash {
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
}

.flash-error {
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
  background: color-mix(in srgb, var(--danger) 12%, var(--surface));
  color: var(--danger);
}

.flash-info {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, var(--surface));
}

/* ---------------------------------------------------------- dashboard -- */
.eyebrow {
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 0.5rem;
}

.lede {
  font-size: 1.15rem;
  margin-top: 0.75rem;
  max-width: 46ch;
}

.grid {
  display: grid;
  gap: 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  margin-top: 2rem;
}

.stat {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.4rem 1.35rem 1.25rem;
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.stat::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--accent), #0a4f48);
  opacity: 0.9;
}

.stat:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
}

.stat__value {
  font-size: 2.15rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.stat__label {
  color: var(--text-secondary);
  font-size: 0.9rem;
  margin-top: 0.25rem;
}

/* -------------------------------------------------------------- motion -- */
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.animate-in {
  animation: rise 0.6s var(--ease) both;
}

.animate-in.delay-1 { animation-delay: 0.06s; }
.animate-in.delay-2 { animation-delay: 0.12s; }
.animate-in.delay-3 { animation-delay: 0.18s; }
.animate-in.delay-4 { animation-delay: 0.24s; }

/* ---------------------------------------------------------------- nav -- */
.navlink {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--text-secondary);
  padding: 0.4rem 0.6rem;
  border-radius: 8px;
  transition: color 0.2s var(--ease), background 0.2s var(--ease);
}

.navlink:hover {
  color: var(--text);
  background: var(--surface-2);
}

.btn--sm {
  padding: 0.42rem 0.85rem;
  font-size: 0.85rem;
}

.btn--danger {
  --btn-fg: var(--danger);
}

.btn--danger:hover {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  box-shadow: none;
}

/* --text-tertiary is a 3.2:1 gray on the paper ground: fine for a decorative
   mark, under AA for the body copy this class actually carries. */
.muted {
  color: var(--text-secondary);
}

/* ------------------------------------------------------------- agenda -- */
.agenda-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.75rem;
}

.agenda-nav {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.agenda-date {
  font-size: 1.2rem;
  font-weight: 600;
  margin-left: 0.5rem;
  text-transform: capitalize;
}

/* auto-fit, not auto-fill: with three professionals on a wide screen the
   columns share the whole row instead of huddling at 280px and leaving a third
   of the page empty. */
.agenda-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}

.staff-col {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1rem 1.25rem;
  box-shadow: var(--shadow-sm);
}

.staff-col__head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding-bottom: 0.75rem;
  margin-bottom: 0.75rem;
  border-bottom: 1px solid var(--border);
}

.staff-col__head h2 {
  font-size: 1.05rem;
  flex: 1;
}

.staff-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex: none;
}

.appt {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.25rem 0.85rem;
  padding: 0.75rem 0 0.75rem 0.85rem;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid var(--appt-accent, transparent);
}

.appt:last-child {
  border-bottom: none;
}

/* per-state accent (reuses the badge palette) */
.appt--pendiente  { --appt-accent: var(--text-tertiary); }
.appt--confirmada { --appt-accent: var(--accent); }
.appt--completada { --appt-accent: var(--success); }
.appt--no_show    { --appt-accent: var(--danger); }
.appt--cancelada  { --appt-accent: var(--danger); }

.appt__time {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.3;
}

.appt__time span {
  display: block;
  font-weight: 400;
  color: var(--text-secondary);
  font-size: 0.82rem;
}

.appt__title {
  font-weight: 500;
}

.appt__meta {
  color: var(--text-secondary);
  font-size: 0.9rem;
  margin: 0.15rem 0 0.4rem;
}

/* The actions disclosure. The trigger sits top-right of the appointment so the
   row keeps its height whether it is open or closed. */
.appt {
  position: relative;
}

.appt__more {
  grid-column: 1 / -1;
}

.appt__summary {
  position: absolute;
  top: 0.5rem;
  right: 0.35rem;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  cursor: pointer;
  color: var(--text-secondary);
  line-height: 1;
  list-style: none;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}

.appt__summary::-webkit-details-marker {
  display: none;
}

.appt__summary:hover,
.appt__more[open] .appt__summary {
  background: var(--surface-2);
  color: var(--text);
}

.appt__summary:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

/* Keep the name clear of the trigger. */
.appt__body {
  padding-right: 1.9rem;
}

.appt__actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.5rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.appt__actions form,
.appt__actions-row {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

/* toolbar actions + segmented view switch */
.agenda-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.iconbtn {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  font-size: 1.15rem;
  line-height: 1;
  color: var(--text-secondary);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  transition: background 0.18s var(--ease), color 0.18s var(--ease),
    transform 0.18s var(--ease);
}

.iconbtn:hover {
  background: var(--surface-2);
  color: var(--text);
}

.iconbtn:active {
  transform: scale(0.94);
}

.iconbtn--sm {
  width: 26px;
  height: 26px;
  font-size: 1rem;
  border-color: var(--border);
  color: var(--accent);
}

.segmented {
  display: inline-flex;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 980px;
}

.seg {
  padding: 0.4rem 0.95rem;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-secondary);
  border-radius: 980px;
  transition: background 0.18s var(--ease), color 0.18s var(--ease);
}

.seg:hover {
  color: var(--text);
}

.seg.is-active {
  color: var(--text);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

@media (prefers-color-scheme: dark) {
  .seg.is-active {
    background: var(--bg-elevated);
  }
}

/* capacity banner (aforo mode) */
.capacity-banner {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1rem;
  margin-bottom: 1.5rem;
  font-size: 0.92rem;
  color: var(--text-secondary);
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: var(--radius);
}

.capacity-banner strong {
  margin-left: auto;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.capacity-banner__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

/* professional picker (week view) */
.staffpick {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.5rem;
  /* Lift above the week grid: the grid cells use .animate-in, whose retained
     transform creates stacking contexts that would otherwise cover the open
     dropdown. */
  position: relative;
  z-index: 20;
}

.staffpick label {
  color: var(--text-secondary);
  font-size: 0.9rem;
  font-weight: 500;
}

.staffpick .cs,
.staffpick select {
  width: auto;
  min-width: 220px;
  flex: 0 0 auto;
}

/* full-width day panel (aforo list) */
.agenda-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.25rem 1.15rem 0.75rem;
  box-shadow: var(--shadow-sm);
}

/* empty states */
.empty {
  color: var(--text-tertiary);
  padding: 2.5rem 0;
  text-align: center;
}

.empty--sm {
  padding: 0.75rem 0;
}

.agenda-hint {
  margin-top: 1rem;
  font-size: 0.85rem;
}

/* weekly grid */
.agenda-week {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

@media (max-width: 900px) {
  .agenda-week {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.week-col {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.6rem;
  min-height: 90px;
  min-width: 0;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}

.week-col__head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-bottom: 0.5rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}

.week-col__label {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

.week-col__day {
  font-weight: 600;
  text-transform: capitalize;
  font-size: 0.9rem;
}

.week-col__num {
  color: var(--text-tertiary);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.week-col__empty {
  text-align: center;
  color: var(--text-tertiary);
}

.week-appt {
  display: block;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
  padding: 0.4rem 0.5rem;
  margin-bottom: 0.4rem;
  cursor: grab;
  transition: transform 0.12s ease, box-shadow 0.12s ease, opacity 0.12s ease;
}

.week-appt:last-child {
  margin-bottom: 0;
}

.week-appt__link {
  display: grid;
  gap: 0.1rem;
  color: inherit;
  text-decoration: none;
}

.week-appt__time {
  font-weight: 600;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

.week-appt__name {
  font-size: 0.85rem;
}

.week-appt__svc {
  font-size: 0.78rem;
  color: var(--text-secondary);
}

/* drag-and-drop feedback */
.appt[draggable] {
  cursor: grab;
}

.is-dragging {
  opacity: 0.5;
}

.is-dropzone {
  background: color-mix(in srgb, var(--accent) 8%, var(--surface));
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
}

.is-saving {
  opacity: 0.4;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .week-col,
  .week-appt {
    transition: none;
  }
}

/* status badges */
.badge {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: 980px;
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: capitalize;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-secondary);
}

.badge--confirmada {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.badge--completada {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 16%, var(--surface));
  border-color: color-mix(in srgb, var(--success) 35%, transparent);
}

.badge--no_show {
  color: var(--danger);
  background: color-mix(in srgb, var(--danger) 14%, var(--surface));
  border-color: color-mix(in srgb, var(--danger) 35%, transparent);
}

/* narrow form pages */
.page-narrow {
  max-width: 520px;
}

.field-row {
  display: flex;
  gap: 1rem;
}

.field-row .field {
  flex: 1;
}

.form-actions {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  margin-top: 1.5rem;
}

/* ------------------------------------------------- public booking -- */
.booking {
  max-width: 620px;
}

.steps {
  font-size: 0.85rem;
  color: var(--text-tertiary);
  margin-bottom: 0.9rem;
}

.steps strong {
  color: var(--text);
  font-weight: 600;
}

.pick-list {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
}

/* A menu of destinations (settings, campaigns) is not a sequence to read down:
   on a wide screen it lays out in columns instead of one very long ribbon. */
.pick-list--grid {
  grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
}

.pick {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  color: var(--text);
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease),
    border-color 0.18s var(--ease);
}

.pick:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow);
  border-color: var(--border-strong);
  color: var(--text);
}

.pick__main {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-width: 0;
}

.pick__title {
  font-weight: 600;
}

.pick__meta {
  display: block;
  color: var(--text-secondary);
  font-size: 0.9rem;
  margin-top: 0.15rem;
}

.pick__dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex: none;
}

.pick__chevron {
  color: var(--text-tertiary);
  font-size: 1.4rem;
  line-height: 1;
  flex: none;
}

.day-nav {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 2rem;
}

.day-nav__label {
  font-weight: 600;
  text-transform: capitalize;
}

.slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 0.6rem;
  margin-top: 1.25rem;
}

.slot {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.7rem 0.5rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  transition: transform 0.15s var(--ease), background 0.15s var(--ease),
    color 0.15s var(--ease);
}

.slot:hover {
  background: var(--accent);
  color: var(--accent-contrast);
  transform: translateY(-1px);
}

.summary {
  margin: 1.75rem 0;
  padding: 1.1rem 1.25rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: grid;
  gap: 0.6rem;
}

.summary__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.summary__row span {
  color: var(--text-secondary);
  font-size: 0.92rem;
}

.ok-mark {
  width: 68px;
  height: 68px;
  margin: 0 auto 1.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--success) 18%, var(--surface));
  color: var(--success);
  font-size: 2rem;
  font-weight: 700;
}

/* ---------------------------------------------------- customers -- */
.search {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.search .input {
  width: min(320px, 60vw);
}

.detail-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: 1.4fr 1fr;
  margin-top: 1.75rem;
}

@media (max-width: 720px) {
  .detail-grid {
    grid-template-columns: 1fr;
  }
}

.history {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.85rem;
}

.history__item {
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--border);
}

.history__item:last-child {
  padding-bottom: 0;
  border-bottom: none;
}

.history__when {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-transform: capitalize;
}

.history__what {
  color: var(--text-secondary);
  font-size: 0.92rem;
  margin: 0.15rem 0 0.4rem;
}

.codeblock {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  font-family: "SF Mono", ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text);
  overflow-x: auto;
  margin: 0 0 0.85rem;
  white-space: pre;
}

/* Esta pantalla es casi toda texto explicando una cosa que se hace una vez, y
   en `page--wide` las líneas llegaban a ciento y pico caracteres en un monitor
   grande. Se corta la medida, no el ancho de la tarjeta: las tarjetas siguen
   ocupando la pantalla como en el resto del panel, y lo que se acota es hasta
   dónde corre una línea antes de volver. */
.seguridad .card__subtitle,
.seguridad .settings-note,
.seguridad .field-hint { max-width: 68ch; }
/* Y el campo del código, que son seis dígitos: a ancho completo parecía pedir
   una frase. La contraseña de desactivar va con la misma medida por simetría. */
.seguridad .field .input { max-width: 22rem; }

/* El alta del segundo factor. En pantalla ancha, el QR a un lado y los pasos
   al otro: en una sola columna el QR deja mil píxeles vacíos a su derecha y los
   párrafos se estiran a ciento y pico caracteres por línea. El `minmax(0, 62ch)`
   es lo que corta eso — la segunda columna no crece más allá de una medida que
   se lee—, y el `align-items: start` evita que la columna del QR se estire a lo
   alto de la otra. Debajo de 900 px se apila, con el QR arriba, que es el orden
   en que se hace: primero escanear, y leer solo si no se puede. */
.alta2fa__qr { margin-bottom: 1rem; }
@media (min-width: 900px) {
  .alta2fa {
    display: grid;
    grid-template-columns: auto minmax(0, 62ch);
    gap: 2.5rem;
    align-items: start;
    /* Las dos juntas a la izquierda. Sin esto el grid las manda a los extremos
       de la tarjeta y deja medio monitor de hueco entre el QR y sus pasos, que
       es lo mismo que se venía a arreglar pero en horizontal. */
    justify-content: start;
  }
  .alta2fa__qr { margin-bottom: 0; }
}

/* Un `.codeblock` cuyo contenido puede partirse por donde sea. `.codeblock` es
   un `<code>` —en línea— con `white-space: pre`, así que no encoge: se sale de
   la pantalla en vez de hacer scroll, y a 360 px se salía 38 px. Aquí dentro va
   una clave de 32 caracteres en grupos de cuatro, que no es código y se puede
   partir sin perder nada. Modificador y no arreglo de la regla base: lo otro
   toca todas las pantallas que ya la usan bien. */
.codeblock--envuelve {
  display: block;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* El QR del alta del segundo factor. Blanco fijo y no `--surface`: el dibujo
   es negro sobre blanco a propósito —lo que tiene que hacer es leerse a la
   primera con una cámara— y sobre el fondo oscuro del tema en modo noche no
   habría contraste. El recuadro blanco es parte de que el QR funcione, no
   decoración. `width: fit-content` para que no se estire al ancho de la
   tarjeta: un QR estirado con el margen a los lados se escanea peor. */
.qr-alta {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.75rem;
  width: fit-content;
  margin: 0.75rem 0;
  line-height: 0;
}
.qr-alta svg {
  display: block;
  width: 160px;
  height: 160px;
}

/* ------------------------------------------------- schedule grid -- */
.field-hint {
  /* Always its own line: hints follow inputs that are sometimes narrower than
     the field, and an inline hint would wrap around them mid-sentence. */
  display: block;
  margin: 0.5rem 0;
  font-size: 0.9rem;
  color: var(--text-secondary);
}

.week {
  display: grid;
  gap: 0.5rem;
}

.week-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  transition: opacity 0.2s var(--ease);
}

.week-day {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 108px;
  font-weight: 500;
  cursor: pointer;
}

.week-day input {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--accent);
}

.week-blocks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  flex: 1;
}

.block {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.block__sep {
  color: var(--text-tertiary);
}

.input--time {
  width: auto;
  padding: 0.45rem 0.55rem;
  font-variant-numeric: tabular-nums;
}

.week-row--off {
  opacity: 0.5;
}

.grid-editor__tools {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1rem;
}

/* --------------------------------------------------- selects (native) -- */
select.input {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.4rem;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23888' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.95rem center;
}

/* ------------------------------------------- styled dropdown (cs) -- */
.cs {
  position: relative;
  width: 100%;
}

.cs__native {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.cs__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  text-align: left;
  padding: 0.8rem 0.95rem;
  font: inherit;
  font-size: 1rem;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease),
    background 0.2s var(--ease);
}

.cs__trigger::after {
  content: "";
  flex: none;
  width: 12px;
  height: 8px;
  margin-left: 0.5rem;
  background: currentColor;
  opacity: 0.45;
  transition: transform 0.2s var(--ease);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5'/%3E%3C/svg%3E") no-repeat center / contain;
}

.cs.is-open .cs__trigger::after {
  transform: rotate(180deg);
}

.cs.is-open .cs__trigger,
.cs__trigger:focus-visible {
  outline: none;
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--ring);
}

.cs__menu {
  position: absolute;
  z-index: 60;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  padding: 4px;
  max-height: 264px;
  overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(-6px) scale(0.98);
  transform-origin: top;
  pointer-events: none;
  transition: opacity 0.16s var(--ease), transform 0.16s var(--ease);
}

.cs.is-open .cs__menu {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.cs__option {
  padding: 0.6rem 0.7rem;
  border-radius: 8px;
  font-size: 0.95rem;
  cursor: pointer;
  transition: background 0.12s var(--ease);
}

.cs__option:hover {
  background: var(--surface-2);
}

.cs__option[aria-selected="true"] {
  color: var(--accent);
  font-weight: 600;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

/* --------------------------------------------------- toast -- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  z-index: 200;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  max-width: min(92vw, 440px);
  padding: 0.85rem 1.1rem;
  color: var(--text);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-lg);
  font-size: 0.95rem;
  opacity: 0;
  transform: translate(-50%, 150%);
  transition: transform 0.34s var(--ease), opacity 0.34s var(--ease);
}

.toast.is-in {
  opacity: 1;
  transform: translate(-50%, 0);
}

.toast__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  font-size: 0.8rem;
  font-weight: 700;
  color: #fff;
}

.toast--error {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
}

.toast--error .toast__icon {
  background: var(--danger);
}

.toast--ok .toast__icon {
  background: var(--success);
}

/* ------------------------------------ unassigned appointments -- */
.unassigned {
  margin-bottom: 1.25rem;
  padding: 1rem 1.15rem;
  background: var(--surface);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
}

.unassigned--warn {
  border-style: solid;
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
  background: color-mix(in srgb, var(--danger) 6%, var(--surface));
}

.unassigned__head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
}

.unassigned__hint {
  margin: 0.25rem 0 0.85rem;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.unassigned__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.appt--chip {
  width: min(300px, 100%);
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--appt-accent, var(--border));
  border-radius: 12px;
  background: var(--surface-2);
  box-shadow: var(--shadow-sm);
  cursor: grab;
}

.appt__date {
  font-size: 0.82rem;
  color: var(--text-secondary);
  margin-top: 0.15rem;
  font-variant-numeric: tabular-nums;
}

.pill {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding: 0 0.4rem;
  border-radius: 980px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--text-secondary);
}

.unassigned--warn .pill {
  background: var(--danger);
  border-color: transparent;
  color: #fff;
}

/* ----------------------------------------------- daily panel -- */
.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

/* ---------------------------------------------- CRM: segments + suggestions -- */
/* Reactivation suggestion cards (the actionable segments up front). */
.suggest-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.suggest {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--border-strong);
  border-left-width: 4px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: inherit;
  transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease);
}

.suggest:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm, 0 4px 14px rgba(0, 0, 0, 0.08));
}

.suggest--dormido { border-left-color: #ff375f; }
.suggest--riesgo { border-left-color: #ff9f0a; }

.suggest__n {
  font-size: 1.6rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.suggest__txt { font-size: 0.9rem; color: var(--muted); }
.suggest__txt strong { color: var(--text); }

/* Segment filter chips. */
.segbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1rem;
}

.segchip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  font-size: 0.82rem;
  color: var(--muted);
  background: var(--surface);
}

.segchip.is-active {
  background: var(--accent);
  color: var(--accent-contrast);
  border-color: var(--accent);
}

.segchip__n { opacity: 0.7; font-variant-numeric: tabular-nums; }

/* Inline segment badge on each customer row. */
.seg {
  display: inline-block;
  padding: 0.05rem 0.45rem;
  margin-left: 0.35rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 600;
  vertical-align: middle;
  background: color-mix(in srgb, var(--muted) 18%, transparent);
  color: var(--muted);
}

.seg--dormido { background: color-mix(in srgb, #ff375f 18%, transparent); color: #d70036; }
.seg--en_riesgo { background: color-mix(in srgb, #ff9f0a 22%, transparent); color: #a35c00; }
.seg--habitual { background: color-mix(in srgb, #34c759 20%, transparent); color: #1a7a35; }
.seg--nuevo { background: color-mix(in srgb, #0071e3 16%, transparent); color: #0060c0; }
.seg--vip { background: color-mix(in srgb, #6a5acd 20%, transparent); color: #5646b8; }

@media (prefers-color-scheme: dark) {
  .seg--dormido { color: #ff6b8f; }
  .seg--en_riesgo { color: #ffb84d; }
  .seg--habitual { color: #5fd97e; }
  .seg--nuevo { color: #5aa8ff; }
  .seg--vip { color: #a99bf0; }
}

/* Customer file: at-a-glance CRM figures under the header. */
.crm-figs {
  display: flex;
  flex-wrap: wrap;
  gap: 1.75rem;
  margin-top: 1rem;
}

.crm-fig { display: flex; flex-direction: column; }
.crm-fig__n { font-size: 1.2rem; font-weight: 700; }
.crm-fig__l { font-size: 0.78rem; color: var(--muted); }

/* Marketing-offer flag on an agenda appointment: tells the owner what to apply. */
.appt__offer {
  display: inline-block;
  margin: 0.2rem 0;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  font-size: 0.74rem;
  font-weight: 600;
  background: color-mix(in srgb, #6a5acd 16%, transparent);
  color: #5646b8;
}

@media (prefers-color-scheme: dark) {
  .appt__offer { color: #a99bf0; }
}

/* ------------------------------------------- recovered-value counter -- */
/* The money card: the metric that justifies the price. Made a visual hero. */
.recovered {
  background:
    radial-gradient(130% 150% at 92% -10%,
      color-mix(in srgb, var(--success) 16%, transparent), transparent 55%),
    var(--surface);
  border-color: color-mix(in srgb, var(--success) 32%, var(--border));
}

.recovered__hero {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: 0.5rem 0 1.1rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}

.recovered__total {
  font-size: clamp(2.8rem, 7vw, 4rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--success);
  font-variant-numeric: tabular-nums;
}

.recovered__caption {
  color: var(--text-secondary);
  font-size: 0.98rem;
}

/* ----------------------------------------------- loyalty stamps -- */
.stamps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--border-strong);
}

.stamp--on {
  color: #ffb400;
}

/* ----------------------------------------------- star rating -- */
.stars {
  display: inline-flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
}

.stars input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.stars label {
  font-size: 2.4rem;
  line-height: 1;
  color: var(--border-strong);
  cursor: pointer;
  padding: 0 0.12rem;
  transition: color 0.12s var(--ease), transform 0.12s var(--ease);
}

.stars label:hover,
.stars label:hover ~ label,
.stars input:checked ~ label {
  color: #ffb400;
}

.stars label:hover {
  transform: scale(1.12);
}

.stars input:focus-visible + label {
  outline: 2px solid var(--ring);
  border-radius: 6px;
}

/* --------------------------------------- smooth page transitions -- */
/* Cross-document View Transitions: navigating (e.g. Día <-> Semana) cross-fades
   instead of showing a hard reload. Unsupported browsers just navigate normally. */
@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.3s;
  animation-timing-function: var(--ease);
}

/* Keep the header steady across navigations so only the content changes. */
.site-header {
  view-transition-name: site-header;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* Dashboard notices (e.g. monthly message-bag warnings). */
.notice {
  margin: 1rem 0 0;
  padding: .85rem 1.1rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-size: .95rem;
  line-height: 1.45;
}
.notice--warn {
  border-color: color-mix(in srgb, #ff9f0a 45%, transparent);
  background: color-mix(in srgb, #ff9f0a 12%, var(--surface));
  color: color-mix(in srgb, #ff9f0a 60%, var(--text));
}
.notice--alert {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  background: color-mix(in srgb, var(--danger) 12%, var(--surface));
  color: var(--danger);
}

/* ------------------------------------------------- empieza por aquí -- */
/* El alta de un negocio nuevo. Se dibuja solo mientras falta algo, así que
   puede permitirse ocupar sitio: es lo único que el dueño tiene que hacer ese
   día. Con el acento de la marca, no en rojo: no es un error, es una tarea. */
.empieza {
  margin: 1.25rem 0 0;
  padding: 1.35rem 1.5rem 1.15rem;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 5%, var(--surface));
}

.empieza__head { margin-bottom: 1.1rem; }

.empieza__title {
  margin: 0 0 0.3rem;
  font-family: var(--font-display);
  font-size: 1.3rem;
  letter-spacing: -0.01em;
}

.empieza__lede {
  margin: 0;
  max-width: 62ch;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--text-secondary);
}

.empieza__pasos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.empieza__paso {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

/* El número es el orden en que hay que hacerlo, no una decoración: si hay tres
   pasos, el primero es el primero. */
.empieza__n {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-contrast, #fff);
  font-size: 0.85rem;
  font-weight: 650;
}

.empieza__texto {
  flex: 1 1 auto;
  display: grid;
  gap: 0.1rem;
  min-width: 0;
}

.empieza__texto b { font-weight: 600; }

.empieza__texto span {
  font-size: 0.88rem;
  color: var(--text-secondary);
}

.empieza__paso .btn { flex: 0 0 auto; }

.empieza__pie {
  margin: 1.1rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
  font-size: 0.85rem;
  color: var(--text-tertiary);
}

.empieza__pie code {
  font-size: 0.85rem;
  color: var(--text);
  word-break: break-all;
}

@media (max-width: 32rem) {
  .empieza__paso { flex-wrap: wrap; }
  .empieza__paso .btn { margin-left: auto; }
}

/* =============================================================================
   Public booking wizard — immersive redesign.
   Branded gradient hero + numbered stepper + elevated step card.
   ============================================================================= */
.booking-wrap {
  max-width: 640px;
  margin: 0 auto;
}

/* ---- hero ---------------------------------------------------------------- */
.bk-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: clamp(1.9rem, 6vw, 3rem) clamp(1.5rem, 5vw, 2.5rem);
  border-radius: var(--radius-lg);
  color: #fff;
  background:
    radial-gradient(120% 140% at 85% 0%, rgba(255, 255, 255, 0.22), transparent 55%),
    linear-gradient(135deg, var(--accent), #0a4f48 92%);
  box-shadow: var(--shadow-lg);
}

.bk-hero__glow {
  position: absolute;
  z-index: -1;
  width: 60%;
  aspect-ratio: 1;
  right: -12%;
  bottom: -55%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.35), transparent 70%);
  filter: blur(8px);
  pointer-events: none;
}

.bk-hero__eyebrow {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
  margin: 0 0 0.6rem;
}

.bk-hero__title {
  font-size: clamp(1.85rem, 6vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: #fff;
}

.bk-hero__lede {
  margin-top: 0.7rem;
  font-size: 1.05rem;
  color: rgba(255, 255, 255, 0.9);
  max-width: 40ch;
}

.bk-hero__trust {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  margin: 1.25rem 0 0;
  padding: 0;
}

.bk-hero__trust li {
  font-size: 0.8rem;
  font-weight: 500;
  padding: 0.32rem 0.75rem;
  border-radius: 980px;
  color: #fff;
  background: rgba(255, 255, 255, 0.16);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

.bk-hero__trust li::before {
  content: "✓ ";
  opacity: 0.85;
}

/* ---- step card ----------------------------------------------------------- */
.bk-card {
  margin-top: -1.5rem;
  position: relative;
  z-index: 1;
  margin-left: clamp(0px, 2vw, 1.25rem);
  margin-right: clamp(0px, 2vw, 1.25rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: clamp(1.4rem, 5vw, 2rem);
}

.bk-card--center {
  margin-top: 0;
  text-align: center;
}

.bk-card__title {
  font-size: 1.3rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 1.25rem;
}

.bk-empty {
  color: var(--text-secondary);
  font-size: 1rem;
  line-height: 1.5;
  padding: 1.25rem 0;
}

.bk-back {
  display: inline-block;
  margin-top: 1.5rem;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-secondary);
}

.bk-back:hover {
  color: var(--accent);
}

/* Era una línea centrada («al reservar aceptas…») y ahora es la información
   del artículo 13: cuatro frases. Centrada no se lee, así que se alinea a la
   izquierda y se separa con una regla, como la letra pequeña que es. */
.bk-fineprint {
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--text-tertiary);
  text-align: left;
}

.bk-fineprint b { font-weight: 600; color: var(--text-secondary); }

.bk-fineprint a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* ---- stepper ------------------------------------------------------------- */
.stepper {
  display: flex;
  list-style: none;
  margin: 0 0 1.75rem;
  padding: 0;
}

.stepper__item {
  flex: 1;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.45rem;
  text-align: center;
  min-width: 0;
}

.stepper__item::before {
  content: "";
  position: absolute;
  top: 13px;
  right: 50%;
  width: 100%;
  height: 2px;
  background: var(--border-strong);
  transition: background 0.3s var(--ease);
}

.stepper__item:first-child::before {
  display: none;
}

.stepper__item.is-active::before,
.stepper__item.is-done::before {
  background: var(--accent);
}

.stepper__dot {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  font-size: 0.82rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
  background: var(--surface);
  border: 2px solid var(--border-strong);
  transition: all 0.25s var(--ease);
}

.stepper__item.is-done .stepper__dot {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}

.stepper__item.is-active .stepper__dot {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--ring);
}

.stepper__label {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.stepper__item.is-active .stepper__label {
  color: var(--text);
  font-weight: 600;
}

/* ---- pick rows (service / professional) ---------------------------------- */
.pick__side {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex: none;
}

.pick__price {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.pick__avatar {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 50%;
  font-size: 1rem;
  font-weight: 600;
  color: #fff;
  background: var(--dot, var(--accent));
  box-shadow: var(--shadow-sm);
}

/* ---- day navigation ------------------------------------------------------ */
.daybtn {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 50%;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  transition: transform 0.15s var(--ease), background 0.15s var(--ease);
}

.daybtn:hover {
  background: var(--surface);
  border-color: var(--border-strong);
  transform: translateY(-1px);
  color: var(--text);
}

.daybtn.is-disabled {
  opacity: 0.35;
  pointer-events: none;
}

.day-nav {
  justify-content: space-between;
  padding: 0.4rem 0.5rem;
  background: var(--surface-2);
  border-radius: 980px;
}

.day-nav__label {
  flex: 1;
  text-align: center;
}

/* ---- slots grouped by part of day ---------------------------------------- */
.slot-group {
  margin-top: 1.5rem;
}

.slot-group__label {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin: 0 0 0.7rem;
}

.slots {
  margin-top: 0;
}

/* ---- summary total emphasis ---------------------------------------------- */
.summary__row--total {
  margin-top: 0.15rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
}

.summary__row--total strong {
  font-size: 1.2rem;
}

/* ---- large primary button ------------------------------------------------ */
.btn--lg {
  padding: 0.95rem 1.6rem;
  font-size: 1.05rem;
  font-weight: 600;
}

/* ---- animated success check ---------------------------------------------- */
.ok-mark {
  color: var(--success);
}

/* neutral variant for cancelled / not-available result screens */
.ok-mark--muted {
  color: var(--text-tertiary);
  background: var(--surface-2);
  font-size: 1.9rem;
  font-weight: 600;
  line-height: 1;
}

.ok-mark__check {
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
  animation: draw-check 0.6s var(--ease) 0.15s forwards;
}

@keyframes draw-check {
  to {
    stroke-dashoffset: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ok-mark__check {
    animation: none;
    stroke-dashoffset: 0;
  }
}

/* =============================================================================
   Auth — full-bleed split screen (brand story + login form).
   ============================================================================= */
.auth-split {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
}

/* left: branded gradient panel */
.auth-brand {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2rem;
  padding: clamp(2rem, 5vw, 3.5rem);
  color: #fff;
  background:
    radial-gradient(115% 130% at 80% 0%, rgba(255, 255, 255, 0.2), transparent 55%),
    linear-gradient(150deg, var(--accent), #0a4f48 95%);
}

.auth-brand__glow {
  position: absolute;
  z-index: -1;
  width: 65%;
  aspect-ratio: 1;
  left: -18%;
  bottom: -30%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.28), transparent 70%);
  pointer-events: none;
}

.auth-brand__logo {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
  font-size: 1.1rem;
  color: #fff;
}

/* The one place the mark sits on the deep teal panel. The darker circle IS
   that panel's colour, so down there it would simply disappear: both come up
   until they can be told apart again, keeping the one-darker-one-brighter
   relationship the mark is made of. */
.auth-brand__logo .brand__mark {
  --logo-a: #1a9184;
  --logo-b: #66cfc1;
  height: 30px;
}

.auth-brand__title {
  font-size: clamp(1.8rem, 3.2vw, 2.6rem);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.08;
  color: #fff;
  max-width: 15ch;
}

.auth-brand__lede {
  margin-top: 0.9rem;
  font-size: 1.08rem;
  color: rgba(255, 255, 255, 0.9);
  max-width: 42ch;
}

.auth-brand__list {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.85rem;
}

.auth-brand__list li {
  position: relative;
  padding-left: 2rem;
  font-size: 1.02rem;
  color: rgba(255, 255, 255, 0.95);
}

.auth-brand__list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: -1px;
  display: grid;
  place-items: center;
  width: 1.4rem;
  height: 1.4rem;
  font-size: 0.8rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
}

.auth-brand__foot {
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.7);
}

/* right: the form */
.auth-panel {
  display: grid;
  place-items: center;
  padding: clamp(1.5rem, 5vw, 3rem);
  background: var(--bg);
}

.auth-form {
  width: min(100%, 380px);
}

@media (max-width: 820px) {
  .auth-split {
    grid-template-columns: 1fr;
    /* brand band sizes to content; the form panel fills the rest — without
       this the grid stretched the teal band to half the screen. */
    grid-template-rows: auto 1fr;
  }
  .auth-brand {
    flex-direction: column;
    justify-content: space-between;
    gap: 1.4rem;
    min-height: 32vh;
    padding: clamp(1.4rem, 6vw, 2rem) clamp(1.25rem, 5vw, 2rem)
      clamp(1.6rem, 6vw, 2.2rem);
  }
  .auth-brand__title {
    font-size: clamp(1.6rem, 7vw, 2.2rem);
    max-width: 20ch;
  }
  .auth-brand__lede,
  .auth-brand__list,
  .auth-brand__foot {
    display: none;
  }
}

/* =============================================================================
   THEME PICKER (Ajustes › Diseño) — mini previews of each public skin
   ============================================================================= */
.themegrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1.1rem;
  margin: 1.5rem 0 2rem;
}
.themecard {
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.themecard input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.themecard__prev {
  position: relative;
  border-radius: var(--r, 16px);
  overflow: hidden;
  border: 2px solid var(--border);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease),
    transform 0.2s var(--ease);
}
.themecard:hover .themecard__prev { transform: translateY(-2px); }
.themecard input:checked + .themecard__prev {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--ring);
}
.themecard__hero {
  display: flex;
  align-items: flex-end;
  height: 78px;
  padding: 0.55rem 0.7rem;
  font-family: var(--font-display);
  font-size: 1.55rem;
  line-height: 1;
  color: #f3efe6;
  background: linear-gradient(158deg, var(--h1), var(--h2));
}
.themecard__hero--serif { font-family: var(--font-display); }
.themecard__hero--sans { font-family: var(--font-sans); font-weight: 800; }
.themecard__hero--mono { font-family: var(--font-mono); font-weight: 600; }
.themecard__hero.is-upper { text-transform: uppercase; letter-spacing: -0.01em; }
.themecard__body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.6rem 0.7rem;
  background: var(--surface);
}
.themecard__line {
  height: 8px;
  width: 46%;
  border-radius: 999px;
  background: var(--border-strong);
}
.themecard__pill {
  font-size: 0.72rem;
  font-weight: 700;
  color: #fff;
  background: var(--ac);
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
}
.themecard__check {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  font-size: 0.8rem;
  color: #fff;
  background: var(--ac);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.2s var(--ease), transform 0.2s var(--ease);
}
.themecard input:checked + .themecard__prev .themecard__check {
  opacity: 1;
  transform: scale(1);
}
.themecard__name { font-weight: 600; }
.themecard__desc { font-size: 0.82rem; color: var(--text-tertiary); }

/* =============================================================================
   BILLING (Ajustes › Suscripción)
   ============================================================================= */
.badge--ok {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 15%, transparent);
}

/* usage bar (message bag) */
.bar {
  height: 10px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
}
.bar__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.4s var(--ease);
}
.bar__fill--warn { background: var(--warn); }
.bar__fill--alert { background: var(--danger); }

/* feature checklist on the plan card */
.checklist {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}
.checklist li {
  position: relative;
  padding-left: 1.7rem;
  color: var(--text-secondary);
}
.checklist li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0.05em;
  display: grid;
  place-items: center;
  width: 1.2rem;
  height: 1.2rem;
  font-size: 0.72rem;
  font-weight: 700;
  border-radius: 50%;
  color: var(--accent);
  background: var(--accent-soft);
}

/* — data tables (results / ROI) —
   Numbers first: figures are tabular so columns line up when scanned, and the
   table scrolls inside its own box instead of pushing the page sideways. */
.table-wrap {
  overflow-x: auto;
  margin-top: 1rem;
  -webkit-overflow-scrolling: touch;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.94rem;
}

.table th,
.table td {
  text-align: left;
  padding: 0.7rem 0.9rem 0.7rem 0;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.table th {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* Every column but the first holds a figure. */
.table td + td,
.table th + th {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.table tbody tr:last-child td {
  border-bottom: none;
}

/* Opt a text column out of the figure alignment. */
.table td.is-text,
.table th.is-text {
  text-align: left;
  white-space: normal;
  color: var(--text-secondary);
}

/* =============================================================================
   PANEL (dashboard)
   An Operate surface: the owner is mid-task, glancing between clients. The day
   bar answers "how is today going" in one strip, so the two things they act on
   (the agenda and the free gaps) start above the fold. Each panel sizes to its
   own content and scrolls inside itself, so a day of 15-minute slots can never
   drag the whole page down with it.
   ============================================================================= */
.page--wide {
  max-width: 1560px;
}

/* ---- day band -----------------------------------------------------------
   The signature surface of the owner tool: the same jewel teal as the public
   booking hero, compressed into a band that carries the day's figures instead
   of a hero plus a separate row of tiles. One strong moment, then the work. */
.daybar {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem 2.5rem;
  padding: clamp(1.25rem, 2.4vw, 1.7rem) clamp(1.4rem, 2.6vw, 2.1rem);
  border-radius: var(--radius-xl);
  color: var(--hero-ink);
  background: var(--hero-bg);
  box-shadow: 0 22px 48px -26px rgba(9, 46, 42, 0.62);
}

/* The light that makes the band feel like a surface rather than a fill. */
.daybar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(120% 140% at 88% -30%, rgba(255, 255, 255, 0.16), transparent 58%),
    radial-gradient(80% 120% at 8% 120%, color-mix(in srgb, var(--accent) 30%, transparent), transparent 62%);
}

.daybar__name {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.6vw, 2.3rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.02;
  margin: 0;
  color: var(--hero-ink);
}

.daybar__date {
  margin: 0 0 0.3rem;
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--hero-dim-strong);
}

/* The way into the digest. Quiet on purpose: it sits under the name, in the
   band's own dim ink, so it is found when looked for without competing with
   the four figures that are the point of the band. */
.daybar__more {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-top: 0.6rem;
  padding: 0.28rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--hero-line);
  font-size: 0.82rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--hero-dim-strong);
  transition: background-color 0.18s ease, color 0.18s ease;
}

.daybar__more:hover,
.daybar__more:focus-visible {
  background: color-mix(in srgb, var(--hero-ink) 12%, transparent);
  color: var(--hero-ink);
}

.daybar__figs {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem 2rem;
  margin: 0;
}

.fig {
  margin: 0;
  min-width: 5.5rem;
}

.fig__label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--hero-dim-strong);
  white-space: nowrap;
}

/* The colour that the old stat tiles carried, kept as a small chip so it reads
   at a glance without spending a whole row of cards on it. */
.fig__chip {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  color: var(--chip-ink, var(--hero-mint));
  background: color-mix(in srgb, var(--chip-ink, var(--hero-mint)) 22%, transparent);
  border: 1px solid color-mix(in srgb, var(--chip-ink, var(--hero-mint)) 30%, transparent);
}

.fig__chip--citas      { --chip-ink: #7fd6c6; }
.fig__chip--huecos     { --chip-ink: #9ecfa6; }
.fig__chip--ocupacion  { --chip-ink: #cbb98a; }
.fig__chip--dinero     { --chip-ink: #f0e2b8; }

.fig__value {
  margin: 0.3rem 0 0;
  font-size: clamp(1.6rem, 2.2vw, 2rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  color: var(--hero-ink);
}

.fig__unit {
  font-size: 0.6em;
  font-weight: 500;
  color: var(--hero-dim);
  margin-left: 0.05em;
}

.fig--wide {
  min-width: 8rem;
}

.fig__bar {
  height: 4px;
  width: 100%;
  max-width: 8rem;
  margin-top: 0.55rem;
  border-radius: 999px;
  background: var(--hero-line);
  overflow: hidden;
}

.fig__barfill {
  display: block;
  height: 100%;
  min-width: 4px;
  border-radius: 999px;
  background: var(--hero-mint);
}

/* The money is the argument the product makes for itself, so it is separated
   and tinted rather than sitting in the row of measurements. */
.fig--money {
  padding-left: 2rem;
  border-left: 1px solid var(--hero-line);
  min-width: 10rem;
}

.fig--money .fig__value {
  color: var(--hero-mint);
}

/* Phones and small tablets: the band stacks, and the money keeps its own line
   instead of being squeezed against a border that no longer has room. */
@media (max-width: 760px) {
  .daybar {
    gap: 1rem 1.5rem;
  }
  .daybar__figs {
    gap: 0.9rem 1.5rem;
    width: 100%;
  }
  .fig {
    min-width: 4.5rem;
  }
  .fig--money {
    padding-left: 0;
    border-left: none;
    border-top: 1px solid var(--hero-line);
    padding-top: 0.9rem;
    flex-basis: 100%;
  }
  .fig--money .fig__label {
    white-space: normal;
  }
}

/* ---- the three panels ---------------------------------------------------- */
.dash {
  display: grid;
  /* align-items:start is what removes the old dead space: a 6-appointment card
     no longer stretches to match a 30-slot one. */
  align-items: start;
  gap: 1.1rem;
  margin-top: 1.5rem;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .dash {
    grid-template-columns: minmax(0, 1.35fr) minmax(280px, 1fr);
  }
  /* The agenda is the task, so it holds the tall left column on its own. */
  .panel--agenda {
    grid-row: span 2;
  }
}

@media (min-width: 1360px) {
  .dash {
    grid-template-columns: minmax(0, 1.5fr) minmax(300px, 1fr) minmax(300px, 1fr);
  }
  .panel--agenda {
    grid-row: auto;
  }
}

.panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 1.4rem 1.5rem 1.5rem;
}

.panel__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.9rem;
}

.panel__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.panel__link {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--accent-strong);
  text-decoration: none;
  white-space: nowrap;
}

.panel__link:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.panel__note {
  font-size: 0.85rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.panel__lede {
  margin: 0 0 0.9rem;
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--text-secondary);
}

.panel__foot {
  margin: 0.9rem 0 0;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--text-secondary);
}

.panel__empty {
  padding: 1.25rem 0 0.5rem;
  color: var(--text-secondary);
}

.panel__empty p {
  margin: 0 0 0.9rem;
}

/* ---- agenda list --------------------------------------------------------- */
.agendalist {
  list-style: none;
  margin: 0;
  padding: 0;
  /* A long day scrolls here rather than in the page. */
  max-height: min(60vh, 560px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
}

.agendalist__item {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
}

.agendalist__item:last-child {
  border-bottom: none;
}

.agendalist__time {
  display: flex;
  flex-direction: column;
  min-width: 3.4rem;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

.agendalist__from {
  font-weight: 600;
}

.agendalist__to {
  font-size: 0.78rem;
  color: var(--text-secondary);
}

.agendalist__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.3;
}

.agendalist__who {
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agendalist__meta {
  font-size: 0.85rem;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A finished or cancelled appointment is history: it steps back so the ones
   still ahead read first. */
.agendalist__item--completada .agendalist__who,
.agendalist__item--cancelada .agendalist__who {
  color: var(--text-secondary);
  font-weight: 400;
}

/* ---- free slots ----------------------------------------------------------
   Each chip books that slot: the owner is filling it because someone called or
   walked in. Nothing else competes for the tap — a freed slot reaches the
   waiting list on its own when a booking is cancelled. */
.gaps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.45rem;
  max-height: min(60vh, 560px);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Reserve the scrollbar so the chips do not reflow when the list overflows. */
  scrollbar-gutter: stable;
}

.gap {
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  overflow: hidden;
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease);
}

.gap:hover,
.gap:focus-within {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  background: var(--accent-soft);
}

.gap__take {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  text-decoration: none;
  color: inherit;
  line-height: 1.2;
}

.gap__time {
  grid-column: 1;
  padding: 0.45rem 0.6rem 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.gap__who {
  grid-column: 1;
  padding: 0 0.6rem 0.45rem;
  font-size: 0.74rem;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A slot with nobody to name is a single line, so it centres instead. */
.gap__take:not(:has(.gap__who)) .gap__time {
  padding-block: 0.62rem;
}

/* The one affordance: this chip opens the booking form on that hour. */
.gap__go {
  grid-column: 2;
  grid-row: 1 / -1;
  display: grid;
  place-items: center;
  width: 1.6rem;
  align-self: stretch;
  font-size: 1.05rem;
  font-weight: 500;
  line-height: 1;
  color: var(--text-secondary);
  border-left: 1px solid var(--border);
  background: var(--surface-2);
  transition: background 0.18s var(--ease), color 0.18s var(--ease);
}

.gap:hover .gap__go,
.gap:focus-within .gap__go {
  background: var(--accent);
  color: var(--accent-contrast);
  border-left-color: var(--accent);
}

.gap__take:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: -2px;
}

/* ---- the month rail ------------------------------------------------------ */
.rows {
  margin: 0;
}

.rows__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.9rem;
}

.rows__row:last-child {
  border-bottom: none;
}

.rows__row dt {
  color: var(--text-secondary);
}

.rows__row dd {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.rows__note {
  font-weight: 400;
  color: var(--text-secondary);
}

/* The euro figure the whole product argues for: it opens the list and carries
   the accent, with its two components indented beneath it. */
.rows__row--lead {
  padding-top: 0;
  font-size: 1rem;
}

.rows__row--lead dt {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--accent-strong);
  font-weight: 600;
}

.rows__row--lead dd {
  font-size: 1.25rem;
  letter-spacing: -0.02em;
  color: var(--accent-strong);
}

.rows__row--sub {
  border-bottom: none;
  padding: 0.2rem 0 0.2rem 1rem;
  font-size: 0.85rem;
}

.rows__row--sub dt {
  position: relative;
}

.rows__row--sub dt::before {
  content: "";
  position: absolute;
  left: -0.7rem;
  top: 0.55em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 45%, transparent);
}

.rows__row--sub dd {
  font-weight: 500;
  color: var(--text-secondary);
}

/* Separates the recovered-value group from the plain month counters. */
.rows__row--gap {
  margin-top: 0.6rem;
  border-top: 1px solid var(--border);
  padding-top: 0.7rem;
}

/* =============================================================================
   DIRECTORY LIST
   A customer directory is scanned, not read. Dense rows with the figures in
   their own columns, so visits and spend line up down the page and a hundred
   customers stay one screen of scrolling instead of ten.
   ============================================================================= */
.dirlist__count {
  margin: 1.25rem 0 0.4rem;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-secondary);
}

.dirlist {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.dirlist__item + .dirlist__item {
  border-top: 1px solid var(--border);
}

.dirrow {
  display: grid;
  align-items: center;
  gap: 0.1rem 0.85rem;
  padding: 0.6rem 1rem;
  text-decoration: none;
  color: inherit;
  transition: background 0.15s var(--ease);
  /* Phone first: avatar beside a stacked name and meta line. */
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "avatar name    chevron"
    "avatar meta    chevron";
}

a.dirrow:hover,
a.dirrow:focus-visible {
  background: var(--surface-2);
}

.dirrow__avatar {
  grid-area: avatar;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  font-size: 0.88rem;
  font-weight: 600;
  color: #fff;
  background: var(--dot, var(--accent));
}

.dirrow__name {
  grid-area: name;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  min-width: 0;
  font-weight: 500;
}

/* Phone: one meta line under the name. From 900px up this wrapper dissolves
   (display: contents) and its children become grid cells of their own. */
.dirrow__meta {
  grid-area: meta;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.35rem;
}

.dirrow__phone,
.dirrow__fig {
  font-size: 0.85rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.dirrow__chevron {
  grid-area: chevron;
  color: var(--text-secondary);
  font-size: 1.1rem;
}

/* Column headings only make sense once there are columns. */
.dirlist__head {
  display: none;
}

/* Phone: one meta line with the two things you scan a directory for on a
   phone — the number to call and how long since they came. Visits and spend
   are a desk question; they return with the columns at 900px. */
@media (max-width: 899px) {
  .dirrow__fig::before {
    content: "·";
    margin-right: 0.35rem;
    color: var(--text-tertiary);
  }
  .dirrow__fig--visitas,
  .dirrow__fig--gasto {
    display: none;
  }
}

/* Tablet and up: a real table, with its heading row. */
@media (min-width: 900px) {
  .dirlist__head {
    display: block;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
  }
  .dirlist__head .dirrow {
    padding-block: 0.5rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
  }
  .dirlist__head .dirrow__name {
    font-weight: 600;
  }
  .dirlist__head .dirrow__phone,
  .dirlist__head .dirrow__fig {
    font-size: inherit;
    color: inherit;
  }

  .dirrow {
    grid-template-columns:
      34px minmax(0, 1.7fr) minmax(8.5rem, 0.9fr)
      minmax(6rem, 0.6fr) minmax(5.5rem, 0.5fr) minmax(4.5rem, 0.4fr) 1rem;
    grid-template-areas: "avatar name phone visita visitas gasto chevron";
    gap: 0.85rem;
    padding: 0.5rem 1.1rem;
  }
  /* The wrapper dissolves so its children are laid out by the row's grid. */
  .dirrow__meta {
    display: contents;
  }
  .dirrow__phone { grid-area: phone; }
  .dirrow__fig--visita  { grid-area: visita; }
  .dirrow__fig--visitas { grid-area: visitas; text-align: right; }
  .dirrow__fig--gasto   { grid-area: gasto;   text-align: right; }
  .dirrow__fig {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .dirrow__fig::before {
    content: none;
  }
}

/* =============================================================================
   AUTOMATION RECIPES
   A catalog, not a stack of forms: cards in columns, with each recipe's
   settings behind a disclosure that is open only while it is running.
   ============================================================================= */
.recipes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr));
  gap: 1rem;
  margin-top: 1.75rem;
  align-items: start;
}

.recipe {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 1.25rem 1.35rem 1.35rem;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

/* A running recipe is sending messages in the owner's name: it says so with
   the accent, not just with a word. */
.recipe--on {
  border-color: color-mix(in srgb, var(--accent) 38%, var(--border));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 14%, transparent),
    var(--shadow-sm);
}

.recipe__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.35rem;
}

.recipe__title {
  margin: 0;
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.recipe__desc {
  margin: 0 0 0.75rem;
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--text-secondary);
}

.recipe__stats {
  margin: 0 0 0.75rem;
  font-size: 0.82rem;
  color: var(--text-secondary);
}

.recipe__stats strong {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* What it currently gives, readable without opening anything. */
.recipe__setup {
  margin: 0.75rem 0 0;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

.recipe__setup strong {
  color: var(--text);
  font-weight: 600;
}

.recipe__config {
  margin-top: 0.9rem;
  border-top: 1px solid var(--border);
  padding-top: 0.4rem;
}

.recipe__config > summary {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent-strong);
  cursor: pointer;
  list-style: none;
}

.recipe__config > summary::-webkit-details-marker {
  display: none;
}

.recipe__config > summary::before {
  content: "›";
  display: inline-block;
  font-size: 1.05rem;
  line-height: 1;
  transition: transform 0.18s var(--ease);
}

.recipe__config[open] > summary::before {
  transform: rotate(90deg);
}

.recipe__config > summary:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: 4px;
}

.recipe__foot {
  margin-top: 1rem;
}

/* The on/off control is the point of the card, so it reads as a switch rather
   than as one more checkbox in a form. */
.switch {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 500;
}

.switch input {
  appearance: none;
  flex: none;
  width: 40px;
  height: 23px;
  border-radius: 999px;
  background: var(--border-strong);
  position: relative;
  cursor: pointer;
  transition: background 0.2s var(--ease);
}

.switch input::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s var(--ease);
}

.switch input:checked {
  background: var(--accent);
}

.switch input:checked::after {
  transform: translateX(17px);
}

.switch input:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* =============================================================================
   AJUSTES (settings)
   The owner opens this to change one thing and leave. Two rules do the work:
   the index is a map — grouped, iconed, and showing the current value, so most
   visits end without opening anything — and every sub-page puts its form and
   the text that explains it side by side, so six fields are one screen instead
   of six. The one strong branded moment is the band at the top of the index;
   below it, the work (same shape as the panel's day band).
   ============================================================================= */

/* Toggled panels (capacity mode) must stay hidden even when their own rule
   sets a display value. */
[hidden] {
  display: none !important;
}

.settings-band {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 2.5rem;
  padding: clamp(1.1rem, 2.2vw, 1.5rem) clamp(1.3rem, 2.6vw, 2rem);
  border-radius: var(--radius-xl);
  color: var(--hero-ink);
  background: var(--hero-bg);
  box-shadow: 0 22px 48px -26px rgba(9, 46, 42, 0.62);
}

.settings-band__eyebrow {
  margin: 0 0 0.2rem;
  font-size: 0.76rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hero-dim-strong);
}

.settings-band__name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.012em;
  font-size: clamp(1.5rem, 3vw, 2rem);
  color: var(--hero-ink);
}

.settings-band__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.settings-band__fact {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.75rem;
  border-radius: 999px;
  font-size: 0.85rem;
  color: var(--hero-ink);
  background: var(--hero-chip);
  border: 1px solid var(--hero-chip-line);
}

.settings-band__fact .ico {
  color: var(--hero-mint);
}

/* ---- the map ------------------------------------------------------------- */
.settings-group {
  margin-top: 1.9rem;
}

.settings-group__title {
  margin: 0 0 0.8rem;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.settings-group .pick-list {
  margin-top: 0;
}

/* Equal-height cards: the meta line is one or two lines depending on the
   setting, and a ragged row of tiles reads as broken. */
.pick-list--grid > li {
  display: flex;
}

.pick-list--grid > li > .pick {
  flex: 1;
}

/* ---- icon chip (index rows + sub-page headers) --------------------------- */
.chip-ico {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  flex: none;
  border-radius: 13px;
  color: #fff;
  background: linear-gradient(150deg, var(--accent), var(--accent-hover));
  box-shadow: 0 8px 16px -8px color-mix(in srgb, var(--accent) 70%, transparent);
}

.chip-ico .ico {
  width: 23px;
  height: 23px;
}

/* Channel marks carry the integration's own colour so "WhatsApp" and "reseñas"
   are recognisable at a glance. The WhatsApp glyph is Meta's, used unmodified
   in the brand green only to identify the channel; the reviews mark is an
   authored pin, NOT Google's logo (that one needs Google's permission). */
.chip-ico--wa {
  background: linear-gradient(150deg, #25d366, #128c7e);
  box-shadow: 0 8px 16px -8px rgba(18, 140, 126, 0.7);
}

.chip-ico--maps {
  background: linear-gradient(150deg, #4285f4, #1a56c4);
  box-shadow: 0 8px 16px -8px rgba(26, 86, 196, 0.65);
}

/* An off/unconfigured setting should not shout in colour like a live one. */
.chip-ico--off {
  color: var(--text-secondary);
  background: var(--surface-2);
  border: 1px solid var(--border);
  box-shadow: none;
}

/* ---- sub-page header + two-column body ----------------------------------- */
.settings-head {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.settings-head h1 {
  margin: 0;
}

.settings-head .lede {
  margin: 0.35rem 0 0;
  max-width: 62ch;
}

.settings-layout {
  display: grid;
  gap: 1.25rem;
  align-items: start;
  margin-top: 1.5rem;
}

@media (min-width: 940px) {
  .settings-layout {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: 1.5rem 2rem;
  }

  /* When the left column is a list or a grid editor it needs more of the width
     than the note beside it. */
  .settings-layout--main {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  }
}

/* Normal flow, not a grid: the fields inside already carry their own spacing
   and adjacent margins collapse the way they should. */
.settings-col {
  min-width: 0;
}

.settings-col > * + * {
  margin-top: 1.25rem;
}

.settings-note {
  padding: 1.1rem 1.25rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.settings-note h2 {
  margin: 0;
  font-size: 1rem;
}

/* The note is a <details>: beside the form on a wide screen it is always open,
   but stacked under it on a phone it would just be more page to scroll past, so
   the script closes it there (see ajustes.js). */
.settings-note > summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  list-style: none;
}

.settings-note > summary::-webkit-details-marker {
  display: none;
}

.settings-note > summary::after {
  content: "›";
  margin-left: auto;
  font-size: 1.2rem;
  line-height: 1;
  color: var(--text-tertiary);
  transition: transform 0.18s var(--ease);
}

.settings-note[open] > summary::after {
  transform: rotate(90deg);
}

.settings-note[open] > summary {
  margin-bottom: 0.7rem;
}

.settings-note > summary:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 3px;
  border-radius: 4px;
}

.settings-note p,
.settings-note li {
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text-secondary);
}

/* Hasta ahora ninguna nota tenía más de un párrafo, así que nadie notó que no
   se separaban: tres seguidos se leían como un muro. */
.settings-note p + p {
  margin-top: 0.7rem;
}

.settings-note ul {
  margin: 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.5rem;
}

.settings-note strong {
  color: var(--text);
}

/* ---- option cards (capacity mode) ---------------------------------------- */
.optioncards {
  display: grid;
  gap: 0.9rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.optioncard {
  display: block;
  padding: 1rem 1.1rem;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease),
    box-shadow 0.18s var(--ease);
}

.optioncard:hover {
  border-color: var(--border-strong);
}

.optioncard__head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 600;
}

.optioncard input {
  width: 1.15rem;
  height: 1.15rem;
  margin: 0;
  flex: none;
  accent-color: var(--accent);
}

.optioncard__desc {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* .is-selected is set by the script so the card reacts on click, before any
   save; :has() covers the no-JS case. */
.optioncard.is-selected,
.optioncard:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.optioncard:has(input:focus-visible) {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* A wide container can hold the week as two columns of days instead of seven
   stacked rows — the difference between one screen and three. */
@media (min-width: 1120px) {
  .grid-wide .week {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---- loyalty card preview ------------------------------------------------ */
.stamps {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.85rem 0 0;
}

.stamp {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1.5px dashed var(--border-strong);
  color: var(--text-tertiary);
  font-size: 0.7rem;
}

.stamp--prize {
  border: none;
  color: var(--accent-contrast);
  background: var(--accent);
  box-shadow: var(--shadow-sm);
}

.settings-head .steps {
  margin-bottom: 0.3rem;
}

/* A colour picker is a swatch, not a text field: at full input width it reads
   as a broken control. */
.input[type="color"] {
  width: 100%;
  height: 46px;
  padding: 4px;
  cursor: pointer;
}

/* Status words in a badge are title-cased ("Confirmada"); a phrase is not. */
.badge--text {
  text-transform: none;
}

/* The state badge shares the meta line with the value, so the line has to be
   allowed to wrap on a narrow card. */
.settings-group .pick__meta {
  flex-wrap: wrap;
  row-gap: 0.2rem;
}

/* =============================================================================
   Pop-ups
   A form that used to be a page, shown over the page it was opened from. The
   panel rises and settles; the ground behind it dims and blurs just enough to
   say "this is the thing now" without hiding where you were. Both movements go
   under prefers-reduced-motion — the pop-up stays, the travel does not.
   ============================================================================= */

.modal {
  /* The dialog element IS the backdrop here: it fills the viewport and centres
     its panel, which keeps the click-outside test to `target === dialog`. */
  width: 100%;
  max-width: 100%;
  max-height: 100%;
  height: 100%;
  margin: 0;
  padding: 1rem;
  border: 0;
  background: transparent;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: grid;
  place-items: center;
}
.modal::backdrop {
  background: rgba(24, 22, 17, 0.42);
  backdrop-filter: saturate(140%) blur(3px);
  opacity: 0;
  transition: opacity 0.22s var(--ease-out);
}
.modal.is-in::backdrop { opacity: 1; }
.modal.is-out::backdrop { opacity: 0; }

.modal__panel {
  position: relative;
  width: min(42rem, 100%);
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 1.75rem clamp(1.1rem, 4vw, 2rem) 1.6rem;
  /* Never taller than the screen; the form scrolls inside its own panel so the
     page underneath stays exactly where it was. */
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  opacity: 0;
  transform: translateY(14px) scale(0.985);
  transition: opacity 0.22s var(--ease-out), transform 0.26s var(--ease-out);
}
.modal.is-in .modal__panel { opacity: 1; transform: none; }
.modal.is-out .modal__panel {
  opacity: 0;
  transform: translateY(6px) scale(0.99);
  transition-duration: 0.16s;
}

/* Inside a pop-up the page furniture is out of place: the title block is
   already the dialog's title, and there is no column to constrain. */
.modal__body > .page-narrow,
.modal__body > .animate-in { max-width: none; animation: none; }
.modal__body .steps { display: none; }
.modal__body h1 { font-size: 1.45rem; margin-top: 0; }
.modal__body .flashes { margin-top: 0; }

.modal__x {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.16s var(--ease), color 0.16s var(--ease);
}
.modal__x:hover { background: var(--border); color: var(--text); }
.modal__x svg {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

/* The page behind must not scroll while a pop-up is open. */
html.has-modal { overflow: hidden; }

/* A button waiting on the network says so, rather than looking ignored. */
.is-loading { opacity: 0.6; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .modal::backdrop,
  .modal__panel { transition: none; }
  .modal__panel { opacity: 1; transform: none; }
}

/* =============================================================================
   Section tabs (inside Marketing)
   Quieter than the top navigation on purpose: this is movement within one
   section, not between sections. The current tab is marked with the accent
   underline that slides, so the eye can follow where it went.
   ============================================================================= */

.subnav {
  display: flex;
  gap: 0.15rem;
  margin: 0 0 1.5rem;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}
.subnav::-webkit-scrollbar { display: none; }

.subnav__tab {
  position: relative;
  flex: 0 0 auto;
  padding: 0.55rem 0.85rem;
  color: var(--text-secondary);
  font-size: 0.92rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  transition: color 0.16s var(--ease), background 0.16s var(--ease);
}
.subnav__tab:hover { color: var(--text); background: var(--surface-2); }
.subnav__tab::after {
  content: "";
  position: absolute;
  left: 0.85rem;
  right: 0.85rem;
  bottom: -2px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 0.24s var(--ease-out);
}
.subnav__tab.is-current { color: var(--text); font-weight: 600; }
.subnav__tab.is-current::after { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .subnav__tab, .subnav__tab::after { transition: none; }
}

/* In a pop-up the section tabs are noise: you are not navigating, you are
   looking at one thing and going back to what you were doing. */
.modal__body .subnav { display: none; }

/* "Ask them, don't tick it yourself": the block on a customer file that turns a
   permission the owner cannot give into a WhatsApp they can send. */
.ask-consent {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 1.25rem;
  padding: 0.85rem 1rem;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: var(--radius);
}
.ask-consent__txt {
  flex: 1 1 16rem;
  margin: 0;
  font-size: 0.88rem;
  color: var(--text-secondary);
}

/* =============================================================================
   "Tell me if something frees up earlier"
   A second question that only exists once the first is answered: the options
   unfold under the checkbox instead of sitting there asking to be read by the
   many people who will not tick it.
   ============================================================================= */

.antes {
  margin-bottom: 1.25rem;
  padding: 0.9rem 1rem 0.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
}
.antes.is-open {
  border-color: color-mix(in srgb, var(--accent) 34%, transparent);
  background: var(--accent-soft);
}
.antes .checkbox { margin-bottom: 0.65rem; }

.antes__opciones {
  display: grid;
  gap: 0.15rem;
  padding: 0.35rem 0 0 1.55rem;
  /* Unfolds rather than appears. The grid row goes 0fr → 1fr, which animates
     where `height: auto` cannot. */
  overflow: hidden;
}
.antes.is-open .antes__opciones { animation: antes-abrir 0.26s var(--ease-out); }

@keyframes antes-abrir {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}

.radio {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  color: var(--text-secondary);
  padding: 0.3rem 0;
  cursor: pointer;
}
.radio input {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--accent);
}

.antes__nota {
  margin: 0.4rem 0 0.75rem;
  font-size: 0.82rem;
  color: var(--text-tertiary);
}

@media (prefers-reduced-motion: reduce) {
  .antes, .antes.is-open .antes__opciones { transition: none; animation: none; }
}

/* =============================================================================
   Waiting list (owner)
   One row per person, and the row says what they are waiting for rather than
   the shape of the record. The ones waiting to bring an appointment forward
   are marked, because for those the owner already has something booked.
   ============================================================================= */

.espera { list-style: none; margin: 0; padding: 0; }

.espera__fila {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  align-items: baseline;
  padding: 0.85rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  margin-bottom: 0.5rem;
}
.espera__fila--adelantar { border-left: 3px solid var(--accent); }

.espera__quien { flex: 1 1 12rem; display: flex; flex-direction: column; gap: 0.1rem; }
.espera__tel { font-size: 0.82rem; color: var(--text-tertiary); }

.espera__que {
  flex: 2 1 18rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  font-size: 0.92rem;
  color: var(--text-secondary);
}
.espera__meta { font-size: 0.8rem; color: var(--text-tertiary); }

/* Un guardado que volvió mal. No se reintenta solo a propósito: puede que lo
   de arriba sí se guardara, y una cita duplicada es peor que un aviso. */
.modal__fallo {
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--danger) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
  color: var(--text);
  font-size: 0.88rem;
}

/* Buscador dentro de un desplegable largo. Se queda pegado arriba mientras la
   lista se desplaza, que es lo único que lo hace útil en una lista de cientos. */
.cs__buscar {
  position: sticky;
  top: 0;
  z-index: 1;
  width: 100%;
  margin-bottom: 4px;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
}
.cs__buscar:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--ring);
}

/* ---- su WhatsApp (Ajustes) -----------------------------------------------
   Tres piezas y ninguna existía: el número tal y como lo ve su cliente, los
   tres pasos del trámite y la lista de mensajes uno a uno. El `.stepper` de la
   reserva no sirve aquí: es horizontal y recorta la etiqueta a una línea, y
   estos pasos son frases ("Que WhatsApp apruebe tus mensajes"). En vertical
   caben enteros y en el móvil se leen mejor, que es donde se mira esto. */
.wa-numero {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 1.1rem 0 0;
  padding: 0.5rem 0.9rem;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

.wa-pasos {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.9rem;
}

.wa-paso {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  color: var(--text-tertiary);
}

.wa-paso__dot {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--surface);
  font-size: 0.78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  transition: all 0.25s var(--ease);
}

.wa-paso.is-done { color: var(--text-secondary); }

.wa-paso.is-done .wa-paso__dot {
  color: var(--accent-contrast);
  background: var(--accent);
  border-color: var(--accent);
}

.wa-paso.is-now {
  color: var(--text);
  font-weight: 600;
}

.wa-paso.is-now .wa-paso__dot {
  color: var(--accent-contrast);
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--ring);
}

.wa-paso__texto {
  display: grid;
  gap: 0.1rem;
  padding-top: 0.15rem;
  min-width: 0;
}

/* El estado va debajo y en pequeño, no en un distintivo a la derecha: a 360 px
   un distintivo empuja la frase y cada paso rompe por un sitio distinto. */
.wa-paso__estado {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-tertiary);
}

/* Siete mensajes en una sola columna estiran la página y dejan media pantalla
   vacía al lado. En cuanto hay ancho se reparten, y la lista se ve entera de un
   vistazo, que es como se mira una lista de siete cosas. */
.wa-mensajes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.55rem;
}

@media (min-width: 700px) {
  .wa-mensajes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.7rem 2.5rem;
  }
}

@media (min-width: 1180px) {
  .wa-mensajes {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.wa-mensaje {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  color: var(--text-secondary);
  font-size: 0.95rem;
}

.wa-mensaje__marca {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.3rem;
  height: 1.3rem;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-tertiary);
  background: var(--surface-2);
}

.wa-mensaje.is-ok .wa-mensaje__marca {
  color: var(--accent);
  background: var(--accent-soft);
}

/* Ámbar, no rojo: una plantilla con pegas la corregimos nosotros y el negocio
   sigue enviando el resto. Pintarlo de alarma sería asustar por un trámite. */
.wa-mensaje.is-pega .wa-mensaje__marca {
  color: #ff9f0a;
  background: color-mix(in srgb, #ff9f0a 16%, transparent);
}

.wa-mensaje__estado {
  display: block;
  font-size: 0.8rem;
  color: var(--text-tertiary);
}
