/*
.SYNOPSIS
    Styles for the JE Barber Estudio site (home, productos, turnos). Redesign pass driven by
    direct user feedback: 3-zone nav (brand-left/links-center/cta-right) like so-alia-webapp's
    header, denser nav spade pattern (side rails removed), slower barber-pole spin, Fraunces
    display type instead of Space Grotesk, a real month-grid calendar, and icon-based product
    cards instead of text-only ones.
.AUTHOR
    Santino Ondarza
.CREATED
    2026-09-16
.MODIFIED
    2026-10-15
.CHANGELOG
    2026-09-16 - Initial creation
    2026-10-15 - Added styles for the real turnos booking-engine UI (service select, week-nav
                 paging, slot franja grouping, sticky summary, feedback states)
    2026-10-15 - Feedback redesign pass: 3-zone nav, denser single nav spade pattern (side rails
                 removed), slower pole spin + static footer variant, Fraunces display font, real
                 month-grid calendar, icon-based product cards, Instagram glyph
    2026-10-15 - Home-focused follow-up pass: half-drop interlaced spade pattern (was a flat
                 grid), radial vignette + grain texture on body background instead of a flat
                 color, location badge style for the hero
    2026-10-15 - Spade pattern rebuilt as a real diamond-trellis lattice (geometric outline +
                 cell motif, not scattered glyphs); large hero logo treatment with
                 mix-blend-mode: screen to hide the logo PNG's opaque black background
    2026-10-15 - Reverted the diamond-trellis pattern and hero-logo styles per user feedback
                 (disliked both) -- spade pattern back to the half-drop glyph version
    2026-10-15 - Audit pass per design-taste-frontend skill: swapped Fraunces for Playfair
                 Display (Fraunces is explicitly flagged as an over-used LLM default display
                 serif by that skill); added .section-compact, .instagram-link; contact-grid
                 now 2 columns instead of 3
    2026-10-15 - Diagnosed and fixed the spade pattern for real: it used the Unicode "spade"
                 text glyph (font-rendering dependent, blurry at small sizes) and rotated it
                 180deg for the half-drop effect, which broke its recognizable silhouette. Spade
                 is now a hand-drawn vector path (body + stem) inside the diamond-trellis lattice
                 -- same structural idea as the earlier (reverted) attempt, but with a correctly
                 drawn icon instead of abused text, chosen by the user from 4 rendered options
    2026-10-15 - Removed the diamond-trellis lattice lines per user feedback (disliked them) --
                 spade tile is now just the vector spade (upright, no rotation) in a 2-row brick
                 offset repeat, no geometric lines at all
    2026-10-15 - Fixed a real bug in that brick tile: one spade straddled x=0, so the tile edge
                 sliced it in half on every repeat ("entrecortado"). Moved both spades fully
                 inside the tile bounds instead.
    2026-10-15 - Densified the spade tile (2 spades per row via the "duplicate at tile-width"
                 wraparound technique, no clipping) and fixed tile HEIGHT to 36px specifically
                 because it divides --nav-height (72px) evenly -- a prior 32px tile didn't,
                 which sliced rows at the nav's top/bottom edge. Hero/Cortes divider thickened
                 to 2px and recolored pure black; removed the nav bar's own bottom border.
    2026-10-15 - Added a pill-shaped inner box around the nav items (logo/links/CTA), inset
                 inside the full-width spade-pattern bar -- NOT a floating detached pill (tried
                 that first, user explicitly rejected it: the outer bar must stay full-width
                 with the spade pattern, only the inner content box is rounded). Documented as
                 the one deliberate exception to the site's all-sharp shape system. Fixed a
                 mobile-only wrap bug this introduced ("JE BARBER" broke into two lines inside
                 the narrower pill) with white-space: nowrap plus a <480px padding/gap tightening
                 media query. Pill background is a black-to-charcoal gradient per user request.
    2026-10-15 - Productos: removed .back-link entirely (now dead CSS on every page, deleted);
                 made category headings much more prominent (bigger Playfair Display, full-ink
                 color, bottom divider) -- fixed `.product-category h3` to `.product-category >
                 h3` since the bare descendant selector was also matching each product card's
                 own `<h3>` name, giving every product name an unwanted underline too
    2026-10-15 - `.product-card-icon` restyled from a small floating icon into a full-width
                 square "image box" (aspect-ratio 1/1, own background + bottom border) so it
                 reads as a proper product-photo frame; `.product-card` padding moved onto its
                 text children (h3/p/.product-note each get their own 24px side margin) since
                 the image box now needs to span edge-to-edge
    2026-10-15 - Added .contact-modal and its field/action styles for turnos.html's new
                 contact-details dialog (nombre, apellido, email, telefono), shown between
                 "Confirmar turno" and the appointment actually being registered
    2026-10-16 - Added .hp-field (visually-hidden honeypot input for #contactForm, part of the
                 new real Cloudflare D1 backend's POST /api/book spam guard)
    2026-10-16 - Added .admin-list/.admin-row for the new admin dashboard's appointment list
    2026-10-16 - Fixed a real bug found via Playwright: .btn[hidden] stayed visible because the
                 .btn class's `display: inline-flex` beats the UA stylesheet's
                 `[hidden] { display: none }` in a specificity tie -- cancelar-ui.js's Cancelar
                 button never actually hid itself after a successful cancel or on an
                 already-cancelled/out-of-window turno. Added an explicit .btn[hidden] override.
*/

