/* Design tokens. Every colour and font in a skin must reference one of these.
   Raw hex or a bare font-family in a skin stylesheet fails `ewm.py check`. */
:root {
  /* ---- colour, OKLCH, anchored to a hue pulled from the client's photography ---- */
  --hue: 255;
  --hue-accent: 260;

  --paper:    oklch(97% 0.010 var(--hue));
  --paper-2:  oklch(94% 0.014 var(--hue));
  --paper-3:  oklch(90% 0.018 var(--hue));
  --rule:     oklch(84% 0.012 var(--hue));
  --neutral:  oklch(58% 0.010 var(--hue));
  --muted:    oklch(44% 0.010 var(--hue));
  --ink:      oklch(20% 0.012 var(--hue));
  --ink-soft: oklch(32% 0.012 var(--hue));

  /* Lightness and chroma are their own custom properties so a live style picker
     can change how vivid the accent is, not only its hue. */
  --accent-l:      52%;
  --accent-l-deep: 38%;
  --accent-c:      0.2;

  --accent:      oklch(var(--accent-l) var(--accent-c) var(--hue-accent));
  --accent-deep: oklch(var(--accent-l-deep) var(--accent-c) var(--hue-accent));
  --accent-wash: oklch(94% 0.030 var(--hue-accent));
  --focus:       oklch(55% 0.19 var(--hue-accent));

  /* ---- type ---- */
  --font-display: 'Inter', system-ui, sans-serif;
  --font-body: 'Inter', system-ui, sans-serif;
  --heading-weight: 700;
  --ratio: 1.5;

  --step--1: clamp(0.86rem, 0.83rem + 0.15vw, 0.94rem);
  --step-0:  clamp(1.05rem, 1.00rem + 0.25vw, 1.19rem);
  --step-1:  clamp(1.31rem, 1.20rem + 0.55vw, 1.66rem);
  --step-2:  clamp(1.64rem, 1.42rem + 1.10vw, 2.33rem);
  --step-3:  clamp(2.05rem, 1.65rem + 2.00vw, 3.26rem);
  --step-4:  clamp(2.56rem, 1.87rem + 3.45vw, 4.56rem);
  --step-5:  clamp(3.20rem, 2.02rem + 5.90vw, 6.39rem);

  --lh-display: 1.02;
  --lh-title: 1.12;
  --lh-body: 1.62;
  --track-display: -0.032em;
  --track-title: -0.018em;
  --measure: 62ch;

  /* ---- space, 4pt base, role named ---- */
  --space-3xs: 0.125rem; --space-2xs: 0.25rem; --space-xs: 0.5rem;
  --space-sm: 0.75rem;   --space-md: 1rem;     --space-lg: 1.5rem;
  --space-xl: 2.5rem;    --space-2xl: 4rem;    --space-3xl: 6rem;
  --space-4xl: 9rem;

  --gutter: clamp(1.15rem, 4vw, 2.5rem);
  --max: 78rem;
  --radius: 12px;
  --radius-sm: calc(12px / 2.5);

  /* ---- motion ---- */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-micro: 120ms; --dur-short: 220ms; --dur-long: 420ms;

  /* ---- depth: weight and hairlines, not float shadows ---- */
  --hairline: 0 0 0 1px oklch(30% 0.01 var(--hue) / 0.08);
  --lift: 0 1px 2px oklch(20% 0.01 var(--hue) / 0.06);

  /* ---- z ---- */
  --z-base: 1; --z-raised: 10; --z-sticky: 200; --z-modal: 400;
}

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

/* ---- reset ----------------------------------------------------------------
   The legacy styles.css carried the reset, and a skin with its own skin.css
   never loads it. Skins that reset for themselves were fine; the ones that did
   not inherited the browser's 8px body margin, which showed as a pale border
   down both sides of every full bleed hero. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; min-height: 100svh; }
img, svg, video { max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }

/* ---- base typography ------------------------------------------------------
   There was none. Every skin was expected to set its own, so a skin that only
   styled its own components fell back to the browser default and rendered the
   whole site in Times New Roman. skin.css loads after this, so a skin that does
   set its own still wins. */
