/* =============================================================================
   CAVALLINO V2 · BASE + LAYOUT PRIMITIVES
   Reset, typography application, focus, landmarks, width roles, grid and the
   media-composition rules every later page shares.
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  /* No global smooth scrolling: scroll behaviour belongs to the visitor. */
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--on-ground);
  font-family: var(--font-text);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: var(--lh-body);
  overflow-wrap: break-word;
  /* No horizontal clip. A clip would hide an overflow rather than prevent one,
     and would silently make content unreachable instead of failing loudly in
     validation. Compositions are sized so the overflow never occurs. */
}

/* Every surface that declares a mode paints its own ground. */
[data-mode] { background: var(--ground); color: var(--on-ground); }

img, picture, video { display: block; max-width: 100%; }
img { height: auto; border: 0; }

/* Figures carry no default browser margin: media width is a layout decision. */
figure { margin: 0; }
hr { border: 0; }

a { color: inherit; }

button, input, select, textarea { font: inherit; color: inherit; }

/* ------------------------------------------------------------------- focus */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--bd-state) solid var(--accent-text);
  outline-offset: 3px;
}
[data-mode="espresso"] :focus-visible { outline-color: var(--brass-bright); }

::selection { background: var(--brass); color: var(--ink); }

/* --------------------------------------------------------------- utilities */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: var(--s4); top: -120px; z-index: 90;
  background: var(--espresso-800); color: var(--ivory);
  padding: var(--s3) var(--s5);
  font-size: var(--fs-small); font-weight: 500;
  text-decoration: none; border-radius: var(--r-ctl);
  transition: top var(--dur-1) var(--ease);
}
.skip:focus { top: var(--s4); }

/* =============================================================================
   TYPOGRAPHY
   Cormorant Garamond carries display. Jost carries everything spoken.
   ========================================================================== */

.display {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
  /* A long German compound must never be clipped by a narrow viewport. */
  overflow-wrap: break-word;
  hyphens: auto;
}

.h1, .h2, .h3 { margin: 0; font-family: var(--font-display); font-weight: 500; }
.h1 { font-size: var(--fs-h1); line-height: var(--lh-title); letter-spacing: var(--tr-display); }
.h2 { font-size: var(--fs-h2); line-height: var(--lh-title); }
.h3 { font-size: var(--fs-h3); line-height: 1.2; }

.lead {
  margin: 0;
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  max-width: var(--w-narrow);
}

.body { margin: 0; max-width: var(--w-text); }
.body + .body { margin-top: var(--s4); }

.muted { color: var(--on-ground-muted); }

/* The single tracked role in the system: small field and section labels.
   Tracked capitals are never used as decorative eyebrows on headings. */
.label {
  font-size: var(--fs-label);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--on-ground-muted);
}

/* A quiet, sentence-case marker for place or context. Not an eyebrow label. */
.marker {
  margin: 0;
  font-size: var(--fs-small);
  font-weight: 400;
  line-height: 1.4;
  color: var(--on-ground-muted);
}

/* =============================================================================
   WIDTH ROLES
   A component chooses the role that suits its job. There is deliberately no
   single mechanical shell applied to everything.
   ========================================================================== */

.shell { width: 100%; padding-inline: var(--gutter); margin-inline: auto; }
.shell--wide { max-width: calc(var(--w-wide) + var(--gutter) * 2); }
.shell--band { max-width: calc(var(--w-band) + var(--gutter) * 2); }
.shell--flush { padding-inline: 0; }

/* The framed editorial width: photographs and words sit inside the gutters,
   never against the viewport edge. */
:root { --w-frame: 1400px; }
.shell--frame { max-width: calc(var(--w-frame) + var(--gutter) * 2); }

.measure { max-width: var(--w-text); }
.measure--narrow { max-width: var(--w-narrow); }

/* ------------------------------------------------------------------- grid */
.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: clamp(16px, 2vw, 40px);
}

/* =============================================================================
   MEDIA COMPOSITION RULES
   Shared by every later page. A photograph is sized by an intentional ratio
   AND capped against the viewport so no composition demands a fight with the
   scroll position.
   ========================================================================== */

.media { position: relative; overflow: hidden; background: var(--ground-sunken); }
.media > img { width: 100%; height: 100%; object-fit: cover; }

/* Ratio roles */
.media--wide    { aspect-ratio: 16 / 9; }
.media--panorama{ aspect-ratio: 21 / 9; }
.media--classic { aspect-ratio: 3 / 2; }
.media--upright { aspect-ratio: 4 / 5; }

/* Viewport budget: chrome and breathing room are removed before a photograph
   is allowed to claim height. Calibrated per component, never global. */
.media--cap { max-height: calc(100svh - var(--cap-reserve, 220px)); }