:root {
  --bg: #121110;
  --bg-alt: #1a1816;
  --bg-band: #0b0a09;
  --ink: #f5f3f0;
  --ink-dim: #a9a39a;
  --line: rgba(245, 243, 240, 0.14);
  --line-strong: rgba(245, 243, 240, 0.28);
  --invert-bg: #f5f3f0;
  --invert-ink: #121110;
  --radius: 0px;
  --nav-height: 72px;
  --max-width: 1200px;
  --font-display: "Playfair Display", "Georgia", serif;
  --font-body: "Manrope", "Segoe UI", sans-serif;
  --pole-red: #b3352c;
  --pole-blue: #2c4a70;
  /* Brick/staggered repeat: only spades, no lattice lines. Two spades per row per tile (denser
     than the first attempt), row 2 offset by half the row spacing from row 1. The row-2 spade
     that would land exactly on the tile's x=0 edge is drawn twice, once at that position and
     once shifted by a full tile-width -- the two copies' visible slices are complementary, so
     together they reconstruct the whole spade across the seam with no horizontal clipping (the
     earlier "entrecortado" bug was a single unmirrored copy straddling that same edge).
     Tile HEIGHT is 36 specifically because it divides --nav-height (72px) evenly: the pattern
     repeats exactly twice within the visible nav bar, so every row starts and ends fully inside
     it -- no row is ever sliced by the nav's top/bottom edge. Do not change one without the
     other: tile height must always be an exact divisor of --nav-height. */
  --spade-tile: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='36'%3E%3Cg fill='white' fill-opacity='0.14'%3E%3Cpath transform='translate(9,2)' d='M6 1c0 0-5 4-5 7.3 0 1.6 1.3 2.7 2.9 2.7 1.1 0 2-0.6 2.1-1.5.3 0.9 1.2 1.5 2.1 1.5 1.6 0 2.9-1.1 2.9-2.7 0-3.3-5-7.3-5-7.3z M6 10.5 L7.8 15 L4.2 15 Z'/%3E%3Cpath transform='translate(39,2)' d='M6 1c0 0-5 4-5 7.3 0 1.6 1.3 2.7 2.9 2.7 1.1 0 2-0.6 2.1-1.5.3 0.9 1.2 1.5 2.1 1.5 1.6 0 2.9-1.1 2.9-2.7 0-3.3-5-7.3-5-7.3z M6 10.5 L7.8 15 L4.2 15 Z'/%3E%3Cpath transform='translate(24,20)' d='M6 1c0 0-5 4-5 7.3 0 1.6 1.3 2.7 2.9 2.7 1.1 0 2-0.6 2.1-1.5.3 0.9 1.2 1.5 2.1 1.5 1.6 0 2.9-1.1 2.9-2.7 0-3.3-5-7.3-5-7.3z M6 10.5 L7.8 15 L4.2 15 Z'/%3E%3Cpath transform='translate(-6,20)' d='M6 1c0 0-5 4-5 7.3 0 1.6 1.3 2.7 2.9 2.7 1.1 0 2-0.6 2.1-1.5.3 0.9 1.2 1.5 2.1 1.5 1.6 0 2.9-1.1 2.9-2.7 0-3.3-5-7.3-5-7.3z M6 10.5 L7.8 15 L4.2 15 Z'/%3E%3Cpath transform='translate(54,20)' d='M6 1c0 0-5 4-5 7.3 0 1.6 1.3 2.7 2.9 2.7 1.1 0 2-0.6 2.1-1.5.3 0.9 1.2 1.5 2.1 1.5 1.6 0 2.9-1.1 2.9-2.7 0-3.3-5-7.3-5-7.3z M6 10.5 L7.8 15 L4.2 15 Z'/%3E%3C/g%3E%3C/svg%3E");
  /* Fine grain overlay for the body background, classic print-texture feel rather than flat digital black */
  --grain-tile: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Elegant dark vignette + a subtle grain texture via body::after, fixed so both read as one
   continuous backdrop behind scrolling content rather than a flat background color. */

body::after {
  content: "";
  position: fixed;
  inset: 0;
  background-image: var(--grain-tile);
  background-repeat: repeat;
  opacity: 0.035;
  mix-blend-mode: overlay;
  pointer-events: none;
  z-index: 1;
}

/* Barber pole accent (classic red/white/blue), used as a small brand icon, not a UI accent color */

.barber-pole {
  flex: 0 0 auto;
  width: 12px;
  height: 32px;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  background-image: repeating-linear-gradient(
    -45deg,
    var(--pole-red) 0 6px,
    var(--ink) 6px 12px,
    var(--pole-blue) 12px 18px,
    var(--ink) 18px 24px
  );
  background-size: 34px 34px;
  animation: barberPoleSpin 3.5s linear infinite;
}

@keyframes barberPoleSpin {
  to {
    background-position: 34px 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .barber-pole {
    animation: none;
  }
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background-color: var(--bg);
  background-image: radial-gradient(ellipse 1100px 760px at 50% -8%, #211d19 0%, var(--bg) 48%, var(--bg-band) 100%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
}

.wrap {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 24px;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.08;
  margin: 0;
  letter-spacing: -0.01em;
}

p {
  margin: 0;
}

/* Buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 24px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), background 0.2s ease, color 0.2s ease;
}

/* A class-based `display` rule beats the UA stylesheet's `[hidden] { display: none }` in a
   specificity tie, so .btn[hidden] (e.g. cancelar-ui.js's Cancelar-turno button before its state
   is known, or admin-dashboard.js toggling rows) would otherwise stay visible despite `hidden`
   being set -- found live via Playwright while testing cancelar.html. Explicit override. */
.btn[hidden] {
  display: none;
}

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

.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn:disabled:active {
  transform: none;
}

.btn-primary {
  background: var(--invert-bg);
  color: var(--invert-ink);
  border-radius: 999px;
  border-color: #c4c4c4;
}

.btn-primary:hover {
  background: var(--ink);
}

.btn-outline {
  background: transparent;
  color: var(--ink);
  border-color: var(--line-strong);
}

.btn-outline:hover {
  border-color: var(--ink);
}

/* Nav */

.site-nav {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--nav-height);
  display: flex;
  align-items: center;
  background-color: rgba(18, 17, 16, 0.86);
  background-image: var(--spade-tile);
  background-repeat: repeat;
  backdrop-filter: blur(10px);
}

/* Pill shape, by explicit request -- a deliberate, documented exception to the site's
   otherwise all-sharp (--radius: 0) shape system. Three rounded elements exist on the site,
   all by explicit request: this inner nav pill, .btn-primary (also pill, see below), and the
   hero-copy card + its matching hero-visual image border (see the Hero section below, 20px
   radius). Everything else (other cards, inputs, the outer nav bar itself, .btn-outline,
   product/portfolio grids) stays sharp-cornered -- don't round anything else to "match"
   without being asked. */
.site-nav .wrap {
  display: flex;
  align-items: center;
  gap: 18px;
  width: fit-content;
  max-width: calc(100% - 64px);
  margin: 0 auto;
  padding: 6px 18px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, #000000 0%, #1a1816 100%);
}

@media (max-width: 479px) {
  .site-nav .wrap {
    gap: 12px;
    padding: 5px 14px;
    max-width: calc(100% - 24px);
  }

  .nav-cta .btn {
    min-height: 32px;
    padding: 0 12px;
    font-size: 0.78rem;
  }
}

.nav-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  min-height: 44px;
}

.nav-brand img {
  height: 48px;
  width: 48px;
  object-fit: contain;
  /* logo.png has an opaque black square background baked in, not real transparency --
     mix-blend-mode: screen hides it against the dark nav so only the white mark shows */
  mix-blend-mode: screen;
}

.nav-brand span {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Center zone: secondary nav links. Right zone (.nav-cta) holds the one primary action. */

.nav-links {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 32px;
}

.nav-link {
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--ink-dim);
  min-height: 44px;
  display: flex;
  align-items: center;
}

.nav-link:hover,
.nav-link[aria-current="page"] {
  color: var(--ink);
}

@media (min-width: 560px) {
  .nav-links {
    display: flex;
  }
}

.nav-cta .btn {
  min-height: 34px;
  padding: 0 16px;
  font-size: 0.8rem;
}

/* Hero */

.hero {
  border-bottom: 2px solid #000;
}

.hero .wrap {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
  padding-top: 56px;
  padding-bottom: 56px;
}

.location-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 18px;
  padding: 7px 14px 7px 10px;
  border: 1px solid var(--line-strong);
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
}

