/*
  Slabowski Hair & Beauty – shared styles for every page (site.css)

  Source of every value: homepage draft 4 (index.html) and 02_Design/Subpages_Design_Guide_2026-09-24.md.
  Visual contract: _patterns.html shows every pattern below once; _template.html is the page skeleton.

  Rules
  - One typeface (the grotesque), black on white, 1 px black lines. No grey, no tints, no shadows,
    no rounded corners, no boxes. Colour comes only from photographs.
  - Pages add their own rules in a small <style> block (or assets/pages/<page>.css) after this file.
    They never redefine a class from this file; they add a page class instead.
  - Typography through .caps (small capitals) and the named text classes; shape and behaviour through
    the pattern class. Example: <a class="caps action">, <a class="caps frame">.
  - One breakpoint: 800 px (the media query at the end of this file).

  Contents
   1 Tokens and resets          6 Footer
   2 Type                       7 Film pause button
   3 Header                     8 Page layout: main, sections, halves
   4 Language picker            9 Patterns: opener, image block, split, grid, section head, hairlines,
   5 Menu                         statement, full image, category line, photo placeholder, chapter, cover,
                                  text column (rounds 2 and 3: 9.11–9.13 and the modifiers marked "round 2/3")
                               10 Phones (max-width 800 px)
                               11 Version 2: the red accent
  Rules marked "consolidation" (2026-09-24) were page rules that two pages kept; they now live here once.
  Usage notes for all of them: 02_Design/Subpage_Briefs_2026-09-24/PATTERNS.md.
*/

/* 1 · Tokens and resets */
/* Geist (SIL Open Font License, assets/fonts/Geist-OFL.txt), served from our own server: the fallback where Helvetica Neue
   is missing – Windows, Android, Linux (Ilja, 2026-09-24). Apple devices have Helvetica Neue, so they never download it.
   Three weights: Light for all text, Regular for small capitals, Bold for the footer titles and the menu's head. */