/* A photograph never carries a mat, ring, frame or decorative shadow. */
.media > img { border: 0; box-shadow: none; }

/* Artwork is not photography: it sits on the ground at its own scale and is
   never cropped, tilted or distorted. */
.artwork { display: block; width: auto; height: auto; background: none; border: 0; }

/* =============================================================================
   ACTIONS
   One accent. Square-ish, confident, generous targets.
   ========================================================================== */

.action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 52px;
  padding: 0 var(--s6);
  border: var(--bd-hair) solid transparent;
  border-radius: var(--r-ctl);
  background: transparent;
  color: var(--on-ground);
  font-family: var(--font-text);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease);
}

/* The house action: brass ground, warm near-black label. */
.action--primary {
  background: var(--accent);
  color: var(--accent-on);
  border-color: var(--brass-deep);
  font-weight: 600;
}
.action--primary:hover { background: var(--brass-bright); }

.action--quiet { border-color: var(--rule); color: var(--on-ground); }
.action--quiet:hover { border-color: var(--on-ground); }

/* =============================================================================
   FIELDS
   Truthful native inputs. No invented options, no implied policy.
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--s2); min-width: 0; }

.field > input {
  width: 100%;
  min-height: 52px;
  padding: 0 var(--s4);
  border: var(--bd-hair) solid var(--field-bd);
  border-radius: var(--r-ctl);
  background: var(--field-bg);
  color: var(--on-ground);
  font-size: 1rem;
  line-height: 1.3;
}
.field > input:focus-visible { border-color: var(--accent-text); }

/* =============================================================================
   SHARED CHROME
   Masthead, navigation, language and persistent reservation access, shared by
   every page. The styling is provisional; the behaviour is not.

   One stable height per breakpoint. The scrolled state changes the surface
   only, never the height, so sticking can never shift the page.
   ========================================================================== */

:root { --masthead-h: 64px; }

/* In-page targets land below the sticky masthead, not underneath it. */
html { scroll-padding-top: var(--masthead-h); }

.masthead {
  position: relative;
  z-index: 40;
  background: var(--brand-ground);
  color: var(--ivory);
  /* The hairline is painted inside the bar, so it never adds to the height. */
  box-shadow: inset 0 calc(-1 * var(--bd-hair)) 0 rgba(247, 242, 231, 0.10);
  transition: box-shadow var(--dur-2) var(--ease);
}

/* Scrolled: a brass hairline separates the masthead from what passes beneath. */
.masthead.is-scrolled { box-shadow: inset 0 calc(-1 * var(--bd-hair)) 0 rgba(176, 141, 87, 0.62); }

/* Controls on the identity ground take the bright focus colour. */
.masthead :focus-visible { outline-color: var(--brass-bright); }

/* A control whose script is unavailable is removed, never left inert. */
.masthead [hidden] { display: none !important; }

.masthead__bar {
  display: flex;
  align-items: center;
  gap: var(--s3) var(--s5);
  min-height: var(--masthead-h);
}

/* Identity: the crest master, mechanically cropped and downscaled only. The
   artwork carries its own ground; the band matches it exactly. */
.masthead__mark {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  margin-right: auto;
  text-decoration: none;
}
.masthead__mark img {
  width: auto;
  height: clamp(40px, 3.4vw, 52px);
  background: none;
}
.masthead__wordmark {
  display: none;
  margin-left: var(--s4);
  padding-left: var(--s4);
  border-left: var(--bd-hair) solid rgba(247, 242, 231, 0.22);
  font-size: var(--fs-small);
  line-height: 1.25;
  color: rgba(247, 242, 231, 0.86);
}
.masthead__wordmark b { display: block; font-weight: 500; letter-spacing: 0.02em; }

.masthead__reserve { min-height: 44px; padding-inline: var(--s5); }

/* The menu toggle exists only where scripting can operate it. */
.masthead__toggle {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 var(--s4);
  border: var(--bd-hair) solid rgba(247, 242, 231, 0.34);
  border-radius: var(--r-ctl);
  background: transparent;
  color: var(--ivory);
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease);
}
.masthead__toggle:hover,
.masthead__toggle[aria-expanded="true"] { border-color: var(--brass-bright); }

.masthead__menu { display: flex; align-items: center; gap: var(--s5); }

/* Real destinations are links; a destination whose page is not built yet
   stays a quiet label, deliberately not styled as a link. */