body { font-family: var(--font-body); color: var(--ink); }
h1, h2, h3, h4, h5, h6 { font-family: var(--font-display); }
button, input, select, textarea { font-family: inherit; }

/* ---- subpages ------------------------------------------------------------
   The page opens with the skin's own hero, so everything below is body content.
   Deliberately restrained: skins override these to speak in their own voice. */
.pg-block { padding-block: var(--space-2xl) var(--space-2xl); }
.pg-block + .pg-block { padding-block-start: 0; }
.pg-block > h2 { font-size: var(--step-2); letter-spacing: -0.015em; max-width: 30ch; }
.pg-lede { margin-block-start: var(--space-md); font-size: var(--step-0); line-height: 1.6;
  color: var(--muted); max-width: 58ch; }
.pg-prose p { margin-block-start: var(--space-sm); max-width: 66ch; line-height: 1.6;
  color: var(--ink-soft); }
.pg-prose strong { color: var(--ink); font-weight: 600; }

/* a ledger, used whenever the items do not all have a photograph. A half filled
   card grid is what made these pages look like a free theme. */
.pg-ledger { list-style: none; margin: var(--space-xl) 0 0; padding: 0;
  border-block-start: 2px solid var(--ink); counter-reset: pg; }
.pg-ledger li { display: grid; grid-template-columns: 2.75rem 1fr; gap: var(--space-md);
  padding-block: var(--space-lg); border-block-end: 1px solid var(--rule); }
@media (min-width: 860px) {
  .pg-ledger li { grid-template-columns: 3.5rem minmax(0, 1fr) auto; gap: var(--space-xl);
    align-items: baseline; }
}
.pg-ledger__n { font-family: var(--font-display); color: var(--muted); font-size: var(--step-0); }
.pg-ledger h3 { font-size: var(--step-1); line-height: 1.25; }
.pg-ledger p { margin-block-start: var(--space-xs); color: var(--muted); line-height: 1.6;
  max-width: 62ch; }
.pg-ledger__m { font-family: var(--font-display); font-size: var(--step-0); white-space: nowrap;
  color: var(--ink); }

/* cards only when every entry has a photograph */
.pg-cards { display: grid; gap: var(--space-xl); margin-block-start: var(--space-xl); }
@media (min-width: 720px) { .pg-cards--2, .pg-cards--3, .pg-cards--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .pg-cards--3 { grid-template-columns: repeat(3, 1fr); }
  .pg-cards--4 { grid-template-columns: repeat(4, 1fr); } }
.pg-card img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius, 8px); margin-block-end: var(--space-md); }
.pg-card h3 { font-size: var(--step-1); line-height: 1.25; }
.pg-card p { margin-block-start: var(--space-xs); color: var(--muted); font-size: var(--step--1);
  line-height: 1.6; }
.pg-meta { margin-block-start: var(--space-sm); font-size: var(--step--1); color: var(--muted); }

.pg-scroll { overflow-x: auto; margin-block-start: var(--space-xl); }
.pg-table { width: 100%; border-collapse: collapse; }
.pg-table th { text-align: start; padding: var(--space-sm) var(--space-lg) var(--space-sm) 0;
  border-block-end: 2px solid var(--ink); font-size: var(--step--1); letter-spacing: 0.1em;
  text-transform: uppercase; white-space: nowrap; }
.pg-table td { padding: var(--space-md) var(--space-lg) var(--space-md) 0;
  border-block-end: 1px solid var(--rule); vertical-align: top; line-height: 1.5; }
.pg-table tr td:last-child { text-align: end; white-space: nowrap;
  font-family: var(--font-display); font-size: var(--step-0); }

.pg-galleryw h2 { margin-block-end: var(--space-lg); }
.pg-gallery { display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.pg-gallery img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; display: block; }

.pg-cta { background: var(--ink); color: var(--paper); border-radius: var(--radius, 10px);
  padding: var(--space-2xl); }