@font-face { font-family: "Geist"; src: url("fonts/Geist-Light.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: swap; }
/* Version 2: Light Italic for the homepage's positioning sentence (Ilja, 2026-09-26), same package; browsers load it only where italic is used */
@font-face { font-family: "Geist"; src: url("fonts/Geist-LightItalic.woff2") format("woff2"); font-weight: 300; font-style: italic; font-display: swap; }
@font-face { font-family: "Geist"; src: url("fonts/Geist-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Geist"; src: url("fonts/Geist-Bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
:root {
  --black: #000;
  --white: #fff;
  --dark: #0a0a0a;
  --sand: #d9c6ad;              /* only for .photo-placeholder, the stand-in for a missing photo */
  --font: "Helvetica Neue", "Geist", sans-serif;   /* no "Helvetica" or Arial: Windows maps Helvetica to Arial, which has no Light */
  --side: 40px;                 /* side padding of the page (20 px on phones) */
  --header: 88px;               /* header height (64 px on phones) */
  --gap: 16px;                  /* gap between images */
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-padding-top: var(--header); }  /* anchor targets land below the fixed header */
/* Smooth anchor scrolling only for visitors who have not asked their system for reduced motion (WCAG 2.3.3) */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
/* All text in Light (Ilja, 2026-09-24); the hierarchy comes from the sizes. Small capitals (.caps, the menu) stay Regular:
   at 12–13 px with wide spacing, Light capitals get too faint to read. */
body { font-family: var(--font); font-size: 14px; line-height: 21px; font-weight: 300; color: var(--black); background: var(--white); -webkit-font-smoothing: antialiased; }
h1, h2, h3, h4 { font-size: inherit; font-weight: inherit; }
a { color: inherit; text-decoration: none; }
img, video { display: block; }
/* Keyboard focus (round 3): a 1 px line 3 px around the focused element, in its own text colour – black on white,
   white where the text is white (.on-image, captions on photos, the cover, the header over the film).
   Replaces the browser's blue rounded ring. */
:focus-visible { outline: 1px solid currentColor; outline-offset: 3px; }

/* 2 · Type (sizes, weights and case from guide §2) */
.caps { font-size: 12px; line-height: 18px; font-weight: 400; letter-spacing: .08em; text-transform: uppercase; }
/* Text action: always together with .caps, a verb ("Termin buchen", "Mehr erfahren") */
.action { display: inline-block; text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
/* Framed button: always together with .caps. On white: black line, fills black. Over an image: add .on-image */
.frame { display: inline-block; border: 1px solid var(--black); padding: 14px 38px; white-space: nowrap; transition: background-color .25s, color .25s; }
.frame:hover { background: var(--black); color: var(--white); }
.frame.on-image { color: var(--white); border-color: var(--white); }
.frame.on-image:hover { background: var(--white); color: var(--black); }
/* Page title: one per page, the opener's h1 */
.page-title { font-size: 40px; line-height: 46px; font-weight: 300; letter-spacing: -.005em; text-wrap: balance; }
/* Section title ("Hochzeitsfrisuren", "Präzision und Pflege") */
.title { font-size: 32px; line-height: 38px; font-weight: 300; letter-spacing: -.005em; text-wrap: balance; }
/* Lead paragraph: the intro text of a section or page */
.lead { max-width: 430px; font-size: 17px; line-height: 27px; font-weight: 300; text-wrap: pretty; }  /* no single word alone on the last line */
/* Vertical rhythm inside text columns (homepage values: title → lead 28, lead → frame 44, title → action 20) */
.title + .lead { margin-top: 28px; }
.lead + .lead { margin-top: 27px; }
.lead + .action { margin-top: 28px; }
.lead + .frame { margin-top: 44px; }
.title + .action { margin-top: 20px; }
.title + .frame { margin-top: 32px; }
/* Credit (round 2): an award or title line between lead and action, e.g. "Grand Prix, Weltmeisterschaft 2021,
   Evening Hairstyle". The lead's size (Ilja, 2026-09-24): at body size it looked smaller than the same award in the
   leads of Dmitri Slabowski and Academy, as the Make-up sentence on Hochzeitsfrisuren did before it became a lead.
   <p class="lead">…</p><p class="credit">…</p><a class="caps action">…</a> */
.credit { max-width: 430px; font-size: 17px; line-height: 27px; font-weight: 300; text-wrap: pretty; }
.price-line { font-size: 14px; line-height: 21px; font-weight: 300; letter-spacing: 0; }
/* Price line (round 3): one starting price under a title, in a chapter or a split. <h2 class="title">Schnitt</h2><p class="price-line">ab 69 €</p> */
.title + .price-line { margin-top: 8px; }
.price-line + .lead { margin-top: 28px; }
.lead + .credit { margin-top: 27px; }  /* like .lead + .lead */
.credit + .action { margin-top: 28px; }
.credit + .frame { margin-top: 44px; }
/* Actions (consolidation, from hochzeitsfrisuren.html and karriere.html): two text actions in one row, 32 px apart,
   wrapping 14 px below. <p class="lead">…</p><div class="actions"><a class="caps action">…</a><a class="caps action">…</a></div> */
.actions { display: flex; flex-wrap: wrap; gap: 14px 32px; }
:is(.lead, .credit, .price-note) + .actions { margin-top: 28px; }
/* Price note (consolidation, from hochzeitsfrisuren.html and leistungen.html): one sentence in body text about prices
   or an option, under a lead (28 px) or under a hairline list (20 px), at most 430 px wide.
   <p class="lead">…</p><p class="price-note">Auf Wunsch kommt das Make-up dazu, jeweils ab 70 €.</p> */
.price-note { max-width: 430px; font-weight: 300; text-wrap: pretty; }  /* Light like the lead above it (Ilja, 2026-09-24): Regular under a Light lead looked like a second typeface */
.lead + .price-note { margin-top: 28px; }
.hairlines + .price-note { margin-top: 20px; }
.price-note + .action { margin-top: 28px; }
/* Helpers (round 2). .nowrap keeps a phone number, a street name or a hyphenated word on one line.
   .visually-hidden hides text on screen but keeps it for screen readers (e.g. a heading the design shows as a photo). */
.nowrap { white-space: nowrap; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* 3 · Header: transparent over an opener image or film, white when hovered, while the menu or the language list
   is open, and once the opener has scrolled away (site.js sets .solid). Pages without an opener image
   (body.no-opener) get the white header from the start. */
.header { position: fixed; inset: 0 0 auto 0; height: var(--header); z-index: 20; display: flex; align-items: center; justify-content: space-between; padding: 0 var(--side); color: var(--white); transition: background-color .25s, color .25s, transform .35s ease; }
.header.away { transform: translateY(-100%); }
.header:hover, .header.solid, body.no-opener .header, body.menu-open .header, .header:has(.lang-picker.open) { background: var(--white); color: var(--black); }
.header .side { width: 170px; display: flex; align-items: center; }
.header .side.right { justify-content: flex-end; gap: 28px; }
/* Homepage only (.header.with-services): LEISTUNGEN over the film, TERMIN BUCHEN once the film has scrolled away.
   Every other page shows TERMIN BUCHEN from the start. */
.header.with-services .booking { display: none; }
.header.with-services.solid .booking, body.menu-open .header.with-services .booking { display: inline; }
.header.with-services.solid .services, body.menu-open .header.with-services .services { display: none; }
/* The header's text links and the language button are underlined under the pointer, like the menu's entries (Ilja, 2026-09-25) */
.header .side.right > a:hover, .lang-current:hover { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }

/* 4 · Language picker: the header shows the current language; one click opens all four as a white extension of the
   header, always in the order DE, FR, EN, RU from the top (Ilja, 2026-09-24). The open list lies over the button,
   so DE takes the button's place and the current language is underlined in its own position. */
.lang-picker { position: relative; }
.lang-current { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
.lang-picker.open .lang-current { visibility: hidden; }
/* Left padding stays below the 28 px gap to TERMIN BUCHEN, so the white box never covers it */
.lang-list { display: none; position: absolute; top: 0; right: -40px; padding: 0 40px 22px 20px; background: var(--white); color: var(--black); flex-direction: column; align-items: flex-end; gap: 10px; }
.lang-picker.open .lang-list { display: flex; }
.lang-list a:hover, .lang-list [aria-current], .menu .langs a:hover { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
/* Right after a click the pointer rests where DE now lies: no hover underline there until the pointer moves (site.js
   sets .settled), so DE does not look chosen */
.lang-picker.open:not(.settled) .lang-list a:not([aria-current]):hover { text-decoration: none; }
.menu .group.langs { display: none; }
.menu .langs .current { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
.header .logo { position: relative; width: 150px; height: 49px; }
.header .logo img { position: absolute; inset: 0; width: 100%; height: 100%; transition: opacity .25s; }
.header .logo .black { opacity: 0; }
.header:hover .logo .black, .header.solid .logo .black, body.no-opener .logo .black, body.menu-open .logo .black, .header:has(.lang-picker.open) .logo .black { opacity: 1; }
.header:hover .logo .white, .header.solid .logo .white, body.no-opener .logo .white, body.menu-open .logo .white, .header:has(.lang-picker.open) .logo .white { opacity: 0; }
/* Menu symbol: two lines of exactly 1 px on whole pixels, so both look equally thick */
.menu-button { width: 28px; height: 20px; background: none; border: 0; cursor: pointer; color: inherit; position: relative; }
.menu-button span { position: absolute; left: 0; width: 28px; height: 1px; background: currentColor; transition: transform .25s, top .25s; }
.menu-button span:first-child { top: 6px; }
.menu-button span:last-child { top: 13px; }
body.menu-open .menu-button span:first-child { top: 10px; transform: rotate(45deg); }
body.menu-open .menu-button span:last-child { top: 10px; transform: rotate(-45deg); }

/* 5 · Menu: white surface, entries left in small capitals after Celine; Leistungen with indented sub-entries.
   The link of the current page carries aria-current="page" and is underlined. */
.menu { position: fixed; inset: 0; z-index: 10; background: var(--white); padding: calc(var(--header) + 72px) 100px 40px; opacity: 0; visibility: hidden; transition: opacity .25s, visibility .25s; overflow-y: auto; display: flex; flex-direction: column; gap: 30px; }
body.menu-open { overflow: hidden; }
body.menu-open .menu { opacity: 1; visibility: visible; }
.menu .group { display: flex; flex-direction: column; gap: 9px; }
.menu .group.sub { padding-left: 24px; margin-top: -21px; }
.menu a { font-size: 13px; font-weight: 400; letter-spacing: .1em; line-height: 18px; text-transform: uppercase; }
.menu a.head { font-weight: 700; }
.menu a:hover, .menu a[aria-current="page"] { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }

/* 6 · Footer (id="standort"): four columns under a hairline, the SLABOWSKI wordmark, the bottom line */
.footer { padding: 120px var(--side) 28px; }
.footer .columns { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--black); }
/* The hairline that opens the footer runs edge to edge (Ilja, 2026-09-24): the columns reach into the side margins and
   take them back as padding, so the columns keep their width and only the line gets longer */
.footer .columns { margin: 0 calc(-1 * var(--side)); padding: 0 var(--side); }
.footer .columns > div { display: flex; flex-direction: column; padding: 22px 24px 0 0; }
.footer .col-title { font-size: 12px; line-height: 18px; letter-spacing: .08em; text-transform: uppercase; font-weight: 700; margin-bottom: 14px; }
.footer a.address { display: flex; flex-direction: column; }  /* name, street and town as three lines of one link */
/* Every footer link is underlined under the pointer, like the menu's entries (Ilja, 2026-09-25); the text action is underlined anyway */
.footer a:not(.action):hover { text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.footer .gap { margin-top: 14px; }
.footer a[href^="tel:"] { white-space: nowrap; }  /* the phone number never breaks */
.footer .hours div { display: flex; }
.footer .hours div > span:first-child { width: 110px; flex-shrink: 0; }
/* Opening hours: the opening hour right-aligned in a two-figure slot with equal-width figures, so "9" stands under the
   "0" of "10" and every dash lines up (Ilja, 2026-09-24) */
.footer .hours, .opening-hours { font-variant-numeric: tabular-nums; }
:is(.footer .hours, .opening-hours) .from { display: inline-block; min-width: 2ch; text-align: right; }  /* .opening-hours: the same on Standort's list */
.footer .wordmark { width: 100%; height: auto; margin: 110px 0 24px; }
.footer .bottom { display: flex; justify-content: space-between; font-size: 12px; line-height: 18px; }
.footer .bottom .legal { display: flex; gap: 24px; }
/* "Cookie-Einstellungen", added by site.js: looks like the legal links beside it */
.footer .consent-settings { padding: 0; border: 0; background: none; font: inherit; color: inherit; cursor: pointer; }
.footer .consent-settings:hover { text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }

/* Cookie window (Ilja, 2026-09-27; behaviour in site.js): the Academy questionnaire's look – white, black text,
   a 1 px line around it, the title in the statement's size, two framed buttons of equal weight – as a small
   non-modal window at the bottom left, so the page and the film stay usable and visible behind it */
.consent { position: fixed; inset: auto auto 24px 24px; z-index: 60; width: min(440px, calc(100% - 48px)); margin: 0; padding: 30px 32px 32px; border: 1px solid var(--black); background: var(--white); color: var(--black); }
.consent:focus { outline: 0; }
.consent-title { font-size: 26px; line-height: 34px; letter-spacing: -.005em; }
.consent-text { margin-top: 16px; font-size: 15px; line-height: 24px; }
.consent-more { display: inline-block; margin-top: 10px; font-size: 15px; line-height: 24px; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.consent-more:hover, .consent-actions .frame:focus-visible { color: var(--red); }
.consent-actions { display: flex; gap: 12px; margin-top: 26px; }
.consent-actions .frame { flex: 1 1 0; min-width: 0; padding: 14px 10px; white-space: normal; background: none; font-family: inherit; color: inherit; cursor: pointer; }  /* long labels (FR, RU) wrap inside the frame */
.consent-actions .frame:hover, .consent-actions .frame:focus-visible { background: var(--black); color: var(--white); }
@media (prefers-reduced-motion: no-preference) {
  .consent[open] { animation: consent-in .3s ease; }
}
@keyframes consent-in { from { opacity: 0; transform: translateY(12px); } }

/* 7 · Film pause button (WCAG 2.2.2): <button class="pause" id="pause"> inside a positioned film block,
   next to <video id="film">. site.js wires it up. */
.pause { position: absolute; right: var(--side); bottom: 34px; width: 20px; height: 20px; border: 0; background: none; cursor: pointer; color: var(--white); }
.pause i { position: absolute; top: 5px; width: 2px; height: 10px; background: var(--white); }
.pause i:first-child { left: 6px; }
.pause i:last-child { left: 12px; }
.pause.paused i:first-child { left: 6px; width: 0; height: 0; background: none; border-left: 9px solid var(--white); border-top: 6px solid transparent; border-bottom: 6px solid transparent; top: 4px; }
.pause.paused i:last-child { display: none; }

/* 8 · Page layout */
/* White header from the start: main starts below it */
body.no-opener main { padding-top: var(--header); }
/* Section spacing: 120 px above (72 on phones), side padding of the page. .tight: 96 px (56 on phones).
   .bleed: no side padding, for edge-to-edge content. Wrapped in :where() so that pattern rules always win. */
:where(.section) { margin-top: 120px; padding-left: var(--side); padding-right: var(--side); }
:where(.section.tight) { margin-top: 96px; }
:where(.section.bleed) { padding-left: 0; padding-right: 0; }
/* Anchor targets (consolidation, from leistungen.html): html's scroll-padding-top keeps the header clear, and 40 px of
   white air sit between the header and the target. A block that begins with an edge-to-edge photo (split, full image,
   image block) meets the header directly, so no sliver of the block above shows. Nothing to add in the page. */
main [id] { scroll-margin-top: 40px; }
main :is(.split, .full-image, .image-block)[id] { scroll-margin-top: 0; }
/* Two equal columns on the page grid, 80 px apart: the right column starts where the opener's lead starts.
   For a title and lead left and a list right. One column on phones. */
.halves { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 80px; align-items: start; }
/* A title and a paragraph as the two columns (Werdegang & Zertifikate, Formate, Arbeiten bei Slabowski): side by side,
   so the paragraph starts level with the title, not 28 px lower as a lead under a title does; on phones the row gap
   alone separates them, as with Ablauf, whose paragraph sits in a <div> (Ilja, 2026-09-24: same structure, same look) */
.halves > .title + .lead { margin-top: 0; }

/* 9 · Patterns */

/* 9.1 Opener (guide §4.1, Khaite arrivals): page title left, lead and one action right, a vertical hairline
   between them, a horizontal hairline below. Direct child of main, never inside .section.
   <section class="opener"><h1 class="page-title">…</h1><div><p class="lead">…</p><a class="caps action">…</a></div></section> */
.opener { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0 var(--side); padding-top: 72px; border-bottom: 1px solid var(--black); }
.opener > * { padding-bottom: 64px; }
.opener > :first-child { padding-right: 40px; border-right: 1px solid var(--black); }
.opener > :last-child { display: flex; flex-direction: column; align-items: flex-start; padding-left: 40px; padding-top: 2px; }

/* 9.2 Big image blocks: edge to edge, the height of the homepage features. Consecutive image blocks and
   an image block right after the opener are 16 px apart. */
.image-block, .full-image { position: relative; height: calc(100vh - 48px); min-height: 600px; max-height: 960px; overflow: hidden; }
.image-block > img, .image-block > video, .image-block > .photo-placeholder, .image-block > picture, .image-block > picture > img,
.full-image > img, .full-image > video, .full-image > .photo-placeholder, .full-image > picture, .full-image > picture > img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* A different crop on phones (art direction): <picture><source media="(max-width: 800px)" srcset="…4x5.jpg"><img src="…16x9.jpg" alt="…"></picture>
   .image-block.portrait-on-phone (round 2): on phones the block takes a 4:5 frame instead of 86vh, for wide photos
   whose tall phone crop would cut the subject; set the crop with object-position on the image.
   .image-block.own-aspect (round 3): the block takes the photo's own aspect ratio instead of the fixed height, at every
   width – for wide group photos that the fixed height would cut on tablets and square windows. */
.image-block.own-aspect { height: auto; min-height: 0; max-height: none; }
.image-block.own-aspect > img, .image-block.own-aspect > picture, .image-block.own-aspect > picture > img { height: auto; }

/* 9.3 Split (guide §4.2): text and image as two halves, the image edge to edge, the text column narrow
   (max 430 px) and vertically centred in its half. .text-left: text left, image right; .text-right: mirrored.
   Phones: image first. <section class="split text-left"><div class="text">…</div><img …></section> */
.split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: minmax(0, 1fr); height: calc(100vh - 48px); min-height: 600px; max-height: 960px; }
.split > .text { display: grid; grid-template-columns: minmax(0, 430px); justify-content: center; align-content: center; justify-items: start; padding: 64px var(--side); }
.split > :not(.text), .split > picture > img { display: block; width: 100%; height: 100%; min-height: 0; object-fit: cover; }
.split.text-left > .text { order: 1; }
.split.text-left > :not(.text) { order: 2; }
.split.text-right > .text { order: 2; }
.split.text-right > :not(.text) { order: 1; }
/* .inset (round 2): a small second photo in the text half, bottom-aligned with the big photo (Khaite Fall/Winter 2022,
   SOBRANA). The copy moves to the top edge. Wrap the copy in a <div>; hidden on phones.
   <div class="text"><div><h2 class="title">…</h2><p class="lead">…</p><a class="caps action">…</a></div><img class="inset" …></div> */
.split > .text:has(> .inset) { align-content: space-between; padding-top: 0; padding-bottom: 0; }
.split .inset { width: min(248px, 27.5vh); height: auto; aspect-ratio: 2 / 3; object-fit: cover; }

:is(.opener, .image-block, .full-image, .split) + :is(.image-block, .full-image, .split) { margin-top: var(--gap); }
/* A grid right after the opener (round 2) gets the same 16 px: <div class="section grid cols-4">…</div> keeps the side margins */
.opener + .grid { margin-top: var(--gap); }

/* 9.4 Grid with captions (guide §4.3): two to four images in a row, 16 px apart; beneath each a caption in
   small capitals, an optional price right-aligned. .span-2 makes one figure two columns wide (Khaite:
   one large image beside two small ones). Set the crop with style="aspect-ratio: 4 / 5" on the image.
   <figure><img …><figcaption class="caps"><span>Schnitt</span><span class="price">ab 69 €</span></figcaption></figure> */
.grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--gap); row-gap: 56px; align-items: start; }
.grid.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid .span-2 { grid-column: span 2; }
.grid figure { min-width: 0; }
.grid figure > img, .grid figure > video, .grid figure > .photo-placeholder { width: 100%; height: auto; object-fit: cover; }
.grid figcaption { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin-top: 14px; }
.grid figcaption .price { flex-shrink: 0; text-transform: none; letter-spacing: .02em; }
/* Linked figure (2026-09-24, damen.html and herren.html): a caption that is a link makes the whole figure clickable –
   its ::after covers picture and caption – and the caption is underlined while the pointer is on the figure.
   <figure><img …><figcaption class="caps"><a href="#farbe">Farbe</a></figcaption></figure> */
.grid figure:has(> figcaption a) { position: relative; }
.grid figcaption a::after { content: ""; position: absolute; inset: 0; }
.grid figure:hover > figcaption a { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }

/* 9.5 Section head (guide §4.3): title left, one text action right, a hairline below */
.section-head { display: flex; justify-content: space-between; align-items: baseline; gap: 24px; padding-bottom: 20px; border-bottom: 1px solid var(--black); margin-bottom: 24px; }
.section-head > .action { flex-shrink: 0; }
/* A hairline list right under a section head (round 3): the head's line is the list's first line, no second line 24 px below */
.section-head:has(+ .hairlines > .row:first-child) { margin-bottom: 0; }
.section-head + .hairlines > .row:first-child { border-top: 0; }

/* 9.6 Hairline list (guide §4.4): rows divided by 1 px lines, name left, values right-aligned, no boxes.
   Two columns by default, .cols-3 for two values per row (e.g. Stylist | Dmitri Slabowski). A group title row
   in small capitals opens each group; its value cells can name the value columns. Value columns line up
   across all groups of one list.
   <div class="hairlines cols-3">
     <p class="group-title caps"><span>Kinder</span><span>Stylist</span><span>Dmitri Slabowski</span></p>
     <p class="row"><span>Bis 5 Jahre</span><span>ab 26 €</span><span>ab 32 €</span></p>
   </div> */
.hairlines { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 40px; }
.hairlines.cols-3 { grid-template-columns: minmax(0, 1fr) auto auto; }
.hairlines > * { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: baseline; }
.hairlines > * > :not(:first-child) { text-align: right; }
.hairlines .row > :not(:first-child) { white-space: nowrap; }
.hairlines > * > :last-child:not(:first-child) { grid-column: -2; }
.hairlines .row { padding: 13px 0 14px; border-bottom: 1px solid var(--black); }
.hairlines > .row:first-child { border-top: 1px solid var(--black); }
.hairlines .group-title { padding-bottom: 13px; border-bottom: 1px solid var(--black); }
.hairlines > * + .group-title, .hairlines + .hairlines { margin-top: 56px; }
/* Two lists side by side in .halves (round 2) start on the same line; on phones they stack 48 px apart */
.halves > .hairlines + .hairlines { margin-top: 0; }
/* .notes (round 2): name | sentence, with .cols-3 name | sentence | value. The sentence is left-aligned and wraps;
   on phones it goes under the name. For steps, curricula, offers. The name column is 184 px; set --name on the list
   to change it (style="--name: 50%" puts the sentences under the opener's lead when the list spans the page).
   <div class="hairlines notes cols-3"><p class="row"><span>Probetermin</span><span>Ein Satz.</span><span>ab 150 €</span></p></div> */
.hairlines.notes { grid-template-columns: var(--name, 184px) minmax(0, 1fr); }
.hairlines.notes.cols-3 { grid-template-columns: var(--name, 184px) minmax(0, 1fr) auto; }
.hairlines.notes > * > :nth-child(2) { grid-column: 2; text-align: left; }
.hairlines.notes .row > :nth-child(2) { white-space: normal; }
.hairlines.notes > * > :nth-child(3) { grid-column: 3; }
/* .timeline (round 2): year | entry, for a vita. The year column is 48 px or wider (ranges), 24 px from the entry,
   so single years put the entry 72 px from the left. <div class="hairlines timeline"><p class="row"><span>2006</span><span>Meisterprüfung</span></p></div> */
.hairlines.timeline { grid-template-columns: minmax(48px, max-content) minmax(0, 1fr); column-gap: 24px; font-variant-numeric: tabular-nums; }
.hairlines.timeline > * > :nth-child(2) { text-align: left; }
.hairlines.timeline .row > :nth-child(2) { white-space: normal; }
/* A row or group title with a single cell spans the whole row, in every variant (consolidation, from standort.html,
   leistungen.html and karriere.html: a name, an address or a group title never wraps early in the name column) */
.hairlines > * > :only-child { grid-column: 1 / -1; }

/* 9.7 Statement (guide §4.5, homepage): one centred sentence, one action beneath, on white.
   Closing variant: a framed "Termin buchen" instead of the text action. The house mark is optional. */
.statement { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 96px 24px 104px; }
.statement .mark { width: 22px; height: 22px; margin-bottom: 36px; }
.statement p { max-width: 640px; font-size: 26px; line-height: 34px; font-weight: 300; letter-spacing: -.005em; text-wrap: balance; }
.statement .action { margin-top: 30px; }
.statement p + .frame { margin-top: 44px; }
/* .closing (round 2): the last block of main, before the footer. No bottom padding: the footer's own 120 px are the
   only space above its hairline. Its action is the framed "Termin buchen".
   <section class="statement closing"><p>…</p><a class="caps frame" href="https://timeglobe.app/book/slabowski">Termin buchen</a></section> */
.statement.closing { padding-bottom: 0; }

/* 9.8 Full image with a centred caption (guide §4.6, homepage Hochzeitsbild): title and one action, centred
   64 px above the bottom edge. The action is a text action (a link to a page) or .frame.on-image (booking).
   <section class="full-image"><img …><div class="caption"><h2 class="title">…</h2><a class="caps action">…</a></div></section> */
.full-image { color: var(--white); }
.full-image .caption { position: absolute; left: var(--side); right: var(--side); bottom: 64px; display: flex; flex-direction: column; align-items: center; text-align: center; }
/* .light (round 2): for photos with a light lower centre (the bride's ivory dress, a pale floor): the caption turns black –
   title, text action and a black-framed button (write it as .frame; .frame.on-image turns black here too) */
.full-image.light { color: var(--black); }
.full-image.light .frame.on-image { color: var(--black); border-color: var(--black); }
.full-image.light .frame.on-image:hover { background: var(--black); color: var(--white); }

/* 9.9 Category line (guide §4.7, Khaite): an index of the page as one centred line, the entries separated by
   slashes, each an anchor link. <nav class="category-line"><a href="#damen">Damen</a> <a …>…</a></nav> */
.category-line { text-align: center; font-size: 26px; line-height: 34px; font-weight: 300; letter-spacing: -.005em; }
.category-line a { white-space: nowrap; }
.category-line a:not(:last-child)::after { content: "/"; content: "/" / ""; display: inline-block; margin-left: .3em; }
.category-line a:hover { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
/* 9.9c Justified paragraph (Ilja, 2026-09-24): Blocksatz for every opener's lead and for longer paragraphs in the right
   column (.lead.justified: Werdegang & Zertifikate, Formate, Ablauf), at most 520 px wide, so their right edges line up.
   Desktop and tablet only: a phone line holds about 40 characters, too few for even gaps, so phones keep ragged-right
   text. German hyphenation (lang="de"; the translations hyphenate by their own lang), but only words of 10+ letters,
   at least 4 letters on each side. No .nowrap and no &nbsp; between longer words inside: both tear gaps into the line,
   and a name joined by &nbsp; counts as one long word and gets hyphenated. A brand name that must not split goes in
   .no-hyphens.   <p class="lead justified">…<span class="no-hyphens">Biosthétique</span>…</p> */
.lead.justified, .opener .lead { max-width: 520px; }
@media (min-width: 801px) {
  .lead.justified, .opener .lead { text-align: justify; hyphens: auto; -webkit-hyphens: auto; hyphenate-limit-chars: 8 3 3; text-wrap: wrap; }
  .justified .no-hyphens, .opener .no-hyphens { hyphens: none; -webkit-hyphens: none; }
}

/* 9.9b Sentence line (2026-09-24, damen.html and herren.html): one centred sentence in the category line's place and type,
   where a grid of captioned pictures above already serves as the page's index. No action.
   <section class="section"><p class="sentence-line">…</p></section> */
.sentence-line { max-width: 720px; margin: 0 auto; text-align: center; font-size: 26px; line-height: 34px; font-weight: 300; letter-spacing: -.005em; text-wrap: balance; }

/* 9.10 Photo placeholder: a plain sand block of the planned photo's ratio while the file is missing.
   No text on it. <div class="photo-placeholder" style="aspect-ratio: 4 / 5"></div> */
.photo-placeholder { width: 100%; background: var(--sand); }

/* 9.11 Chapter (round 2, from damen.html and herren.html): a row opened by a hairline; the title (and an optional
   starting price, .price-line) left, text and one action right, starting where the opener's lead starts.
   Inside a .section; chapters follow each other directly. On phones stacked.
   <article class="chapter"><div><h2 class="title">Schnitt</h2><p class="price-line">ab 69 €</p></div>
     <div><p class="lead">…</p><a class="caps action">Preise ansehen</a></div></article> */
.chapter { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 48px 0 72px; border-top: 1px solid var(--black); }
.chapter > :last-child { display: flex; flex-direction: column; align-items: flex-start; padding-left: 40px; padding-top: 1px; }
/* .note (consolidation; Damen and Herren now show Kinder as a full chapter, 2026-09-24): a side remark in the chapter grid –
   a label in small capitals left, one body sentence and one action right, no space below. Same markup on every page:
   <aside class="chapter note" aria-label="Kinder"><p class="caps">Kinder</p>
     <div><p>Für Mädchen bis 14 Jahre gelten die Preise für Kinder.</p><a class="caps action" href="leistungen.html#kinder">Preise ansehen</a></div></aside> */
.chapter.note { padding: 28px 0 0; }
.chapter.note > .caps { padding-top: 3px; }  /* the 12 px label on the baseline of the 14 px sentence beside it */
.chapter.note p + .action { margin-top: 14px; }

/* 9.12 Cover (round 2, from dmitri-slabowski.html): the page's first block, a portrait on a dark ground, with the
   caption at the left on the dark part of the photo: a title and a line in small capitals. On phones the caption
   stands above the photo on black. The crop (object-position) stays on the page.
   <section class="image-block over-image cover"><picture>…</picture>
     <div class="caption"><p class="title">Dmitri Slabowski</p><p class="caps">Gründer und Friseurmeister</p></div></section> */
.cover { background: var(--black); color: var(--white); }
.cover .caption { position: absolute; left: var(--side); top: 50%; transform: translateY(-50%); display: flex; flex-direction: column; gap: 10px; }

/* 9.13 Text column (round 3, from impressum.html and datenschutz.html): text pages. The column follows the opener and
   runs in its right half: text and section lines start where the opener's lead starts (760 px at 1440) and end at the
   right page margin, flush with the opener's line and the footer's (consolidation: no longer capped at 620 px, which
   left them 20 px short at 1440); running text at most 520 px. Each section opens with a hairline (the first one hangs under the opener's line) and a
   bold small-caps label like the footer's column titles. Links in running text are underlined. Phones: one column.
   <article class="text-column">
     <section><h2 class="caps">Kontakt</h2><p>Telefon: <a class="nowrap" href="tel:+496619019125">0661 90 19 125</a></p></section>
     <section><a class="caps action" href="datenschutz.html">Datenschutz</a></section></article> */
.text-column { padding: 0 var(--side); }
.text-column > * { margin-left: calc(50% + 40px); }
.text-column section { border-top: 1px solid var(--black); padding: 22px 0 44px; }
.text-column > section:first-child { border-top: 0; padding-top: 44px; }
/* The last section (the link to the sister page) ends the page like .statement.closing: the footer's own 120 px are the
   only white above its hairline (consolidation) */
.text-column > section:last-child { padding-bottom: 0; }
.text-column section > h2 { font-weight: 700; }
.text-column section > h2 + * { margin-top: 14px; }
.text-column p, .text-column li { max-width: 520px; }
.text-column p + p { margin-top: 12px; }
/* Links inside running text – a text column, a lead – are underlined 5 px below (consolidation: also in a lead, from standort.html) */
:is(.text-column p, .text-column li, .lead) a:not(.action) { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }

/* 10 · Phones */
@media (max-width: 800px) {
  /* Cookie window: the full width between the phone margins, at the bottom */
  .consent { inset: auto var(--side) var(--side) var(--side); width: auto; padding: 24px 22px 22px; }
  .consent-title { font-size: 22px; line-height: 30px; }
  /* the two buttons one above the other, each the full width, so no label breaks */
  .consent-actions { flex-direction: column; gap: 10px; margin-top: 22px; }
  .consent-actions .frame { flex: none; padding: 13px 8px; }
  .footer .bottom .legal { flex-wrap: wrap; row-gap: 8px; }
  :root { --side: 20px; --header: 64px; }
  .header .side { width: 96px; }
  .header .lang, .header .long { display: none; }
  .menu .group.langs { display: flex; flex-direction: row; gap: 22px; }
  .header .logo { width: 110px; height: 36px; }
  .menu { padding: calc(var(--header) + 40px) 28px 40px; }
  /* Two equal columns; the gutter replaces the columns' right padding, so the longest line
     ("Slabowski Hair & Beauty", 154 px) and the phone number (150 px) fit a 165 px column */
  .footer .columns { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--side); row-gap: 36px; }
  .footer .columns > div { padding-right: 0; }
  .footer .hours div > span:first-child { width: 84px; }  /* "Donnerstag" 73 px + "geschlossen" 79 px */
  .footer .wordmark { margin-top: 72px; }
  .footer .bottom { flex-direction: column; gap: 8px; }

  .page-title { font-size: 30px; line-height: 36px; }
  .title { font-size: 28px; line-height: 34px; }
  .lead, .credit { font-size: 16px; line-height: 25px; }
  .statement p, .category-line, .sentence-line { font-size: 22px; line-height: 30px; }
  .image-block.portrait-on-phone { height: auto; min-height: 0; aspect-ratio: 4 / 5; }

  :where(.section) { margin-top: 72px; }
  :where(.section.tight) { margin-top: 56px; }
  .halves { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }

  .opener { grid-template-columns: minmax(0, 1fr); padding-top: 40px; }
  .opener > :first-child { padding: 0 0 20px; border-right: 0; }
  .opener > :last-child { padding: 0 0 40px; }

  .image-block, .full-image { height: 86vh; }
  .full-image .caption { bottom: 72px; }

  .split { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; height: auto; min-height: 0; max-height: none; }
  .split > :not(.text), .split.text-left > :not(.text), .split.text-right > :not(.text) { order: 0; height: auto; aspect-ratio: 4 / 5; }
  .split > .text, .split.text-left > .text, .split.text-right > .text { order: 1; justify-content: start; padding: 48px var(--side) 0; }
  .split + :is(.image-block, .full-image, .split) { margin-top: 72px; }  /* on phones the split ends with its text */
  .split .inset { display: none; }

  .section-head { flex-direction: column; align-items: flex-start; gap: 10px; }  /* a long title and its action do not share a phone line */

  .grid, .grid.cols-2, .grid.cols-3 { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
  .grid:not(.cols-4) .span-2 { grid-column: auto; }
  .grid.cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 40px; }

  .hairlines { column-gap: 16px; }
  .hairlines.cols-3 { grid-template-columns: minmax(0, 1fr) fit-content(96px) fit-content(96px); }
  .hairlines > * + .group-title, .hairlines + .hairlines { margin-top: 48px; }
  .halves > .hairlines + .hairlines { margin-top: 8px; }  /* + the 40 px row gap of .halves = 48 px */
  .hairlines.notes, .hairlines.notes.cols-3 { grid-template-columns: minmax(0, 1fr) auto; }
  .hairlines.notes > * > :nth-child(2) { grid-column: 1 / -1; grid-row: 2; margin-top: 4px; }
  .hairlines.notes > * > :nth-child(3) { grid-column: 2; grid-row: 1; }

  .chapter { grid-template-columns: minmax(0, 1fr); padding: 32px 0 56px; }
  .chapter > :last-child { padding: 20px 0 0; }
  .chapter.note { padding: 24px 0 0; }
  .chapter.note > .caps { padding-top: 0; }
  .chapter.note > :last-child { padding-top: 12px; }

  .image-block.cover { display: flex; flex-direction: column; height: auto; min-height: 0; max-height: none; }
  .image-block.cover.over-image { padding-top: var(--header); }  /* the transparent header lies over the black */
  .image-block.cover > img, .image-block.cover > picture, .image-block.cover > picture > img { height: auto; aspect-ratio: 4 / 5; }
  .cover .caption { order: -1; position: static; transform: none; padding: 24px var(--side) 32px; }

  .text-column > * { margin-left: 0; }
  .text-column section { padding: 20px 0 36px; }
  .text-column > section:first-child { padding-top: 32px; }
}

/* Very narrow phones (under 360 px, e.g. 320): two footer columns of 130 px cannot hold "Donnerstag" and "geschlossen"
   (152 px) side by side – the footer stacks into one column */
@media (max-width: 359px) {
  .footer .columns { grid-template-columns: minmax(0, 1fr); }
}

/* 11 · Version 2 (Ilja, 2026-09-25): the red of the S mark above the homepage's positioning sentence (assets/mark-red.svg)
   as the one accent. Last in the file so it wins over the black hovers above. */
:root { --red: #c1121f; }
/* Every link turns red under the pointer, text links and captions alike (the logo has no text, so it stays as it is) */
a:hover, .lang-current:hover, .grid figure:hover > figcaption a { color: var(--red); }
/* … and the menu symbol (its two lines are drawn in currentColor) */
.menu-button:hover { color: var(--red); }
/* The red S mark left of the SLABOWSKI lockup in the header (Ilja, 2026-09-25, after the salon's own logo): as tall as the
   lettering, its top on the top of SLABOWSKI and its bottom on the bottom of HAIR & BEAUTY. The lettering fills the
   lockup file almost exactly (48.2 of 49 px), so the mark is the logo's height, 14 px before the lettering. The S is white
   (mark-red-header.svg lays a white disc under the cut-out S), so it reads the same over the film. The logo link takes
   the mark's room as left margin, so mark and lettering together stay centred in the header. */
.header .logo { margin-left: 63px; }
.header .logo::before { content: ""; position: absolute; left: -63px; top: 0; width: 49px; height: 49px; background: url("mark-red-header.svg") center / contain no-repeat; }
@media (max-width: 800px) {
  /* Phones: the lockup is 110 × 36, the mark 36 px with 10 px to the lettering. As on desktop the logo link takes the
     mark's room as left margin, so mark and lettering together stay centred (Ilja, 2026-09-26: with only the lettering
     centred the logo sat 23 px left of the middle). This squeezed the lettering against LEISTUNGEN at 360 px, but the
     phone header no longer shows LEISTUNGEN, and Russian and French show the language button instead of their wider
     booking word (section 12) */
  .header .logo { margin-left: 46px; }
  .header .logo::before { left: -46px; width: 36px; height: 36px; }
}
/* … and the film's pause button (its bars and triangle are drawn in white, not currentColor) */
.pause:hover i { background: var(--red); }
.pause.paused:hover i:first-child { background: none; border-left-color: var(--red); }
/* Framed buttons (Termin buchen, Anfragen, Bewerbung senden) fill red with white letters, on white and over images */
.frame:hover, .frame.on-image:hover, .full-image.light .frame.on-image:hover { background: var(--red); border-color: var(--red); color: var(--white); }
/* … except the booking button over the homepage film, which fills white with black letters as in the main version
   (Ilja, 2026-09-26) */
.frame.on-image.hero-link:hover { background: var(--white); border-color: var(--white); color: var(--black); }

/* 12 · Version 2, phones only (Ilja, 2026-09-26). Everything here sits inside the phone query, so the desktop view
   stays as it is; only .phone-only needs a rule outside it, to stay hidden on desktop. */
.phone-only, .split > .phone-only { display: none; }  /* the split rule would show it otherwise */
@media (max-width: 800px) {
  /* A photo shown only on phones takes the place of one shown only on desktop (Dmitri page, Handwerk) */
  .desktop-only, .split > .desktop-only { display: none; }
  .phone-only, .split > .phone-only { display: block; }
  /* Homepage: the language button instead of LEISTUNGEN over the film; TERMIN still takes its place once the film has
     scrolled away, as before */
  .header.with-services .services { display: none; }
  .header.with-services:not(.solid) .lang { display: block; }
  body.menu-open .header.with-services .lang { display: none; }
  /* The open language list ends at the phone's page margin (desktop: 40 px margin, phones: 20 px) */
  .lang-list { right: calc(-1 * var(--side)); padding-right: var(--side); }
  /* Footer: Impressum and Datenschutz on the copyright line instead of under it. The line needs 317 of the 320 px a
     360 px phone leaves; narrower phones wrap the two links onto a second line */
  .footer .bottom { flex-direction: row; flex-wrap: wrap; justify-content: space-between; column-gap: 12px; }
  .footer .bottom .legal { gap: 14px; }
  /* The bride photo (homepage and Damen): the bride in the middle of the frame instead of at its left edge. The desktop
     crop sits on the image as an inline style, so the phone crop needs !important to replace it */
  .full-image > img[src$="hochzeit-braut.jpg"] { object-position: 81% 0% !important; }
  /* Russian and French: the language button always stays top right, also once the homepage film has scrolled away and
     with the menu open; the booking word ("Записаться", "Réserver") is too wide next to the centred logo and read
     oddly there (Ilja, 2026-09-26). Booking stays in the menu and on every page's buttons. !important because the
     homepage's state rules above (.solid, body.menu-open) are more specific, and this holds in every state */
  html:is(:lang(ru), :lang(fr)) .header .booking { display: none !important; }
  html:is(:lang(ru), :lang(fr)) .header .lang { display: block !important; }
}
