/* ============================================================
   04 Del Patio Barbershop - site.css

   READ: late-opening neighbourhood barbershop landing for Nou Barris
   families, with a warm plainspoken language, leaning toward a saturated
   teal ground where the week's opening hours are the page's hero object.

   WHAT THIS DESIGN IS NOT. The shop's listing calls it a "peluqueria,
   barberia dominicana", but not one of its six read reviews mentions
   Dominican, Latin, Afro or curly-hair work. So there is no Caribbean
   signalling anywhere in here: no flag colours, no palm, no domino, no
   tropical motif. Teal and coral were chosen precisely because they read
   as confident and local rather than as any country's flag. The shop's
   own self-description appears once on the page, framed as its own words,
   and the design supplies no specialism the evidence does not support.

   WHAT IT IS BUILT AROUND. Three facts that are evidenced:
     1. It is open late and every day differs (the week strip is the spine).
     2. Families come, and a reviewer names games for the children.
     3. 4.9 from 93 Google reviews.

   ONE PHOTOGRAPH, AND THAT IS THE WHOLE OF IT. Public sources hold exactly
   one usable frame of this business: an empty interior, with no signage
   anywhere in it. There is no shopfront, no night shot and no play-corner
   photograph to be had, and the shop's Instagram is the owner's personal
   reel rather than shop marketing. So this page carries one image, in the
   "where we are" section, described in its alt text as only what is visible
   and never as proof of which shop it is. The other three slots this design
   once reserved have been cut rather than left standing empty: a labelled
   hole is honest but it is still a hole, and a page that reads as
   deliberately typographic is the better outcome. Everything that used to
   lean on a photograph now leans on type, on the week chart and on the six
   real reviews.

   Loaded FIRST, before ds.css / booking.css / media.css, so those layers
   refine it. Everything they need is declared here:
   --bg --bg-2 --line --text --muted --accent --accent-ink
   --font-display --font-body
   ============================================================ */

/* ---------- Tokens ---------- */

:root {
  /* Palette. Measured contrast on the #08454E ground:
       ink #FAF7F2        9.97:1
       muted #C3D8DB      7.18:1
       accent #FF5A3C     3.44:1  <- LARGE TEXT, FILLS AND RULES ONLY.
       error #ff9e8d      5.34:1
     The accent is never small running text, never a caption, and never a
     link inside a paragraph. That is a hard constraint of this palette and
     it is honoured throughout the file. */
  --bg: #08454E;
  --bg-2: #063B43;   /* card and placeholder surface: DEEPER than the ground,
                        which lifts ink to 11.46:1 and error text to 6.14:1 */
  --bg-3: #0A4E58;   /* form control fill, 8.76:1 for ink */
  --line: rgba(250, 247, 242, 0.17);
  --line-strong: rgba(250, 247, 242, 0.34);
  --text: #FAF7F2;
  --muted: #C3D8DB;
  --accent: #FF5A3C;
  --accent-ink: #2A0A03;   /* 5.93:1 on the coral fill */

  --font-display: "Unbounded", "Figtree", system-ui, -apple-system, sans-serif;
  --font-body: "Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* One corner-radius system, chosen and then held. Generously round,
     because the register of this page is "come in and sit down". */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-pill: 999px;

  --nav-h: 64px;
  --pad: clamp(1.25rem, 4vw, 3rem);
  --maxw: 1160px;

  --ease: cubic-bezier(0.22, 0.75, 0.3, 1);

  /* ds.css interaction dials, matched to the motion dials on <html>. */
  --ds-lift: 3px;
  --ds-dur: 0.3s;

  /* Native form controls (the date picker above all) must render dark, or
     the calendar glyph is a black icon on a dark teal field. */
  color-scheme: dark;
}

/* THE ERROR COLOUR, SET BY HAND AND ON PURPOSE.
   booking.css picks --bad off prefers-color-scheme, which cannot know that
   this page is dark whatever the system is set to. On a light system theme
   its #b3261e default measures 1.63:1 here, and the error message is the one
   string on the page a person MUST be able to read. #ff9e8d measures 5.34:1
   on the ground and 6.14:1 on the card surface.
   `html:root` rather than `:root` because booking.css loads after this file
   and would otherwise win on equal specificity. */
html:root { --bad: #ff9e8d; }

/* ---------- Reset and base ---------- */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

a { color: inherit; }

img { max-width: 100%; }

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--pad);
}

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