.pg-cta h2 { color: var(--paper); font-size: var(--step-2); max-width: 22ch; }
.pg-cta p { color: color-mix(in oklab, currentColor 84%, transparent); margin-block-start: var(--space-md);
  max-width: 58ch; line-height: 1.6; }
.pg-btn { display: inline-flex; margin-block-start: var(--space-xl); font-weight: 600;
  font-size: var(--step--1); letter-spacing: 0.06em; padding: var(--space-sm) var(--space-xl);
  border: 1px solid var(--paper); background: var(--paper); color: var(--ink); }
.pg-btn:hover { background: transparent; color: var(--paper); }

/* ---- scroll motion ---------------------------------------------------------
   One mechanism, tuned per skin. A calm business gets a long slow rise, a lively
   one gets a shorter springier one. Set --rv-dist to 0 to opt a skin out. */
:root {
  --rv-dist: 16px;
  --rv-dur: 620ms;
  --rv-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --rv-step: 70ms;
  --rv-scale: 1;
}
.js-rv {
  opacity: 0;
  transform: translate3d(0, var(--rv-dist), 0) scale(var(--rv-scale));
  transition: opacity var(--rv-dur) var(--rv-ease),
              transform var(--rv-dur) var(--rv-ease);
  transition-delay: calc(var(--rv-i, 0) * var(--rv-step));
  will-change: opacity, transform;
}
.js-rv.is-in { opacity: 1; transform: none; will-change: auto; }
[data-drift] { transform: translate3d(0, var(--drift, 0), 0); }
@media (prefers-reduced-motion: reduce) {
  .js-rv { opacity: 1; transform: none; transition: none; }
  [data-drift] { transform: none; }
}

/* ---- social links (shared, optional) ---- */
.ewm-social { display: flex; flex-wrap: wrap; gap: var(--space-md);
  list-style: none; margin: 0; padding: 0; }
.ewm-social a { display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem; border-radius: 50%; color: inherit;
  border: 1px solid color-mix(in oklab, currentColor 24%, transparent);
  transition: color .18s ease, border-color .18s ease, background-color .18s ease; }
.ewm-social a:hover { color: var(--accent);
  border-color: color-mix(in oklab, var(--accent) 55%, transparent);
  background: color-mix(in oklab, var(--accent) 10%, transparent); }
.ewm-social svg { display: block; }

/* ---- proof strip (shared, optional, degrades to however few marks exist) ---- */
.ewm-proof { display: flex; flex-wrap: wrap; align-items: center;
  justify-content: center; gap: var(--space-lg) var(--space-2xl);
  padding-block: var(--space-xl); }
.ewm-proof__i { display: inline-flex; align-items: center; gap: var(--space-sm);
  font-size: var(--step--1); letter-spacing: .04em; text-transform: uppercase;
  color: color-mix(in oklab, currentColor 62%, transparent); }
.ewm-proof__i img { height: 2rem; width: auto; opacity: .72; }
.ewm-proof__n { font-family: var(--font-display); font-size: var(--step-2);
  line-height: 1; letter-spacing: 0; text-transform: none; color: inherit; }
.ewm-proof--one { justify-content: flex-start; }
.ewm-social__off { display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem; border-radius: 50%; color: inherit;
  border: 1px solid color-mix(in oklab, currentColor 24%, transparent); }

/* Shared blog (skins without their own blog templates) */
.pg-post__meta { color: var(--muted); font-size: var(--step--1); }
.pg-post__img { margin: var(--space-lg) 0; border-radius: var(--radius, 10px); overflow: hidden; }
.pg-post__img img { display: block; width: 100%; height: auto; }
.pg-post__body { max-width: 68ch; }
.pg-post__body h2 { font-size: var(--step-1); margin-block-start: var(--space-xl); }
.pg-post__body ul, .pg-post__body ol { max-width: 64ch; line-height: 1.6; }
.pg-post .pg-cta { margin-block-start: var(--space-2xl); }
.pg-post__more { margin-block-start: var(--space-xl); }
.pg-post__more p { font-weight: 600; }
.pg-posts { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-lg);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr)); }
.pg-posts a { display: grid; gap: var(--space-2xs); color: inherit; text-decoration: none; }
.pg-posts img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius, 10px); margin-block-end: var(--space-xs); }
.pg-posts strong { font-size: var(--step-1); line-height: 1.25; }
.pg-posts span { color: var(--muted); }
.pg-posts__date { font-size: var(--step--1); }
.pg-posts a:hover strong { text-decoration: underline; text-underline-offset: 3px; }