.location-badge svg {
  width: 15px;
  height: 15px;
  color: var(--pole-red);
  flex: 0 0 auto;
}

/* Third deliberate rounded exception to the site's all-sharp shape system (after the nav pill
   and .btn-primary), by explicit request: a black card wrapping the whole hero-copy column,
   paired with a matching black border + radius on .hero-visual so the two feel like one unit. */
.hero-copy {
  width: fit-content;
  max-width: 100%;
  background: #000;
  border: 1px solid var(--line-strong);
  border-radius: 20px;
  padding: 36px;
}

.hero-copy h1 {
  font-size: clamp(2.6rem, 7vw, 4.2rem);
  max-width: 10ch;
  font-weight: 600;
}

.hero-copy p {
  margin-top: 20px;
  color: var(--ink-dim);
  font-size: 1.05rem;
  max-width: 46ch;
}

.hero-cta {
  margin-top: 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.hero-visual {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: 20px;
}

.hero-visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (min-width: 860px) {
  .hero .wrap {
    grid-template-columns: 1.1fr 0.9fr;
    align-items: center;
    padding-top: 88px;
    padding-bottom: 88px;
  }

  .hero-visual {
    aspect-ratio: 3 / 4;
  }
}

/* Section shell */

.section {
  padding: 64px 0;
  border-bottom: 1px solid var(--line);
}

.section-alt {
  background: var(--bg-alt);
}

.section-compact {
  padding: 36px 0;
}

.section-head {
  max-width: 56ch;
  margin-bottom: 40px;
}

.section-head h2 {
  font-size: clamp(1.6rem, 4vw, 2.2rem);
}

.section-head p {
  margin-top: 12px;
  color: var(--ink-dim);
  font-size: 1rem;
}

.instagram-link {
  margin-top: 16px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
}

.instagram-link svg {
  width: 18px;
  height: 18px;
}

.instagram-link:hover {
  color: var(--ink-dim);
}

/* Portfolio grid */

.portfolio-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px;
}