/* Reveal floor. motion.js takes ownership when it runs (ds.css switches this
   transition off); if it never runs, this is what still shows the page, and
   the <noscript> block in the markup covers scripting being off entirely. */
.rv {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; transition: none; }
}

/* ---------- Icons ----------
   Always beside a word, never instead of one. Sprite symbols only; nothing
   here draws a path by hand. */
.ic {
  width: 1.05em; height: 1.05em;
  flex: none;
  vertical-align: -0.16em;
  color: var(--accent);
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 50px;
  padding: 0.8rem 1.5rem;
  border-radius: var(--r-pill);
  border: 1.5px solid transparent;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  text-align: center;
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}
.btn-primary .ic { color: var(--accent-ink); }
.btn-primary:hover { background: #ff6f54; border-color: #ff6f54; }

.btn-ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--line-strong);
}
.btn-ghost .ic { color: var(--text); }
.btn-ghost:hover { background: rgba(250, 247, 242, 0.07); }

.btn:disabled { opacity: 0.6; cursor: default; }

/* ---------- Header ---------- */

.site-head {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .site-head { background: #08454E; }
}

.head-in {
  min-height: var(--nav-h);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-block: 0.5rem;
  flex-wrap: wrap;
}

.brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: -0.02em;
  text-decoration: none;
  line-height: 1.15;
  margin-right: auto;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.brand small {
  font-size: 0.78em;
  font-weight: 600;
  color: var(--muted);
  margin-left: 0.4em;
}

/* Keyboard users land here first. Hidden until focused, then a real target. */
.skip {
  position: absolute;
  left: 0.75rem;
  top: -4rem;
  z-index: 100;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1rem;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
  text-decoration: none;
  transition: top 0.2s var(--ease);
}
.skip:focus { top: 0.75rem; }

.langs { display: flex; gap: 0.15rem; }
.langs a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 0.55rem;
  border-radius: var(--r-pill);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
}
.langs a:hover { color: var(--text); background: rgba(250, 247, 242, 0.08); }
/* Never colour alone: the current language also gets the filled pill. */
.langs a[aria-current="true"] {
  background: var(--accent);
  color: var(--accent-ink);
}

.nav-cta {
  display: none;
  align-items: center;
  min-height: 44px;
  padding: 0 1.15rem;
  border-radius: var(--r-pill);
  border: 1.5px solid var(--accent);
  color: var(--text);
  font-weight: 700;
  font-size: 0.92rem;
  text-decoration: none;
}
.nav-cta:hover { background: var(--accent); color: var(--accent-ink); }
@media (min-width: 760px) { .nav-cta { display: inline-flex; } }

/* ---------- Hero ----------
   LAYOUT FAMILY 1: a full-width typographic hero. Four text elements, no
   more: headline, lede, actions, rating line.

   THIS WAS AN ASYMMETRIC SPLIT WITH A PHOTOGRAPH COLUMN AND IS NOT ANY MORE.
   A hero photograph is the page saying "this is the shop", and the single
   photograph that exists for this business has no signage in the frame, so it
   cannot say that. Leaving the slot empty was worse: a reserved box beside the
   headline is the first thing a visitor sees and it reads as an unfinished
   page. So the column is gone, the headline takes the whole measure, and the
   actions and the Google rating sit on one line beneath it.

   min-height uses dvh so the mobile browser chrome cannot push the booking
   CTA under the fold. */

.hero {
  min-height: calc(100dvh - var(--nav-h));
  display: flex;
  align-items: center;
  padding-block: clamp(2rem, 7vh, 4.5rem);
}
@supports not (height: 100dvh) {
  .hero { min-height: calc(100vh - var(--nav-h)); }
}

.hero-in {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.25rem, 5vw, 3.5rem);
  align-content: center;
  width: 100%;
}

/* The headline now owns the full measure, so it can be far larger than the
   4.6rem it was capped at while it shared the row with a photograph column.
   The accent half is set `display: block`, which is what guarantees exactly
   two lines in all three languages at every width: "Obert / fins tard" would
   otherwise fit on one line at 1280px and the Spanish would not, and a hero
   that changes shape between languages reads as an accident. */