.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--s5);
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-nav__item {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--fs-small);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: rgba(247, 242, 231, 0.66);
  cursor: default;
}
a.site-nav__item {
  color: rgba(247, 242, 231, 0.9);
  text-decoration: none;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
a.site-nav__item:hover { color: var(--ivory); }
a.site-nav__item[aria-current="page"] { color: var(--brass-bright); }

/* Language: present only where scripting can switch it in place. */
.lang { display: none; align-items: center; gap: var(--s1); }
.has-js .lang { display: inline-flex; }
.lang__option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 var(--s2);
  border: var(--bd-hair) solid transparent;
  border-radius: var(--r-ctl);
  background: transparent;
  color: rgba(247, 242, 231, 0.72);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.lang__option:hover { color: var(--ivory); }
.lang__option[aria-pressed="true"] { color: var(--ivory); border-color: rgba(214, 188, 140, 0.6); }

/* --- Below desktop: compact sticky bar, menu behind a named toggle -------- */
@media (max-width: 1023.98px) {
  /* Without scripting the menu is simply a second row, and the masthead
     scrolls away with the page instead of permanently claiming height. */
  .masthead__bar { flex-wrap: wrap; }
  .masthead__menu { flex-basis: 100%; padding-bottom: var(--s2); }

  .has-js .masthead { position: sticky; top: 0; }
  .has-js .masthead__toggle { display: inline-flex; }

  /* The panel overlays the page below the bar: it never pushes content, and
     the page keeps scrolling normally while it is open. */
  .has-js .masthead__menu {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s5);
    max-height: calc(100svh - var(--masthead-h));
    overflow-y: auto;
    padding: var(--s3) var(--gutter) var(--s6);
    background: var(--brand-ground);
    border-bottom: var(--bd-hair) solid rgba(176, 141, 87, 0.62);
  }
  .has-js .masthead__menu.is-open { display: flex; }
  .has-js .site-nav { align-self: stretch; }
  .has-js .site-nav__list { flex-direction: column; gap: 0; }
  .has-js .site-nav__item {
    width: 100%;
    min-height: 52px;
    font-size: var(--fs-body);
    border-bottom: var(--bd-hair) solid rgba(247, 242, 231, 0.10);
  }
}

/* --- Desktop: sticky masthead, inline navigation, reservation top right --- */
@media (min-width: 1024px) {
  :root { --masthead-h: 76px; }

  .masthead { position: sticky; top: 0; }
  .masthead__wordmark { display: block; }
  /* Last in the row, after navigation and language. */
  .masthead__reserve { order: 1; margin-left: var(--s2); }
  .masthead__menu { gap: var(--s6); }
  .site-nav__list { gap: 0 var(--s6); }
  a.site-nav__item:hover { box-shadow: inset 0 -1px 0 rgba(214, 188, 140, 0.6); }
  a.site-nav__item[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--brass-bright); }
  .lang {
    padding-left: var(--s5);
    border-left: var(--bd-hair) solid rgba(247, 242, 231, 0.22);
  }
}

/* --- Small phones: identity, reservation and menu on one line ------------ */
@media (max-width: 560px) {
  .masthead__bar { gap: var(--s3); }
  .masthead__mark img { height: 36px; }
  .masthead__reserve {
    padding-inline: var(--s4);
    font-size: var(--fs-label);
    letter-spacing: 0.03em;
  }
  .masthead__toggle { padding-inline: var(--s3); }
}

/* =============================================================================
   SHARED FOOTER
   On the crest's measured ground, so the opaque crest integrates with no
   plaque. An invitation, then identity, visit, routes and language. Future
   routes stay plain text until their pages exist.
   ========================================================================== */

.site-footer {
  background: var(--brand-ground);
  color: var(--ivory);
  padding-block: clamp(var(--s6), 4vw, var(--s8)) var(--s5);
}
.site-footer :focus-visible { outline-color: var(--brass-bright); }
.site-footer [hidden] { display: none !important; }

.site-footer__invite {
  display: grid;
  gap: var(--s5) var(--s7);
  padding-bottom: clamp(var(--s5), 3vw, var(--s7));
}
.site-footer__title {
  margin: 0;
  max-width: 16ch;
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 5.4vw, 4.6rem);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: var(--tr-display);
  text-wrap: balance;
}
.site-footer__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s4);
}
.site-footer__phone {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 500;
  color: var(--ivory);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(214, 188, 140, 0.6);
  text-underline-offset: 0.22em;
}
.site-footer__phone:hover { text-decoration-color: var(--brass-bright); }

.site-footer__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5) var(--s6);
  padding-block: clamp(var(--s5), 3vw, var(--s6));
  border-top: var(--bd-hair) solid rgba(247, 242, 231, 0.14);
}
.site-footer__brand { grid-column: 1 / -1; }
.site-footer__brand img { width: auto; height: 64px; }
.site-footer__name { margin: var(--s4) 0 0; font-size: var(--fs-small); color: rgba(247, 242, 231, 0.86); }
.site-footer__family { margin: var(--s2) 0 0; font-size: var(--fs-small); color: rgba(247, 242, 231, 0.66); }
@media (min-width: 760px) { .site-footer__family { white-space: nowrap; } }
/* The sister house, one click away. */
.site-footer__hotel {
  display: inline-block;
  margin-top: var(--s3);
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 500;
  color: var(--brass-bright);
  text-underline-offset: 3px;
}
.site-footer__hotel:hover { color: var(--ivory); }