.portfolio-grid figure {
  margin: 0;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--bg-band);
}

.portfolio-grid img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.portfolio-grid a:hover img {
  transform: scale(1.04);
}

@media (min-width: 640px) {
  .portfolio-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
  }
}

@media (min-width: 960px) {
  .portfolio-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* Products */

.product-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.product-card {
  background: var(--bg-alt);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Image box: a dedicated square frame for the product, not a loose floating icon. Holds the
   line-icon placeholder today (no real product photos yet) but reads as a proper photo slot. */
.product-card-icon {
  width: 100%;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-band);
  border-bottom: 1px solid var(--line);
  color: var(--ink-dim);
}

.product-card-icon svg {
  width: 38%;
  height: 38%;
}

.product-card h3 {
  margin: 20px 24px 0;
  font-size: 1.15rem;
}

.product-card p {
  margin: 10px 24px 0;
  color: var(--ink-dim);
  font-size: 0.92rem;
}

.product-card .product-note {
  margin: 16px 24px 24px;
  display: inline-block;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

@media (min-width: 640px) {
  .product-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 960px) {
  .product-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.product-grid.product-grid-catalog {
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.product-grid-teaser {
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .product-grid-teaser {
    grid-template-columns: repeat(3, 1fr);
  }
}

.section-cta {
  margin-top: 32px;
  text-align: center;
}

.product-category {
  margin-bottom: 56px;
}

.product-category:last-child {
  margin-bottom: 0;
}

.product-category > h3 {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 1.9rem);
  font-weight: 700;
  color: var(--ink);
  padding-bottom: 16px;
  margin-bottom: 28px;
  border-bottom: 2px solid var(--line-strong);
}

/* Booking band */

.booking-band {
  background: var(--invert-bg);
  color: var(--invert-ink);
  padding: 72px 0;
  text-align: center;
}

.booking-band h2 {
  font-size: clamp(1.8rem, 5vw, 2.6rem);
  max-width: 20ch;
  margin: 0 auto;
}

.booking-band p {
  margin: 18px auto 0;
  max-width: 48ch;
  color: rgba(18, 17, 16, 0.7);
  font-size: 1rem;
}

.booking-band .btn {
  margin-top: 28px;
}

.booking-band .btn-primary {
  background: var(--invert-ink);
  color: var(--invert-bg);
}

.booking-band .btn-primary:hover {
  background: #2a2724;
}

/* Contact */

.contact-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}

.contact-block h3 {
  font-size: 1.1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
}

.contact-block p,
.contact-block a {
  margin-top: 10px;
  font-size: 1.05rem;
  text-decoration: none;
}

.contact-block a:hover {
  text-decoration: underline;
}

@media (min-width: 520px) {
  .contact-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Page header (sub-pages: productos, turnos) */

.page-header {
  border-bottom: 1px solid var(--line);
  padding: 48px 0 40px;
}

.page-header h1 {
  margin-top: 0;
  font-size: clamp(1.8rem, 5vw, 2.6rem);
}

.page-header p {
  margin-top: 14px;
  color: var(--ink-dim);
  max-width: 52ch;
  font-size: 1rem;
}

.hours-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  padding: 8px 16px;
  border: 1px solid var(--line-strong);
  font-size: 0.82rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--ink-dim);
}

.hours-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pole-red);
  flex: 0 0 auto;
}