.hero h1 {
  font-size: clamp(2.5rem, 8.5vw, 6rem);
  letter-spacing: -0.04em;
  margin-bottom: 1.2rem;
}
.hero h1 em {
  display: block;
  font-style: normal;
  color: var(--accent);   /* display size, so 3.44:1 clears the 3:1 bar */
}

.hero-lede {
  font-size: clamp(1.05rem, 1rem + 0.5vw, 1.3rem);
  color: var(--text);
  max-width: 42ch;
}

/* Actions and the rating share one row on anything wider than a phone: the
   CTA anchors the left edge under the headline, the Google score closes the
   line on the right. On a phone they stack and the buttons go full width. */
.hero-foot { display: grid; gap: 1.4rem; }
@media (min-width: 760px) {
  .hero-foot {
    grid-template-columns: auto auto;
    justify-content: space-between;
    align-items: center;
    gap: 1.4rem 2rem;
  }
  .hero-rating { justify-self: end; }
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
}
.hero-actions .btn { flex: 1 1 13rem; }
/* Content width once the actions and the rating share a row. Left at
   `flex: 1 1 13rem` the pair sat in an auto-sized grid track and wrapped into
   a stacked column at 1280px, which is the phone layout arriving on a desktop
   for no reason.
   THIS BLOCK HAS TO SIT AFTER THE RULE IT OVERRIDES. Both selectors are
   (0,2,0), and a media query adds nothing to specificity, so written above the
   base rule it lost the cascade in every viewport and the buttons stayed
   stacked. Verified by reading the computed flex value back out of the
   browser rather than by assuming the override took. */
@media (min-width: 760px) {
  .hero-actions .btn { flex: 0 0 auto; }
}

.hero-rating {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  font-size: 0.95rem;
  color: var(--muted);
}
.hero-rating b {
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.stars {
  color: var(--accent);
  letter-spacing: 0.12em;
  font-size: 0.95rem;
}

/* ---------- Section frame ---------- */

.sec { padding-block: clamp(3.5rem, 9vw, 6.5rem); }
.sec-alt { background: var(--bg-2); }

.sec-head { max-width: 46ch; margin-bottom: clamp(2rem, 4vw, 3rem); }
.sec-head h2 {
  font-size: clamp(1.9rem, 5.5vw, 3rem);
  margin-bottom: 0.85rem;
}
.sec-head p { color: var(--muted); font-size: 1.03rem; }

/* ---------- The week ----------
   LAYOUT FAMILY 2, and the spine of the page. Every day differs and the
   shop runs late, so the week is drawn rather than listed: each day is a
   bar on a shared 10:00 to 22:30 scale and the late finishes are visible
   at a glance. The times are real text in every row, so the chart is never
   the only way to read the information and nothing is conveyed by colour
   or by bar length alone. */

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

.wk {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 0.35rem 1rem;
  padding: 0.85rem 1rem;
  border-radius: var(--r-md);
  background: var(--bg-2);
  border: 1px solid var(--line);
}
.sec-alt .wk { background: var(--bg); }

.wk-day {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
/* Time and the late marker share ONE grid cell. If the marker had a column of
   its own, rows that carry it would hand a narrower 1fr to the bar track and
   the seven bars would stop sharing a scale, which is the entire point of the
   chart. */
.wk-when {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
  justify-self: end;
}
.wk-time {
  font-variant-numeric: tabular-nums;
  font-size: 0.98rem;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
}
.wk-track {
  grid-column: 1 / -1;
  position: relative;
  height: 10px;
  border-radius: var(--r-pill);
  background: rgba(250, 247, 242, 0.12);
  overflow: hidden;
}
.wk-bar {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--from);
  right: calc(100% - var(--to));
  border-radius: var(--r-pill);
  background: var(--accent);
}

/* Closed day: stated in words first, then de-emphasised. */
.wk.is-closed { border-style: dashed; }
.wk.is-closed .wk-day,
.wk.is-closed .wk-time { color: var(--muted); font-weight: 600; }
.wk.is-closed .wk-track { display: none; }

/* The three late finishes carry a word, not just a longer bar. */
.wk-late {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--accent-ink);
  background: var(--accent);
  border-radius: var(--r-pill);
  padding: 0.15rem 0.65rem;
}

/* The scale the bars are drawn on. aria-hidden: every row already states its
   own hours in words, so this is a reading aid and not information. */