.site-footer__label {
  margin: 0 0 var(--s3);
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--brass-bright);
}
.site-footer__address { font-style: normal; line-height: 1.5; }

.site-footer__list { display: grid; gap: var(--s1); margin: 0; padding: 0; list-style: none; }
.site-footer__link,
.site-footer__route {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  font-size: var(--fs-small);
}
.site-footer__link {
  color: var(--ivory);
  text-decoration: underline;
  text-decoration-color: rgba(247, 242, 231, 0.3);
  text-underline-offset: 0.22em;
}
.site-footer__link:hover { text-decoration-color: var(--brass-bright); }
.site-footer__link[aria-current="page"] { color: var(--brass-bright); text-decoration: none; }
.site-footer__route { color: rgba(247, 242, 231, 0.6); cursor: default; }

/* A route marker whose page exists is a real link (home.css sets its rule). */
a.route-mark {
  display: inline-flex;
  color: var(--on-ground);
  text-decoration: none;
  cursor: pointer;
}
a.route-mark:hover { text-decoration: underline; text-underline-offset: 0.22em; }

/* Language needs scripting; without it the column is absent, not inert. */
.site-footer__lang { display: none; }
.has-js .site-footer__lang { display: block; }
.site-footer .lang { padding-left: 0; border-left: 0; margin-left: calc(-1 * var(--s2)); }

.site-footer__base {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3) var(--s5);
  padding-top: var(--s4);
  border-top: var(--bd-hair) solid rgba(247, 242, 231, 0.14);
  font-size: var(--fs-label);
  color: rgba(247, 242, 231, 0.6);
}
.site-footer__base p { margin: 0; }
/* Credit after a thin vertical line; on its own line on narrow phones. */
.site-footer__credit {
  margin-left: var(--s3);
  padding-left: var(--s3);
  border-left: var(--bd-hair) solid rgba(247, 242, 231, 0.3);
}
@media (max-width: 480px) {
  .site-footer__credit { display: block; margin: var(--s2) 0 0; padding: 0; border: 0; }
}

@media (min-width: 760px) {
  .site-footer__grid { grid-template-columns: minmax(0, 2fr) repeat(2, minmax(0, 1fr)); }
  .site-footer__brand { grid-column: auto; }
}
@media (min-width: 1280px) {
  .site-footer__invite { grid-template-columns: minmax(0, 1fr) auto; align-items: end; }
}

/* =============================================================================
   BACK TO TOP
   A plain in-page link that works without scripting. With scripting it
   floats bottom-right and appears after about one viewport; hidden, it is
   also out of the tab order.
   ========================================================================== */

.to-top {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;
  color: rgba(247, 242, 231, 0.8);
  font-size: var(--fs-label);
  text-decoration: none;
}
.to-top:focus-visible { outline: var(--bd-state) solid var(--brass-bright); outline-offset: 3px; }

.has-js .to-top {
  position: fixed;
  right: var(--s4);
  bottom: var(--s5);
  z-index: 35;
  justify-content: center;
  width: 48px;
  height: 48px;
  min-height: 0;
  background: var(--espresso-800);
  color: var(--brass-bright);
  border: var(--bd-hair) solid rgba(214, 188, 140, 0.55);
  border-radius: var(--r-ctl);
  font-size: 1.15rem;
  opacity: 0;
  visibility: hidden;
  translate: 0 8px;
  transition: opacity var(--dur-2) var(--ease), translate var(--dur-2) var(--ease), visibility 0s linear var(--dur-2);
}
.has-js .to-top.is-visible {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
  transition: opacity var(--dur-2) var(--ease), translate var(--dur-2) var(--ease), visibility 0s;
}
.has-js .to-top:hover { border-color: var(--brass-bright); }
.has-js .to-top__text {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* =============================================================================
   MOTION SAFETY
   Content is fully visible with no JavaScript and under reduced motion.
   Nothing in this project hides content awaiting an observer.
   ========================================================================== */

@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;
  }
}

/* E-Mail-Adresse neben der Telefonnummer: lange Adresse darf umbrechen */
.site-footer__email { overflow-wrap: anywhere; }

/* Five navigation entries: tighter spacing where the desktop header is narrowest. */
@media (min-width: 1024px) and (max-width: 1439.98px) {
  .masthead__wordmark { display: none; }
  .masthead__menu { gap: var(--s4); }
  .site-nav__list { gap: 0 var(--s4); }
}