/* Scheduler (turnos.html) - visual only, does not persist anywhere yet */

.scheduler {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}

@media (min-width: 860px) {
  .scheduler {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
}

.scheduler-block {
  min-width: 0;
}

.scheduler-block h2 {
  font-size: 1.1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
  margin-bottom: 18px;
}

.scheduler-block-spaced {
  margin-top: 32px;
}

.service-select-wrap {
  display: block;
}

.service-select {
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  border: 1px solid var(--line-strong);
  background: var(--bg-alt);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.95rem;
  border-radius: var(--radius);
}

.calendar-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.calendar-nav span {
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--ink);
  text-transform: capitalize;
}

.calendar-nav-btn {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  font-size: 1rem;
}

.calendar-nav-btn:hover:not(:disabled) {
  border-color: var(--ink);
}

.calendar-nav-btn:disabled {
  opacity: 0.32;
  cursor: not-allowed;
}

.calendar-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin-bottom: 8px;
}

.calendar-weekdays span {
  text-align: center;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--ink-dim);
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}

.calendar-day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-strong);
  background: var(--bg-alt);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
}

.calendar-day.is-blank {
  visibility: hidden;
  border: none;
  background: none;
}

.calendar-day:hover:not(:disabled) {
  border-color: var(--ink);
}

.calendar-day.is-selected {
  background: var(--invert-bg);
  border-color: var(--invert-bg);
  color: var(--invert-ink);
}

.calendar-day:disabled {
  opacity: 0.32;
  cursor: not-allowed;
}

.slots-empty {
  color: var(--ink-dim);
  font-size: 0.92rem;
}

.slot-group-label {
  font-family: var(--font-display);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
  margin: 20px 0 10px;
}

.slot-group-label:first-child {
  margin-top: 0;
}

.slot-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