.wk-axis {
  --ax-l: 1rem;    /* left edge of the bar track, so the ticks line up with it */
  --ax-r: 1rem;
  position: relative;
  height: 1.6rem;
  margin-top: 0.35rem;
  font-size: 0.75rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.wk-axis span {
  position: absolute;
  top: 0;
  left: calc(var(--ax-l) + (100% - var(--ax-l) - var(--ax-r)) * var(--at));
  transform: translateX(-50%);
  white-space: nowrap;
}

@media (min-width: 860px) {
  .wk {
    grid-template-columns: 7.5rem 15.5rem 1fr;
    gap: 0 1.25rem;
    padding: 0.95rem 1.4rem;
  }
  .wk-track { grid-column: auto; }
  /* Left-aligned on the wide layout so every row's opening time starts at the
     same x. Right-aligned, the three rows carrying a late marker pushed their
     times out of line with the other four and the column stopped reading as a
     column. */
  .wk-when { flex-direction: row; align-items: center; gap: 0.65rem; justify-self: start; }
  /* Hidden rather than removed, so Sunday still occupies its row and the six
     bars above it keep their alignment. */
  .wk.is-closed .wk-track { display: block; visibility: hidden; }
  .wk-axis { --ax-l: calc(7.5rem + 15.5rem + 2.5rem + 1.4rem); --ax-r: 1.4rem; }
}

.week-note {
  margin-top: 1.4rem;
  color: var(--muted);
  font-size: 0.95rem;
  max-width: 60ch;
}

/* The wide photograph band that used to close this section is gone. There is
   no night shot of this shop in any public source and there is no prospect of
   one, so the band was a permanent empty letterbox under the one chart the
   page is built around. The week strip closes the section on its own. */

/* ---------- Family ----------
   LAYOUT FAMILY 3: one centred column, the quotation set large.

   This was text beside a photograph slot for the children's play corner. That
   photograph does not exist publicly, and the one interior frame that does
   exist must not be dropped in here: under a headline about children, any
   photograph reads as evidence for the headline, and this one is evidence of
   nothing but a room. The claim was always the customer's words, so the
   customer's words are now the whole section and they are set at the size
   that says so. Centred, which no other section on this page is, so the
   change of rhythm is doing the work the missing image used to do. */

.family-in {
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}
.family-in h2 {
  font-size: clamp(1.9rem, 5.5vw, 3rem);
  margin-bottom: clamp(1.75rem, 4vw, 2.5rem);
  text-wrap: balance;
}

.pull { margin: 0; }
.pull p {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1.05rem + 1.5vw, 2.1rem);
  font-weight: 600;
  line-height: 1.32;
  letter-spacing: -0.025em;
}
.pull footer {
  margin-top: 1.1rem;
  font-size: 0.9rem;
  color: var(--muted);
}
.pull footer b { color: var(--text); font-weight: 700; }

/* A rule rather than a gap, so the supporting sentences read as a footnote to
   the quotation instead of as a second, competing statement. */
.family-note {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  padding-top: clamp(1.75rem, 4vw, 2.5rem);
  border-top: 1px solid var(--line);
  color: var(--muted);
  max-width: 52ch;
  margin-inline: auto;
}

/* ---------- Reviews ----------
   LAYOUT FAMILY 4: a rating block and a wall of quote cards of unequal
   length. With one photograph on the whole page, these and the rating are
   what carry its credibility, so they get the space.
   The quotes are shown in the language they were written in, on all three
   pages. Translating a person's review puts words in their mouth. */

.rating {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem 1.1rem;
  padding: 1.4rem 0 1.8rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}
.rating-num {
  font-family: var(--font-display);
  font-size: clamp(3.2rem, 12vw, 5rem);
  font-weight: 700;
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: var(--accent);   /* display size: clears the 3:1 large-text bar */
  font-variant-numeric: tabular-nums;
}
.rating-meta { color: var(--muted); font-size: 0.98rem; }
.rating-meta b { display: block; color: var(--text); font-size: 1.05rem; }