/* ---- readable text on photo heroes (every skin whose header and hero sit on a photograph) ----
   A photo can be light anywhere, so the text never relies on the photo being dark: a soft shade
   behind the menu, and a shaded panel behind the hero text. Measured by `ewm.py qa`. */
.fq-hero::after, .on-hero::after, .rg-hero::after, .tb-hero::after {
  content: ""; position: absolute; inset: 0 0 auto 0; height: clamp(120px, 22vh, 220px); z-index: -1; pointer-events: none;
  background: linear-gradient(to bottom, oklch(16% 0.02 var(--hue) / 0.62), oklch(16% 0.02 var(--hue) / 0)); }
.fq-hero__in, .on-hero__in, .rg-hero__in, .tb-hero__in { position: relative; text-shadow: 0 1px 3px oklch(10% 0.02 var(--hue) / 0.45); }
/* a soft shade that follows the text, with no edges: it reads as light falling off, not as a box */
.fq-hero__in::before, .on-hero__in::before, .rg-hero__in::before, .tb-hero__in::before {
  content: ""; position: absolute; inset: -38% -26% -32% -34%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, oklch(14% 0.02 var(--hue) / 0.64), oklch(14% 0.02 var(--hue) / 0.56) 62%, oklch(14% 0.02 var(--hue) / 0.22) 85%, transparent); }
/* small lines inside the hero panel (eyebrows, credits) stay readable too */
.fq-hero__in .fq-eyebrow, .rg-hero__credit, .tb-hero__eyebrow, .on-hero__in small { color: oklch(95% 0.01 var(--hue) / 0.92) !important; }


/* ---- facts strip: even columns, no boxes. A short accent line, the fact in the display face,
   one readable line below. Works for figures ("4,9") and for short phrases alike. ---- */
.ewm-proof:has(.ewm-proof__n) { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  gap: var(--space-xl) clamp(1.5rem, 3vw, 3rem); align-items: start; text-align: left; justify-content: stretch;
  padding-block: clamp(2.5rem, 5vw, 4rem); }
.ewm-proof:has(.ewm-proof__n) > .ewm-proof__i { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2xs);
  text-transform: none; letter-spacing: 0; color: var(--ink-soft, var(--ink)); font-size: var(--step-0); line-height: 1.45; }
.ewm-proof:has(.ewm-proof__n) > .ewm-proof__i::before { content: ""; width: 2.25rem; height: 2px; margin-block-end: var(--space-sm);
  background: var(--accent-deep, var(--accent, currentColor)); border-radius: 2px; }
.ewm-proof:has(.ewm-proof__n) .ewm-proof__n, .ewm-proof:has(.ewm-proof__n) > .ewm-proof__i:not(:has(.ewm-proof__n)) > span {
  font-family: var(--font-display); font-size: var(--step-1); line-height: 1.2; color: var(--ink); }

/* long words (German compounds, URLs) hyphenate by the page's language and break as a last resort,
   instead of pushing text out of its box on a narrow phone */
h1, h2, h3, h4, p, li, dd, dt, td, th, blockquote, figcaption, label { overflow-wrap: break-word; hyphens: auto; }

/* A telephone number never breaks across two lines: half a number is not a number, and a visitor
   about to call reads it as a mistake. Shared, because it is true for every client (12 Sep). */
a[href^="tel:"], a[href^="whatsapp:"], a[href*="wa.me/"] { white-space: nowrap; hyphens: manual; }