@media (min-width: 480px) {
  .slot-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.slot-btn {
  min-height: 48px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
}

.slot-btn:hover {
  border-color: var(--ink);
}

.slot-btn.is-selected {
  background: var(--invert-bg);
  border-color: var(--invert-bg);
  color: var(--invert-ink);
}

.slot-btn:disabled {
  opacity: 0.32;
  cursor: not-allowed;
}

.scheduler-summary {
  margin-top: 32px;
  padding: 24px;
  border: 1px solid var(--line);
  background: var(--bg-alt);
}

.scheduler-summary .summary-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
}

.scheduler-summary .summary-value {
  margin-top: 8px;
  font-family: var(--font-display);
  font-size: 1.3rem;
}

.scheduler-summary .btn {
  margin-top: 20px;
  width: 100%;
}

.scheduler-note {
  margin-top: 16px;
  font-size: 0.82rem;
  color: var(--ink-dim);
}

.scheduler-feedback {
  margin-top: 14px;
  font-size: 0.88rem;
  min-height: 1.2em;
}

.scheduler-feedback.is-success {
  color: var(--ink);
}

.scheduler-feedback.is-error {
  color: var(--pole-red);
}

.scheduler-confirmed {
  border-color: var(--line-strong);
}

.scheduler-confirmed .summary-value {
  color: var(--ink);
}

@media (min-width: 860px) {
  .scheduler-summary {
    position: sticky;
    top: calc(var(--nav-height) + 24px);
  }
}

/* Contact-details modal, shown on "Confirmar turno" before an appointment is actually
   registered. Sharp corners -- not one of the site's three documented rounded exceptions. */

.contact-modal {
  width: calc(100% - 48px);
  max-width: 420px;
  padding: 32px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-alt);
  color: var(--ink);
}

.contact-modal::backdrop {
  background: rgba(8, 7, 6, 0.78);
}

.contact-modal h2 {
  font-size: 1.4rem;
}

.modal-summary {
  margin-top: 8px;
  color: var(--ink-dim);
  font-size: 0.92rem;
}

.modal-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 20px;
}

.modal-field label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
}

.modal-field input {
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.95rem;
}

.modal-field input:focus {
  outline: none;
  border-color: var(--ink);
}

.modal-feedback {
  margin-top: 14px;
  font-size: 0.88rem;
  min-height: 1.2em;
}

.modal-feedback.is-error {
  color: var(--pole-red);
}

.modal-actions {
  display: flex;
  gap: 12px;
  margin-top: 24px;
}

.modal-actions .btn {
  flex: 1;
}

/* Honeypot field for #contactForm -- visually hidden via clip (not display:none, which some
   spam bots detect and skip) so a real visitor never sees or fills it; POST /api/book treats a
   non-empty value as a bot and fakes success without creating anything. */
.hp-field {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Admin dashboard appointment list */

.admin-list {
  margin-top: 24px;
  display: flex;
  flex-direction: column;
}

.admin-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}

.admin-row-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.admin-row-info strong {
  font-family: var(--font-display);
  font-size: 1.05rem;
}

.admin-row-info span {
  color: var(--ink-dim);
  font-size: 0.9rem;
}

.admin-row-info a {
  font-size: 0.9rem;
  text-decoration: underline;
  width: fit-content;
}

@media (max-width: 560px) {
  .admin-row {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Footer */

.site-footer {
  padding: 32px 0;
}

.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.footer-brand {
  display: flex;
  align-items: center;
  gap: 10px;
}

.footer-brand img {
  height: 26px;
  width: 26px;
  object-fit: contain;
  mix-blend-mode: screen;
}

.footer-brand span {
  font-size: 0.85rem;
  color: var(--ink-dim);
}

.site-footer a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
  color: var(--ink-dim);
  text-decoration: none;
}

.site-footer a svg {
  width: 18px;
  height: 18px;
}

.site-footer a:hover {
  color: var(--ink);
}

/* Reveal-on-scroll: visible by default, JS only opts elements into the pre-reveal state */

.reveal-up {
  opacity: 1;
  transform: none;
}

.js-enabled .pre-reveal {
  opacity: 0;
  transform: translateY(18px);
}

.reveal-up.is-visible {
  opacity: 1;
  transform: none;
  transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .js-enabled .pre-reveal {
    opacity: 1;
    transform: none;
  }

  .portfolio-grid img,
  .btn {
    transition: none;
  }
}