.reviews {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.9rem;
}
@media (min-width: 700px) { .reviews { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .reviews { grid-template-columns: repeat(3, 1fr); } }

.quote {
  margin: 0;
  padding: 1.5rem 1.5rem 1.3rem;
  border-radius: var(--r-md);
  background: var(--bg-2);
  border: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}
.sec-alt .quote { background: var(--bg); }
/* The first card is the longest quote; on a wide grid it gets the room. */
@media (min-width: 1040px) {
  .quote:first-child { grid-column: span 2; }
  .quote:first-child blockquote p { font-size: 1.2rem; }
}
.quote blockquote { margin: 0; }
.quote blockquote p {
  font-size: 1.04rem;
  line-height: 1.65;
}
.quote figcaption {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.88rem;
  color: var(--muted);
}
.quote figcaption b {
  color: var(--text);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
}
.quote figcaption i {
  font-style: normal;
  color: var(--accent);
  letter-spacing: 0.1em;
}

.reviews-note {
  margin-top: 1.5rem;
  font-size: 0.92rem;
  color: var(--muted);
  max-width: 62ch;
}

/* ---------- Prices ----------
   LAYOUT FAMILY 5: one wide bordered panel and nothing else. There is no
   published price list for this shop anywhere, and the single figure that
   exists is a customer's four-year-old recollection, so no euro figure
   appears on this page in any language. The panel says so plainly. */

.note-panel {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.4rem;
  padding: clamp(1.6rem, 4vw, 2.6rem);
  border-radius: var(--r-lg);
  border: 1px solid var(--line-strong);
  border-left: 4px solid var(--accent);
  background: var(--bg-2);
}
.sec-alt .note-panel { background: var(--bg); }
@media (min-width: 860px) {
  .note-panel { grid-template-columns: 1fr 1fr; gap: 2.5rem; align-items: start; }
}
.note-panel h2 { font-size: clamp(1.7rem, 4.5vw, 2.4rem); }
.note-panel p { color: var(--muted); margin-top: 0.9rem; }
/* Unscoped on purpose: the same telephone link appears in the prices panel and
   beside the booking form, and scoping this to .note-panel left the second one
   as a 19px tap target. */
.panel-tel {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 48px;
  margin-top: 0.6rem;
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
  font-variant-numeric: tabular-nums;
}

/* ---------- Booking ----------
   LAYOUT FAMILY 6. The submit button books through the website; WhatsApp
   sits beside it and never in front of it. booking.css owns .book-actions
   and the result panel. */

.book-in {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 5vw, 3.5rem);
}
@media (min-width: 960px) {
  .book-in { grid-template-columns: 0.75fr 1.25fr; }
}

.book-aside p { color: var(--muted); margin-top: 0.9rem; }
.book-aside .panel-tel { color: var(--text); }

.form {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  border-radius: var(--r-lg);
}
@media (min-width: 620px) {
  .form { grid-template-columns: 1fr 1fr; }
  .form .full { grid-column: 1 / -1; }
}

.field { display: flex; flex-direction: column; gap: 0.4rem; border-radius: var(--r-sm); }
.field label {
  font-size: 0.88rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--text);
}
.field input,
.field select,
.field textarea {
  font: inherit;
  font-size: 1rem;
  min-height: 50px;
  padding: 0.7rem 0.9rem;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  background: var(--bg-3);
  color: var(--text);
  width: 100%;
  min-width: 0;
}
.field textarea { min-height: 5rem; border-radius: var(--r-sm); }
/* The native select keeps its own caret. Stripping it with appearance:none
   left three fields that looked like read-only text boxes, and nothing here
   is worth hand-drawing a chevron for. color-scheme: dark on :root is what
   makes the native caret and the date picker render light on this ground. */
.field select { padding-right: 0.5rem; }
.field .hint { font-size: 0.82rem; color: var(--muted); }
/* The two in-sentence links on this page are given a real 44px box rather than
   left at their 16px text height. They wrap onto their own line when they have
   to, which is the right trade: this form is filled in one-handed. */
.field .hint a,
.info-list .sub a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.field .field-msg { margin: 0.15rem 0 0; }

.form-error, .form-ok {
  grid-column: 1 / -1;
  display: none;
  margin: 0;
  padding: 0.85rem 1rem;
  border-radius: var(--r-sm);
  font-size: 0.97rem;
  line-height: 1.6;
}
.form-error.show, .form-ok.show { display: block; }
.form-error {
  color: var(--bad);
  border: 1px solid var(--bad);
  background: rgba(255, 158, 141, 0.08);
}
.form-error a { color: var(--bad); font-weight: 700; }
.form-ok {
  color: var(--text);
  border: 1px solid var(--line-strong);
  background: rgba(250, 247, 242, 0.06);
}

.book-result { border-radius: var(--r-lg); }
.book-result .book-ref { border-radius: var(--r-sm); }
/* booking.css sets this link in the accent, at 1.15rem bold. That is a
   whisker under the 18.67px bold that would let 3.44:1 count as large text,
   so the label is set in ink and the accent moves to the underline, where
   3:1 is the bar that applies. An id selector, because booking.css loads
   after this file. */
#book-result .tel-row a {
  color: var(--text);
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}

/* ---------- Visit ----------
   LAYOUT FAMILY 7: a contact list beside the one photograph on the page.
   Every contact element here has a label that still reads correctly when
   site.js removes its href, because an unconfirmed detail must not become a
   dead link. */

.visit-in {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}
/* The photograph column is the wider of the two. One image on a page has to
   be given room or it reads as an afterthought, and this is the section where
   an interior belongs: the reader is deciding whether to walk over. */
@media (min-width: 900px) { .visit-in { grid-template-columns: 1fr 1.1fr; } }

.info-list { display: grid; gap: 0.15rem; }
.info-list > li {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.15rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--line);
}
.info-list .k {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}
.info-list .v {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 44px;
  font-size: 1.08rem;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  overflow-wrap: break-word;
}
.info-list a.v {
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
}
.info-list a.v:hover { text-decoration-color: var(--text); }
/* Once site.js strips the href it is no longer a link, so it must stop
   dressing like one. */
.info-list a.v:not([href]) {
  text-decoration: none;
  color: var(--muted);
  cursor: default;
}
.info-list .sub { font-size: 0.88rem; color: var(--muted); }

/* THE ONE PHOTOGRAPH.
   4:3 because that is the native shape of the file (1600x1200) and cropping
   the only image on the page to fit a layout would be backwards. media.css
   gives .m-figure its overflow, object-fit and the min-width: 0 that stops an
   img carrying width="1600" from blowing the grid column open on a phone;
   what is set here is the frame around it.
   The border is a real edge rather than decoration: on a dark ground a
   photograph whose own corners are dark otherwise bleeds into the page. */
.visit-photo {
  margin: 0;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--line);
}
/* Centred in its column rather than top-aligned. The contact list runs to
   about 690px and a 4:3 frame in this column is about 396px, so aligned to
   the top the photograph left roughly 290px of empty ground beneath it and
   the section read as though something further had failed to load. Stretching
   it instead would mean cropping a landscape interior to a tall portrait,
   which is not a trade worth making for the only image on the page. */
@media (min-width: 900px) { .visit-photo { align-self: center; } }

/* ---------- Footer ---------- */

.site-foot {
  border-top: 1px solid var(--line);
  padding-block: clamp(2.5rem, 5vw, 3.5rem);
  font-size: 0.9rem;
  color: var(--muted);
}
.foot-in { display: grid; gap: 1.6rem; }
@media (min-width: 800px) { .foot-in { grid-template-columns: 1.3fr 1fr; gap: 3rem; } }
.foot-name {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.02em;
}
.own-words { margin-top: 0.5rem; }
.own-words q { font-style: normal; color: var(--text); }
.foot-notes li {
  position: relative;
  padding: 0.3rem 0 0.3rem 1.1rem;
}
/* A round bullet, not a rule. The first version drew a 14px coral hairline,
   which at footer size read on screen as an em-dash: exactly the tell this
   project bans, arriving through CSS instead of through a character. */
.foot-notes li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.95em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

/* ---------- 360px guard ----------
   Declared rather than assumed. Every multi-column block above collapses at
   a min-width breakpoint, so the base state is already single column; this
   just takes the pressure off the largest type. */
@media (max-width: 400px) {
  .rating-num { font-size: 3.1rem; }
  .btn { padding-inline: 1.1rem; }
  .wk-time { font-size: 0.94rem; }
  /* MEASURED at 390px: the Spanish rating line ends 1px short of the content
     edge and the Catalan one ("93 ressenyes a Google") is two characters
     longer, so it wrapped and left "4,9" stranded on a line of its own. The
     three pages have to hold the same shape, and at 360px all three would
     wrap, so the line steps down here rather than in one language. */
  .hero-rating { font-size: 0.88rem; gap: 0.5rem; }
  .hero-rating b { font-size: 1.08rem; }
}
