@charset "utf-8";
@layer base, layout, components, utilities;

/* ------------------------------------------------------------------ *
 * Elektro Meier GmbH, Riedhof im Limmattal
 * Three color schemes, switched via data-palette on <html>:
 *   (default) K1 "Nachtblau und Tuerkis"   anchor 285, accent 195
 *   k2        "Graphit und Signalgelb"     anchor 255, accent  85
 *   k3        "Zinkgrau und Kupfer"        anchor  50, accent  40
 * Hard edges on surfaces, a small radius on controls only, hard
 * easings, mono strictly for values, labels and units, never for full
 * sentences. Seven fixed type steps with coupled tracking
 * (--t1..--t8, no --t2 / --ls1..--ls8, no --ls2). One recurring
 * slanted mark (45deg parallelogram) as the site-wide directional
 * element.
 * ------------------------------------------------------------------ */

@layer base {
  @font-face {
    font-family: "Saira";
    src: url("../fonts/saira.woff2") format("woff2");
    font-weight: 100 900;
    font-stretch: 50% 125%;
    font-style: normal;
    font-display: swap;
  }
  @font-face {
    font-family: "JetBrains Mono";
    src: url("../fonts/mono.woff2") format("woff2");
    font-weight: 100 800;
    font-style: normal;
    font-display: swap;
  }

  /* K1 "Nachtblau und Tuerkis": hard dark band (L 0.205), loud cold
   * accent 90deg from anchor, dark button text.
   * WCAG contrasts, computed 23.08.2026 (scratchpad/palette.py):
   *   ink/light 14.28  ink/light-2 12.55  ink-soft/light 7.15
   *   ink-soft/light-2 6.28  ink-dark/dark 14.60  ink-dark-soft/dark 7.41
   *   accent/dark 7.60  accent-deep/light 5.81  accent-deep/light-2 5.11
   *   button ink-on-accent 7.60 (OKLCH delta-L 0.510 >= 0.35)
   *   button hover ink-on-press 5.97
   * L bounds: light 0.955 <= 0.975, dark 0.205 >= 0.205. */
  :root {
    color-scheme: light;

    --dark: oklch(0.205 0.028 285);
    --light: oklch(0.955 0.008 285);
    --ink: oklch(0.245 0.026 285);
    --ink-dark: oklch(0.930 0.012 285);
    --accent: oklch(0.715 0.130 195);        /* button surface, marks   */
    --accent-press: oklch(0.650 0.122 195);  /* button hover, same hue  */
    --accent-deep: oklch(0.455 0.105 195);   /* accent text on light    */
    --accent-bright: oklch(0.715 0.130 195); /* accent text on dark     */
    --btn-ink: oklch(0.205 0.028 285);       /* button text             */

    /* derived, not enumerated: neutrals grow out of the two anchors */
    --dark-2: color-mix(in oklch, var(--ink-dark) 7%, var(--dark));
    --light-2: color-mix(in oklch, var(--ink) 6%, var(--light));
    --ink-soft: color-mix(in oklch, var(--ink) 74%, var(--light));
    --ink-dark-soft: color-mix(in oklch, var(--ink-dark) 72%, var(--dark));
    --rule: color-mix(in oklch, var(--ink) 16%, var(--light));
    --rule-dark: color-mix(in oklch, var(--ink-dark) 18%, var(--dark));

    /* seven type steps with coupled tracking. Differentiation runs
       over weight and grey, not over a long ladder of sizes: no more
       than four of these are ever on screen at once. */
    --t1: 0.78rem;   --ls1: 0.05em;    /* mono labels              */
    --t3: 0.95rem;   --ls3: 0em;       /* small values, notes, meta */
    --t4: clamp(1rem, 0.97rem + 0.14vw, 1.05rem); --ls4: 0em;  /* body */
    --t5: clamp(1.1rem, 1.02rem + 0.3vw, 1.28rem); --ls5: -0.005em; /* h3 */
    --t6: 1.4rem;    --ls6: -0.01em;   /* mono key figures         */
    --t7: clamp(1.55rem, 1.15rem + 1.35vw, 2.05rem); --ls7: -0.012em; /* h2 */
    /* the display step has to sit inside a sign that lies in the
       picture and must not swallow the motif, hence the lower ceiling */
    --t8: clamp(2.1rem, 1.08rem + 3.65vw, 3.9rem); --ls8: -0.018em; /* h1, one display number */

    --sans: "Saira", "Segoe UI", system-ui, sans-serif;
    --mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;

    /* underline offsets: exactly two values site-wide */
    --uo-s: 0.25em;
    --uo-l: 0.3em;

    --ease: cubic-bezier(0.2, 0, 0, 1);

    /* two shadow strengths for the controls, plus the one the stuck
       head casts onto the page it covers */
    --shade-near: color-mix(in oklch, var(--ink) 16%, transparent);
    --shade-far: color-mix(in oklch, var(--ink) 10%, transparent);
    --shade-stuck: color-mix(in oklch, var(--dark) 40%, transparent);
  }

  /* K2 "Graphit und Signalgelb": shallower dark band (L 0.235), hardest
   * ink (0.215) and rules (20%), deepest banding (8%), warm signal
   * accent nearly complementary (-170deg) to the cool anchor.
   * WCAG contrasts, computed 23.08.2026:
   *   ink/light 15.82  ink/light-2 13.20  ink-soft/light 9.04
   *   ink-soft/light-2 7.54  ink-dark/dark 13.77  ink-dark-soft/dark 7.57
   *   accent/dark 8.83  accent-deep/light 5.79  accent-deep/light-2 4.83
   *   button ink-on-accent 8.83 (OKLCH delta-L 0.565)  hover 7.02
   * L bounds: light 0.965 <= 0.975, dark 0.235 >= 0.205. */
  :root[data-palette="k2"] {
    --dark: oklch(0.235 0.020 255);
    --light: oklch(0.965 0.005 255);
    --ink: oklch(0.215 0.022 255);
    --ink-dark: oklch(0.935 0.008 255);
    --accent: oklch(0.800 0.150 85);
    --accent-press: oklch(0.735 0.145 85);
    --accent-deep: oklch(0.490 0.100 70);
    --accent-bright: oklch(0.800 0.150 85);
    --btn-ink: oklch(0.235 0.020 255);
    --light-2: color-mix(in oklch, var(--ink) 8%, var(--light));
    --ink-soft: color-mix(in oklch, var(--ink) 78%, var(--light));
    --ink-dark-soft: color-mix(in oklch, var(--ink-dark) 74%, var(--dark));
    --rule: color-mix(in oklch, var(--ink) 20%, var(--light));
    --rule-dark: color-mix(in oklch, var(--ink-dark) 20%, var(--dark));
  }

  /* K3 "Zinkgrau und Kupfer": softest dark band (L 0.245), quiet
   * near-tonal copper (-10deg from the warm anchor), softest rules
   * (13%), and the flipped button: light text on deep copper.
   * WCAG contrasts, computed 23.08.2026:
   *   ink/light 13.27  ink/light-2 11.96  ink-soft/light 6.31
   *   ink-soft/light-2 5.68  ink-dark/dark 12.83  ink-dark-soft/dark 6.48
   *   accent-bright/dark 6.74  accent-deep/light 6.03  accent-deep/light-2 5.43
   *   button light-on-accent 5.34 (OKLCH delta-L 0.445)  hover 6.61
   * L bounds: light 0.945 <= 0.975, dark 0.245 >= 0.205. */
  :root[data-palette="k3"] {
    --dark: oklch(0.245 0.018 50);
    --light: oklch(0.945 0.006 50);
    --ink: oklch(0.260 0.020 50);
    --ink-dark: oklch(0.920 0.010 50);
    --accent: oklch(0.500 0.105 40);
    --accent-press: oklch(0.450 0.100 40);
    --accent-deep: oklch(0.470 0.095 45);
    --accent-bright: oklch(0.735 0.095 50);
    --btn-ink: oklch(0.945 0.006 50);
    --light-2: color-mix(in oklch, var(--ink) 5%, var(--light));
    --ink-soft: color-mix(in oklch, var(--ink) 72%, var(--light));
    --ink-dark-soft: color-mix(in oklch, var(--ink-dark) 70%, var(--dark));
    --rule: color-mix(in oklch, var(--ink) 13%, var(--light));
    --rule-dark: color-mix(in oklch, var(--ink-dark) 15%, var(--dark));
  }

  @supports not (color: oklch(0 0 0)) {
    :root {
      --dark: #161523; --light: #efeff5; --ink: #1f1f2c; --ink-dark: #e7e7f0;
      --accent: #00bcbc; --accent-press: #00a5a6; --accent-deep: #006869;
      --accent-bright: #00bcbc; --btn-ink: #161523;
      --dark-2: #212130; --light-2: #e1e1e8; --ink-soft: #4e4e5b;
      --ink-dark-soft: #a5a6b1; --rule: #cacad2; --rule-dark: #353544;
      --shade-near: rgba(31, 31, 44, 0.16); --shade-far: rgba(31, 31, 44, 0.1);
      --shade-stuck: rgba(22, 21, 35, 0.4);
    }
    :root[data-palette="k2"] {
      --dark: #181f28; --light: #f1f4f7; --ink: #131a24; --ink-dark: #e6eaef;
      --accent: #eab532; --accent-press: #d3a11a; --accent-deep: #84550f;
      --accent-bright: #eab532; --btn-ink: #181f28;
      --dark-2: #242a33; --light-2: #dde0e4; --ink-soft: #3c434c;
      --ink-dark-soft: #aaafb6; --rule: #bfc3c8; --rule-dark: #3b424a;
      --shade-near: rgba(19, 26, 36, 0.16); --shade-far: rgba(19, 26, 36, 0.1);
      --shade-stuck: rgba(24, 31, 40, 0.4);
    }
    :root[data-palette="k3"] {
      --dark: #281e19; --light: #f0ece9; --ink: #2c211b; --ink-dark: #eae3df;
      --accent: #944c32; --accent-press: #833f27; --accent-deep: #86482a;
      --accent-bright: #da9872; --btn-ink: #f0ece9;
      --dark-2: #332a24; --light-2: #e5e0de; --ink-soft: #5e534e;
      --ink-dark-soft: #aba29d; --rule: #d4cecb; --rule-dark: #413732;
      --shade-near: rgba(44, 33, 27, 0.16); --shade-far: rgba(44, 33, 27, 0.1);
      --shade-stuck: rgba(40, 30, 25, 0.4);
    }
  }

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

  html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
  }

  body {
    margin: 0;
    background: var(--light);
    color: var(--ink);
    font-family: var(--sans);
    font-size: var(--t4);
    letter-spacing: var(--ls4);
    line-height: 1.58;
    font-optical-sizing: auto;
    font-synthesis-weight: none;
  }

  figure { margin: 0; }
  picture { display: contents; }
  img { display: block; max-inline-size: 100%; height: auto; }
  ul, ol { margin: 0; padding: 0; list-style: none; }
  svg { display: block; }

  h1, h2, h3 {
    margin: 0;
    text-wrap: balance;
    font-weight: 600;
    -webkit-hyphens: auto;
    hyphens: auto;
    hyphenate-limit-chars: 14 8 6;
    hyphenate-limit-lines: 2;
    -webkit-hyphenate-limit-before: 8;
    -webkit-hyphenate-limit-after: 6;
    -webkit-hyphenate-limit-lines: 2;
  }

  h1 {
    font-size: var(--t8);
    line-height: 1.02;
    letter-spacing: var(--ls8);
    font-variation-settings: "wdth" 87;
  }
  h2 {
    font-size: var(--t7);
    line-height: 1.12;
    letter-spacing: var(--ls7);
    font-variation-settings: "wdth" 92;
  }
  h3 {
    font-size: var(--t5);
    line-height: 1.24;
    letter-spacing: var(--ls5);
  }

  p, li, dd, dt, label, figcaption {
    text-wrap: pretty;
    -webkit-hyphens: auto;
    hyphens: auto;
    hyphenate-limit-chars: 10 5 4;
    hyphenate-limit-lines: 2;
    -webkit-hyphenate-limit-before: 5;
    -webkit-hyphenate-limit-after: 4;
    -webkit-hyphenate-limit-lines: 2;
  }
  p { margin: 0 0 1.05em; max-inline-size: 52ch; } /* ~70 chars in Saira */
  p:last-child { margin-block-end: 0; }

  a { color: inherit; }

  :focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
  }

  ::selection { background: color-mix(in oklch, var(--accent) 30%, transparent); }
  :root { accent-color: var(--accent); }

  [id] { scroll-margin-block-start: 1.5rem; }
  @media (width >= 62.5em) {
    [id] { scroll-margin-block-start: 5.25rem; }
  }

  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      transition-duration: 0.01ms !important;
    }
  }

  @media (prefers-reduced-motion: no-preference) {
    @view-transition { navigation: auto; }
  }

  /* Scroll reveals. The hiding rule only ever applies under .rv-init,
     which js/site.js sets exclusively when it runs, IntersectionObserver
     exists and reduced motion is not asked for: without JavaScript, and
     for anyone who asked for less movement, everything is simply
     visible. The offset runs sideways in reading direction, the same
     direction the slanted mark of this site points. */
  html.rv-init [data-reveal] {
    opacity: 0;
    translate: -28px 0;
  }
  html.rv-init [data-reveal].rv-on {
    opacity: 1;
    translate: 0;
    transition: opacity 560ms var(--ease), translate 560ms var(--ease);
    transition-delay: calc(var(--rv-i, 0) * 110ms);
  }

  /* 4. the slanted mark wipes in with its section */
  html.rv-init [data-reveal] > h2::before {
    scale: 0 1;
    transform-origin: left center;
  }
  html.rv-init [data-reveal].rv-on > h2::before {
    scale: 1;
    transition: scale 400ms var(--ease) 150ms;
  }

  /* 1. Load entrance. Pure CSS, so it runs without JavaScript too, and
     it ends in the visible state whatever happens. Only transform and
     opacity, so it cannot shift layout. */
  @media (prefers-reduced-motion: no-preference) {
    @keyframes pr-slide-in {
      from { opacity: 0; translate: -32px 0; }
    }
    @keyframes pr-rise {
      from { opacity: 0; translate: 0 14px; }
    }
    .stage__sign h1 > span {
      animation: pr-slide-in 550ms var(--ease) both;
    }
    .stage__sign .stage__lede { animation-delay: 120ms; }
    .top__mark,
    .top__nav { animation: pr-rise 450ms var(--ease) 250ms both; }
    .top__ends { animation: pr-rise 450ms var(--ease) 370ms both; }
  }
}

/* ------------------------------------------------------------------ */

@layer layout {
  .page {
    display: grid;
    grid-template-columns:
      [full-start] minmax(1.25rem, 1fr)
      [content-start] repeat(12, minmax(0, 5.5rem))
      [content-end] minmax(1.25rem, 1fr) [full-end];
    column-gap: clamp(0.9rem, 1.6vw, 1.6rem);
  }
  .page > * { grid-column: content; }

  /* While the phone tag sticks to the right edge, the type area keeps
     its distance there: the right margin is wider than the left. */
  @media (width < 62.5em) {
    .page {
      grid-template-columns:
        [full-start] minmax(1.25rem, 1fr)
        [content-start] repeat(12, minmax(0, 5.5rem))
        [content-end] minmax(3.6rem, 1fr) [full-end];
    }
  }

  .band { background: var(--light); }
  .band--tint { background: var(--light-2); }
  .band--dark {
    background: var(--dark);
    color: var(--ink-dark);
    position: relative;
  }
  .band--dark h2,
  .band--dark h3 { color: var(--ink-dark); }

  /* focus rings on dark grounds use the on-dark accent (K3 differs) */
  .band--dark :focus-visible,
  .plate :focus-visible,
  .top :focus-visible { outline-color: var(--accent-bright); }

  /* phones 36px, desktop 88px as before; the old 52px floor stacked
     with the hero band into what read as an empty section (decision 84) */
  .section { padding-block: clamp(2.25rem, 1rem + 5vw, 5.5rem); }
}

/* ------------------------------------------------------------------ */

@layer components {

  /* --- one label style, site-wide ----------------------------------- */
  /* Caps are reserved for navigation. A label set in caps reads as
     the eyebrow pattern; weight and tracking carry it just as well. */
  .label,
  .form label,
  .form legend {
    font-family: var(--mono);
    font-size: var(--t1);
    font-weight: 500;
    letter-spacing: var(--ls1);
    line-height: 1.4;
  }

  /* --- the slanted mark: the one directional form of this site ------ */
  .kicker > h2::before {
    content: "";
    display: block;
    inline-size: 1.5rem;
    block-size: 0.5rem;
    margin-block-end: 0.85rem;
    background: var(--accent);
    clip-path: polygon(0.5rem 0, 100% 0, calc(100% - 0.5rem) 100%, 0 100%);
  }
  .band--dark .kicker > h2::before { background: var(--accent-bright); }

  /* --- eyebrow ------------------------------------------------------ */
  /* A short orientation line above the heading (round 2). It takes the
     slanted mark over from the heading, so the section still opens with
     exactly one of them and the group reads top down. */
  .eyebrow {
    color: var(--ink-soft);
    margin-block-end: 0.55rem;
  }
  .band--dark .eyebrow { color: var(--ink-dark-soft); }
  .eyebrow::before {
    content: "";
    display: block;
    inline-size: 1.5rem;
    block-size: 0.5rem;
    margin-block-end: 0.85rem;
    background: var(--accent);
    clip-path: polygon(0.5rem 0, 100% 0, calc(100% - 0.5rem) 100%, 0 100%);
  }
  .band--dark .eyebrow::before { background: var(--accent-bright); }
  .eyebrow + h1::before,
  .eyebrow + h2::before { content: none; }

  /* --- skip link ----------------------------------------------------- */
  .skip {
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 0;
    padding: 0.7rem 1rem;
    background: var(--accent);
    color: var(--btn-ink);
    font-family: var(--mono);
    font-size: var(--t3);
    letter-spacing: 0.02em;
    translate: 0 -110%;
    z-index: 50;
  }
  .skip:focus-visible { translate: 0 0; }

  /* --- head zone: dark line that merges into hero and page heads ----- */
  .top {
    background: var(--light-2);
    position: relative;
  }

  /* Head, action zone and page heads sit on light ground now. They keep
     using the on-dark tokens, so pointing those at their light
     counterparts here turns every rule inside them at once: navigation,
     phone, slanted mark, focus rings, the fact strip and its rules. */
  .top,
  .pagehead {
    --ink-dark: var(--ink);
    --ink-dark-soft: var(--ink-soft);
    --accent-bright: var(--accent-deep); /* text accents only; marks, underlines and bullets use --accent (28.08., decision 82) */
    --rule-dark: var(--rule);
    color: var(--ink);
  }
  .top__in {
    grid-column: content;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem 1.7rem;
    padding-block: 1.05rem;
  }
  .top__mark {
    position: relative;
    font-weight: 600;
    font-size: var(--t5);
    letter-spacing: 0.01em;
    font-variation-settings: "wdth" 90;
    text-decoration: none;
    padding-block: 0.35rem;
    white-space: nowrap;
  }
  /* the wordmark is the way home: 44px target without layout change */
  .top__mark::after {
    content: "";
    position: absolute;
    inset: -0.35rem -0.4rem;
  }
  .top__mark b { font-weight: 400; color: var(--ink-soft); } /* no second brand colour in text (decision 86) */
  .top__nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1.5rem;
  }
  .top__nav a {
    position: relative;
    font-family: var(--mono);
    font-size: var(--t1);
    letter-spacing: 0.09em; /* caps need more air than the labels do */
    text-transform: uppercase;
    color: var(--ink-dark-soft);
    text-decoration: none;
    padding-block: 0.35rem;
    transition: color 120ms var(--ease);
  }
  .top__nav a::after {
    content: "";
    position: absolute;
    inset: -0.62rem -0.4rem;
  }
  .top__nav a:hover { color: var(--ink-dark); }
  .top__nav a[aria-current="page"] { color: var(--ink-dark); }
  /* current page carries the slanted mark, small (owner's wish: the
     mark stays; the way home is the wordmark, not a Startseite link) */
  .top__nav a[aria-current="page"]::before {
    content: "";
    display: inline-block;
    inline-size: 0.85rem;
    block-size: 0.38rem;
    margin-inline-end: 0.4rem;
    background: var(--accent);
    clip-path: polygon(0.38rem 0, 100% 0, calc(100% - 0.38rem) 100%, 0 100%);
  }
  /* number and call to action as buttons in the layout colour (Martin
     09.09.): the number outlined, the request filled, same size, same
     type as every other button of the site */
  .top__tel,
  .top__cta {
    font-family: var(--mono);
    font-size: var(--t3);
    letter-spacing: var(--ls3);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    padding: 0.5rem 0.95rem;
    border: 1.5px solid var(--accent);
    border-radius: 10px;
    color: var(--ink-dark);
    transition: background-color 130ms var(--ease), border-color 130ms var(--ease), color 130ms var(--ease);
  }
  .top__cta { background: var(--accent); color: var(--btn-ink); }
  .top__tel:hover { background: color-mix(in oklch, var(--accent) 16%, transparent); color: inherit; }
  .top__cta:hover { background: var(--accent-press); border-color: var(--accent-press); color: var(--btn-ink); }
  /* the two ends travel together; the navigation stays with the mark */
  .top__ends { display: flex; align-items: center; gap: 1.4rem; }
  /* below the switch point: wordmark and number on the first line,
     the page links underneath. The head zone may use the full width:
     the right-hand phone-tag margin protects scrolling content at
     mid-viewport height, not the zone pinned to the very top. */
  @media (width < 62.5em) {
    .top__in { grid-column: full; padding-inline: 1.25rem; }
    .top__ends { order: 2; margin-inline-start: auto; }
    /* On its own row the navigation is the last thing in the head zone,
       and the touch area of a link reaches 0.62rem below its box. Without
       this padding that area ends up outside the zone, where the hero
       below wins the hit test and the lower edge of every link stops
       answering. Measured with elementFromPoint at 320, 360, 390, 768
       and 900. */
    .top__nav { order: 3; flex-basis: 100%; padding-block-end: 0.7rem; }
    /* below the switch point the dock at the bottom carries number and
       request (decision 87); the head shows neither (Martin 11.09.) */
    .top__ends { display: none; }
  }
  /* Four page links since "Startseite" joined them (Martin 23.09.,
     feedback 49). On a phone they are meant to stay on one line, so the
     type steps down one notch, the tracking loosens less and the state
     mark shrinks; measured at 360 px the row needs 304 of the 320 px
     the zone has. The floor of the playbook holds: 11.5 px, and the
     touch areas keep 2 px between them. Below about 350 px the row
     breaks into two lines rather than shrink under the floor. */
  @media (width < 40em) {
    /* The row gap is not decoration: each link carries a touch area that
       reaches 0.62rem past its box top and bottom. With the rows
       touching, the areas of the two lines overlapped by about 20 px and
       a tap at the lower edge of the first line landed on a link of the
       second. The gap is therefore at least twice that reach. */
    .top__nav { gap: 1.35rem 0.75rem; }
    .top__nav a { font-size: 0.72rem; letter-spacing: 0.03em; }
    .top__nav a::after { inset: -0.62rem -0.3rem; }
    .top__nav a[aria-current="page"]::before {
      inline-size: 0.5rem;
      margin-inline-end: 0.25rem;
      clip-path: polygon(0.22rem 0, 100% 0, calc(100% - 0.22rem) 100%, 0 100%);
    }
  }
  /* On a screen this short the vertically centred phone tag reaches up
     into the head zone; the number steps out of its channel so it is
     never cut in half. Taller screens keep the full width. */
  @media (width < 62.5em) and (height < 42rem) {
    .top__in { padding-inline-end: 3.9rem; }
  }
  @media (width >= 62.5em) {
    .top__ends { margin-inline-start: auto; }
    /* The head zone stays put while the page runs past underneath.
       It is the same dark band as before, merging into the dark page
       heads at the top of every page, and it carries number and call
       to action along. Fixed height, so nothing shifts. */
    .top {
      position: sticky;
      inset-block-start: 0;
      z-index: 45;
    }
    .top__in {
      block-size: 4rem;
      padding-block: 0;
      align-items: center;
    }
    /* the shadow appears only once the band has actually left its
       place; without JavaScript it simply never appears */
    .top--stuck { box-shadow: 0 8px 22px var(--shade-stuck); }
  }
  .top-sentinel { block-size: 1px; }

  /* --- the stage: title sign lying in the place band ----------------- */
  /* Picture and sign share one grid cell, so nothing moves after the
     first paint. The sign is a sibling of the figure, never its child:
     the whole band is one photo-swap button and a button inside a
     button would be invalid. */
  .stage { position: relative; }
  .stage > .placeband { grid-column: full; grid-row: 1; }
  /* Title straight on the photo, the way current hero sections do it:
     no box, a dark-to-transparent scrim over the lower part of the
     picture, light type bottom-left, a short accent rule as the one
     mark of the brand. The picture stays whole (Rolf 28.08., decision
     85, after two boxed variants he rejected). Contrast is measured on
     the rendered pixels, not assumed. */
  .stage > .placeband { position: relative; }
  .stage > .placeband::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(
      to top,
      oklch(0.14 0.03 285 / 0.96) 0%,
      oklch(0.14 0.03 285 / 0.84) 32%,
      oklch(0.14 0.03 285 / 0.58) 60%,
      oklch(0.14 0.03 285 / 0.18) 82%,
      oklch(0.14 0.03 285 / 0) 100%
    );
  }
  .stage__sign {
    grid-row: 1;
    grid-column: content;
    z-index: 2;
    justify-self: start;
    align-self: end;
    color: var(--light);
    padding-block: clamp(2rem, 6vw, 4rem) clamp(1.25rem, 3.5vw, 2.5rem);
    text-shadow: 0 1px 2px oklch(0 0 0 / 0.35);
  }
  .stage__sign::before {
    /* the site's one mark, identical to the eyebrow and kicker marks */
    content: "";
    display: block;
    inline-size: 1.5rem;
    block-size: 0.5rem;
    margin-block-end: 0.85rem;
    background: var(--accent);
    clip-path: polygon(0.5rem 0, 100% 0, calc(100% - 0.5rem) 100%, 0 100%);
  }
  .stage__sign h1 {
    line-height: 1.04;
    text-wrap: balance;
  }
  .stage__sign h1 > span {
    /* hyphenate only at the real hyphen in Elektro-Spezialist, never
       mid-syllable as auto hyphenation did on narrow phones */
    -webkit-hyphens: manual;
    hyphens: manual;
  }
  .stage__sign .stage__lede {
    display: block;
    margin-block-start: clamp(0.7rem, 2vw, 1rem);
    max-inline-size: 62ch;
    font-family: var(--mono);
    font-size: clamp(0.8rem, 0.6rem + 0.9vw, 0.95rem);
    font-weight: 400;
    letter-spacing: 0.02em;
    line-height: 1.5;
    text-wrap: pretty;
    color: oklch(0.93 0.008 285 / 0.92);
  }
  /* the picture keeps covering the cell when a long title grows it:
     min-block-size wins over the 30rem cap, object-fit keeps the crop */
  .stage .placeband .pr-photo__open,
  .stage .placeband picture { display: block; block-size: 100%; }
  .stage .placeband img { min-block-size: 100%; }
  @media (width >= 40em) {
    /* the cap keeps the picture open to the right; below 40em the
       column is narrow enough on its own, and capping there would cost
       the group two more lines than the first screen has room for */
    .stage__sign {
      grid-column: content-start / span 9;
      max-inline-size: min(44rem, 78%);
    }
  }
  /* below the switch point the action row under the picture is gone
     (the dock carries it, Martin 11.09.); the next section keeps the
     same air under the picture that two sections keep between them */
  @media (width < 62.5em) {
    .stage + .section { padding-block-start: 4.5rem; }
  }

  .hero__lede {
    margin-block: 1.4rem 0;
    max-inline-size: 46ch;
    color: var(--ink-dark-soft);
  }

  /* --- page head of the subpages ------------------------------------ */
  .pagehead {
    /* bottom to top 1.5, same gate as the hero */
    padding-block: clamp(2.5rem, 1.9rem + 1.6vw, 3.5rem) clamp(3.75rem, 2.85rem + 2.4vw, 5.25rem);
    row-gap: 1.75rem;
  }
  .pagehead__body { grid-column: content-start / span 9; }

  /* --- button --------------------------------------------------------- */
  /* The radius belongs to the controls, the edge belongs to the
     surfaces: signs, labels, register rows and the drawing head stay
     at radius 0, only what you press is rounded. The slanted 45deg
     mark of the site lives on in the section marks, the navigation
     and the map pin, so the button no longer needs its cut corner. */
  .btn {
    display: inline-block;
    padding: 0.85rem 1.5rem;
    background: var(--accent);
    color: var(--btn-ink);
    font-family: var(--mono);
    font-size: var(--t3);
    font-weight: 500;
    letter-spacing: 0.02em;
    text-decoration: none;
    border: 0;
    border-radius: 10px;
    cursor: pointer;
    box-shadow: 0 1px 2px var(--shade-near);
    transition: background-color 130ms var(--ease), translate 90ms var(--ease),
      box-shadow 130ms var(--ease);
  }
  .btn:hover {
    background: var(--accent-press);
    translate: 0 -1px;
    box-shadow: 0 2px 3px var(--shade-near), 0 8px 18px var(--shade-far);
  }
  .btn:active { translate: 0 1px; box-shadow: 0 1px 2px var(--shade-near); }
  .btn:focus-visible { outline-offset: 3px; }

  .kicker {
    grid-column: content-start / span 8;
    margin-block-end: 1.6rem;
  }
  .kicker p { margin-block-start: 0.9rem; color: var(--ink-soft); }
  .band--dark .kicker p { color: var(--ink-dark-soft); }
  /* the services intro stands on one line on wide screens (Martin 09.09.) */
  @media (width >= 62.5em) {
    #leistungen .kicker { grid-column: content; }
    #leistungen .kicker p { max-inline-size: none; }
  }
  /* a head with a picture beside it: text left, picture right, the
     same split as the three reasons */
  .section--side .kicker { grid-column: content-start / span 7; margin-block-end: 0; }
  .side { grid-column: 9 / content-end; align-self: center; }
  @media (width < 56.25em) {
    .section--side .kicker { grid-column: content; }
    .side { grid-column: content; margin-block-start: 2rem; }
  }

  /* --- full-width picture band (contact page) ------------------------ */
  .strip img {
    inline-size: 100%;
    aspect-ratio: 21 / 9;
    max-block-size: 26rem;
    object-fit: cover;
  }
  @media (width < 40em) {
    .strip img { aspect-ratio: 3 / 2; }
  }

  /* --- images: one grammar, two formats ------------------------------ */
  .fig { position: relative; }
  .fig img { inline-size: 100%; object-fit: cover; }
  .fig--wide img { aspect-ratio: 3 / 2; }
  .fig--tall img { aspect-ratio: 4 / 5; }
  /* the caption speaks in the body voice, only greyed: measured on
     25.08. it was the fifth style in views that span two sections */
  .fig figcaption {
    margin-block-start: 0.6rem;
    font-size: var(--t4);
    letter-spacing: var(--ls4);
    line-height: 1.5;
    color: var(--ink-soft);
    max-inline-size: 56ch;
  }
  .band--dark .fig figcaption { color: var(--ink-dark-soft); }

  /* --- the three reasons (start page) -------------------------------- */
  .pledge__main { grid-column: content-start / span 7; }
  .pledge__fig { grid-column: 9 / content-end; align-self: start; }
  @media (width < 56.25em) {
    .pledge__main { grid-column: content; }
    .pledge__fig { grid-column: content; margin-block-start: 2rem; max-inline-size: 22rem; }
  }

  /* --- sheet: label/text rows with hairlines ------------------------- */
  .sheet {
    margin: 1.6rem 0 0;
    border-block-start: 1px solid var(--ink);
  }
  .pledge__main > .sheet { margin-block-start: 0; } /* first thing after the hero band (decision 84) */
  .sheet > div {
    display: grid;
    gap: 0.3rem clamp(1.5rem, 3vw, 2.75rem);
    padding-block: 1.15rem;
    border-block-end: 1px solid var(--rule);
  }
  @media (width >= 56.25em) {
    .sheet > div { grid-template-columns: minmax(0, 12rem) minmax(0, 1fr); }
    .sheet--wide > div { grid-template-columns: minmax(0, 21rem) minmax(0, 1fr); }
  }
  .sheet dt.label { color: var(--ink-soft); padding-block-start: 0.2rem; }
  .sheet dd { margin: 0; color: var(--ink); max-inline-size: 52ch; }
  .sheet dd .soft, .sheet dd small { color: var(--ink-soft); font-size: inherit; }
  /* question variant: the dt is a sentence, not a label */
  .sheet dt.q { font-weight: 600; line-height: 1.4; }
  .sheet--wide dd { color: var(--ink-soft); }

  /* --- service teasers (start page) ---------------------------------- */
  /* Name and one line each, in the same hairline rhythm as the sheet,
     but as a list so every entry can be its own editing zone: a button
     inside a definition list would not be valid markup. */
  .teasers { grid-column: content; border-block-start: 1px solid var(--ink); }
  .teasers > li {
    display: grid;
    gap: 0.3rem clamp(1.5rem, 3vw, 2.75rem);
    padding-block: 1.15rem;
    border-block-end: 1px solid var(--rule);
  }
  @media (width >= 56.25em) {
    .teasers > li { grid-template-columns: minmax(0, 21rem) minmax(0, 1fr); }
  }
  .teasers h3 {
    font-size: var(--t4);
    letter-spacing: var(--ls4);
    font-weight: 600;
    line-height: 1.4;
  }
  .teasers p { color: var(--ink-soft); max-inline-size: 52ch; }
  .teasers__more { grid-column: content; margin-block-start: 2rem; }

  /* --- place band (Ortsband): the opening image of the start page ----- */
  .placeband { inline-size: 100%; }
  .placeband img {
    inline-size: 100%;
    aspect-ratio: 21 / 9;
    /* on wide screens the band flattens toward 3:1 instead of growing:
       height is capped, object-fit keeps the crop honest, no vh anywhere */
    max-block-size: 30rem;
    object-fit: cover;
    object-position: 50% 55%;
    filter: saturate(1.08);
  }
  @media (width < 40em) {
    .placeband img { aspect-ratio: 4 / 3; }
  }
  /* desktop: a fixed 3:1 whatever the window height, no cap (Martin #105,
     decision 178); the phone keeps its 4:3 crop */
  @media (width >= 62.5em) {
    .placeband img { aspect-ratio: 3 / 1; max-block-size: none; }
  }
  /* --- steps (numbered sequences) ------------------------------------ */
  .steps { grid-column: content; border-block-start: 1px solid var(--ink); }
  .steps > li {
    display: grid;
    gap: 0.35rem clamp(1.5rem, 3vw, 2.75rem);
    padding-block: 1.4rem;
    border-block-end: 1px solid var(--rule);
  }
  @media (width >= 56.25em) {
    .steps > li { grid-template-columns: minmax(0, 8rem) minmax(0, 1fr); }
  }
  .steps b {
    font-family: var(--mono);
    font-size: var(--t6);
    letter-spacing: var(--ls6);
    font-variant-numeric: tabular-nums;
    color: var(--ink-soft);
    font-weight: 400;
  }
  .steps h3 { margin-block-end: 0.3rem; }
  .steps p { color: var(--ink-soft); }

  /* --- closing call (dark, carries the one big display number) ------- */
  .cta { row-gap: 0; }
  .cta__tel {
    grid-column: content;
    justify-self: start;
    margin-block-start: 1.9rem;
    font-family: var(--mono);
    font-size: var(--t8);
    letter-spacing: var(--ls8);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
    color: var(--ink-dark);
    text-decoration: none;
    border-block-end: 3px solid var(--accent);
    padding-block-end: 0.2rem;
    transition: color 120ms var(--ease);
  }
  .cta__tel:hover { color: inherit; }
  .cta__tel small {
    display: block;
    margin-block-end: 0.5rem;
    font-family: var(--mono);
    font-size: var(--t1);
    letter-spacing: 0.03em;
    line-height: 1.4;
    color: var(--ink-dark-soft);
  }
  .cta__acts {
    grid-column: content;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.25rem 2rem;
    margin-block-start: 2.1rem;
  }
  .cta__note {
    margin: 0;
    font-size: var(--t3);
    letter-spacing: var(--ls3);
    color: var(--ink-dark-soft);
    max-inline-size: 40ch;
  }

  /* --- team figure (duotone treatment arrives with the tool layer) ---- */
  .teamfig { grid-column: content-start / span 8; }
  .teamfig img { aspect-ratio: 3 / 2; }
  @media (width < 56.25em) {
    .teamfig { grid-column: content; }
  }

  /* --- form ------------------------------------------------------------ */
  .form { display: grid; gap: 1.4rem; max-inline-size: 34rem; }
  .form__field { display: grid; gap: 0.4rem; }
  .form label, .form legend { color: var(--ink-soft); padding: 0; }
  .form input[type="text"],
  .form input[type="tel"],
  .form input[type="email"],
  .form select,
  .form textarea {
    font: inherit;
    font-size: 1rem;
    color: var(--ink);
    background: var(--light);
    border: 1px solid var(--ink-soft);
    border-radius: 6px;
    padding: 0.7rem 0.8rem;
    inline-size: 100%;
    transition: border-color 130ms var(--ease), box-shadow 130ms var(--ease);
  }
  .form textarea { field-sizing: content; min-block-size: 3.5rem; resize: vertical; }
  .form input:hover, .form select:hover, .form textarea:hover { border-color: var(--ink); }
  .form input:focus-visible,
  .form select:focus-visible,
  .form textarea:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--ink);
  }
  .form input:user-invalid, .form select:user-invalid { border-color: var(--accent-deep); }
  .form fieldset { border: 0; padding: 0; margin: 0; display: grid; gap: 0.4rem; }
  .form__opts { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; margin-block-start: 0.3rem; }
  .form .form__opt {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--sans);
    font-size: var(--t3);
    font-weight: 400;
    letter-spacing: var(--ls3);
    text-transform: none;
    color: var(--ink);
    padding-block: 0.35rem;
    cursor: pointer;
  }
  .form__opt input { inline-size: 1.05rem; block-size: 1.05rem; margin: 0; }
  .form input[type="file"] {
    font-size: var(--t3);
    letter-spacing: var(--ls3);
    color: var(--ink-soft);
    padding-block: 0.35rem;
  }
  .form input[type="file"]::file-selector-button {
    margin-inline-end: 0.75rem;
    padding: 0.5rem 0.9rem;
    border: 1px solid var(--ink);
    border-radius: 2px;
    background: var(--light);
    color: var(--ink);
    font: inherit;
    cursor: pointer;
  }
  .form input[type="file"]:hover::file-selector-button { background: var(--light-2); }
  .form__note {
    font-size: var(--t3);
    letter-spacing: var(--ls3);
    line-height: 1.55;
    color: var(--ink-soft);
    margin: 0;
    max-inline-size: 40ch;
  }

  .contact { grid-column: content-start / span 7; }
  .contact__side { grid-column: 9 / content-end; }
  @media (width < 56.25em) {
    .contact { grid-column: content; }
    .contact__side { grid-column: content; margin-block-start: 2.75rem; }
  }
  .dlist { margin: 0; display: grid; gap: 0; border-block-start: 1px solid var(--ink); }
  .dlist div { padding-block: 0.9rem; border-block-end: 1px solid var(--rule); }
  .dlist dt { color: var(--ink-soft); }
  .dlist dd { margin: 0.3rem 0 0; }
  .dlist a {
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-underline-offset: var(--uo-s);
    text-decoration-thickness: 2px;
    padding-block: 0.35rem;
    display: inline-block;
  }
  .dlist a:hover { text-decoration-thickness: 2px; }

  /* --- map: static OSM cutout, framed like a technical document ------ */
  .map {
    grid-column: content;
    max-inline-size: 760px;
    margin-block-end: 2.25rem;
  }
  .map__frame {
    position: relative;
    border: 1px solid var(--ink);
  }
  .map__link { display: block; line-height: 0; }
  .map__link img { inline-size: 100%; height: auto; }
  /* own pin: needle plus the site's slanted 45deg mark as its head */
  .map__pin {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    /* needle tip sits at (15,46) of the fixed 40x48 box */
    translate: -15px -46px;
    pointer-events: none;
  }
  .map__needle { stroke: var(--dark); stroke-width: 2.5; }
  .map__head { fill: var(--accent); stroke: var(--dark); stroke-width: 1.5; }
  .map__addr {
    position: absolute;
    inset-block-start: 0.75rem;
    inset-inline-start: 0.75rem;
    margin: 0;
    padding: 0.45rem 0.7rem;
    background: var(--dark);
    color: var(--ink-dark);
    border-inline-start: 2px solid var(--accent-bright);
    font-family: var(--mono);
    font-size: var(--t3);
    letter-spacing: var(--ls3);
    line-height: 1.45;
    pointer-events: none;
  }
  /* ODbL attribution: not a removable pronta mark, stays always.
     Solid paper chip so the contrast holds on any map ground:
     ink on light = 14.28 (k1) / 15.82 (k2) / 13.27 (k3), computed. */
  @media (width < 40em) {
    .map__addr {
      inset-block-start: 0.5rem;
      inset-inline-start: 0.5rem;
      padding: 0.3rem 0.5rem;
      font-size: var(--t1);
      letter-spacing: 0;
    }
  }
  .map__attr {
    position: absolute;
    inset-block-end: 0;
    inset-inline-end: 0;
    margin: 0;
    padding: 0.1rem 0.45rem;
    background: var(--light);
    color: var(--ink);
    font-family: var(--mono);
    font-size: var(--t1);
    font-weight: 500;
    letter-spacing: var(--ls1);
    line-height: 1.5;
  }
  .map__attr a {
    display: inline-block;
    padding-block: 0.3rem;
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-underline-offset: var(--uo-s);
  }
  .map__attr a:hover { text-decoration-thickness: 2px; }

  /* --- footer: title block in the manner of a drawing head ----------- */
  .plate {
    background: var(--dark);
    color: var(--ink-dark);
    position: relative;
  }
  .plate__field {
    grid-column: content;
    margin-block: clamp(2.5rem, 1.5rem + 3vw, 4rem);
    border: 1px solid var(--rule-dark);
    display: grid;
    grid-template-columns: minmax(0, 1fr);
  }
  @media (width >= 40em) {
    .plate__field { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  @media (width >= 56.25em) {
    .plate__field { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  }
  .plate__cell {
    padding: 1.1rem 1.25rem 1.35rem;
    border-block-end: 1px solid var(--rule-dark);
    border-inline-end: 0;
  }
  @media (width >= 40em) {
    .plate__cell { border-inline-end: 1px solid var(--rule-dark); }
    .plate__cell:nth-child(2n) { border-inline-end: 0; }
    .plate__cell:nth-last-child(-n + 3):not(.plate__status) { border-block-end: 0; }
  }
  @media (width >= 56.25em) {
    .plate__cell:nth-child(2n) { border-inline-end: 1px solid var(--rule-dark); }
    .plate__cell:nth-child(4n) { border-inline-end: 0; }
    .plate__cell:not(.plate__status) { border-block-end: 0; }
  }
  .plate__label {
    color: var(--accent-bright);
    margin: 0 0 0.6rem;
  }
  .plate__cell p:not(.label), .plate__cell li { margin: 0; font-size: var(--t3); letter-spacing: var(--ls3); line-height: 1.6; }
  .plate__cell ul { display: grid; gap: 0.2rem; }
  .plate__cell a {
    text-decoration: underline;
    text-decoration-color: var(--rule-dark);
    text-underline-offset: var(--uo-s);
    text-decoration-thickness: 1px;
    padding-block: 0.35rem;
    margin-block: -0.35rem; /* tap height without shifting the line (Martin 09.09.) */
    display: inline-block;
    transition: text-decoration-color 130ms var(--ease);
  }
  .plate__cell a:hover { text-decoration-color: var(--accent-bright); }
  .plate__cell .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: var(--t3); }
  .plate__status {
    grid-column: 1 / -1;
    border-block-end: 0;
    border-inline-end: 0;
    border-block-start: 1px solid var(--rule-dark);
  }
  .plate__status p:not(.label) {
    font-size: var(--t3);
    letter-spacing: var(--ls3);
    line-height: 1.6;
    color: var(--ink-dark-soft);
    max-inline-size: 56ch;
  }
  .plate__status a { color: var(--ink-dark); }

  /* --- contact dock: the permanent contact path on phones ------------ */
  /* One bar at the bottom edge, two equal actions, thumb zone. Replaces
     the two edge tags that hung around the middle of the screen and
     jumped between layouts whenever the browser chrome changed the
     viewport height (decision 87). Hidden on desktop, where the header
     already carries phone and CTA. */
  .dock {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 30;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
    padding: 0.5rem 1rem calc(0.5rem + env(safe-area-inset-bottom, 0px));
    background: color-mix(in oklch, var(--dark) 94%, transparent);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border-block-start: 1px solid oklch(1 0 0 / 0.08);
  }
  .dock__btn {
    display: grid;
    place-items: center;
    min-block-size: 3rem;
    padding-inline: 0.75rem;
    border-radius: 10px;
    font-family: var(--mono);
    font-size: var(--t3);
    font-weight: 500;
    letter-spacing: 0.02em;
    text-decoration: none;
    color: var(--ink-dark);
    background: oklch(1 0 0 / 0.08);
    border: 1px solid oklch(1 0 0 / 0.18);
  }
  .dock__btn--cta {
    background: var(--accent);
    color: var(--btn-ink);
    border-color: transparent;
  }
  .dock__btn:active { translate: 0 1px; }
  @media (width >= 62.5em) { .dock { display: none; } }
  @media (width < 62.5em) {
    /* room for the dock, so the footer never hides behind it */
    body { padding-block-end: calc(4rem + 1px + env(safe-area-inset-bottom, 0px)); }
  }

  /* --- service blocks on the services page ---------------------------- */
  .svc {
    grid-column: content;
    display: grid;
    gap: 1.1rem clamp(1.5rem, 3vw, 2.75rem);
    padding-block: clamp(2rem, 1.4rem + 1.6vw, 2.75rem);
    border-block-end: 1px solid var(--rule);
  }
  .svc:first-of-type { border-block-start: 1px solid var(--ink); }
  /* the quality head further down shares the split of a service row:
     text left, the picture 18rem wide beside it (Martin 11.09.) */
  .beside { grid-column: content; display: grid; gap: 1.1rem clamp(1.5rem, 3vw, 2.75rem); }
  .beside .kicker { grid-column: auto; margin-block-end: 0; }
  @media (width >= 56.25em) {
    .svc, .beside { grid-template-columns: minmax(0, 46rem) minmax(0, 18rem); }
    .svc__fig, .beside .fig { align-self: start; }
  }
  /* Every row is built the same way and shows its picture from the
     first paint, on the phone too (Martin 23.09., feedback 51): the
     folds that used to hide the picture below 56.25em are gone, and
     with them the bullet lists and the technical labels. What a lay
     reader needs stands in the short text. */
  .svc__body > * + * { margin-block-start: 1rem; }

  /* --- two columns ----------------------------------------------------- */
  .duo { grid-column: content; display: grid; gap: 2rem clamp(1.5rem, 4vw, 3.5rem); }
  @media (width >= 56.25em) {
    .duo { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
  }
  .stack > * + * { margin-block-start: 1.1rem; }
  .stack ul { display: grid; gap: 0.45rem; max-inline-size: 52ch; }
  .stack li { padding-inline-start: 1.1rem; position: relative; }
  .stack li::before {
    content: "";
    position: absolute;
    inset-block-start: 0.72em;
    inset-inline-start: 0;
    inline-size: 0.5rem;
    block-size: 1px;
    background: var(--accent);
  }

  /* mobile: every content zone uses the full grid width */
  @media (width < 56.25em) {
    .kicker,
    .pagehead__body { grid-column: content; }
  }

  /* --- blocks the operator can take away ------------------------------ */
  /* Three keys, one attribute, one rule pair. A firm that does not want
     to publish its office hours, the inspection service
     or a team section at all switches the block off in the editing box;
     the boot snippet in <head> writes the chosen keys onto <html>
     before first paint, so a switched-off block never occupies a frame
     and costs no layout shift, and it is out of the accessible tree
     with it. While the editing layer is on it stays on the page at 45
     percent, because that is where its own switch lives. Without the
     tool layer nothing is ever hidden: data-marks only exists once the
     boot snippet has run. */
  html[data-hidden~="hours"][data-marks="off"] [data-hideable="hours"],
  html[data-hidden~="controls"][data-marks="off"] [data-hideable="controls"],
  html[data-hidden~="team"][data-marks="off"] [data-hideable="team"] {
    display: none;
  }
  html[data-hidden~="hours"]:not([data-marks="off"]) [data-hideable="hours"],
  html[data-hidden~="controls"]:not([data-marks="off"]) [data-hideable="controls"],
  html[data-hidden~="team"]:not([data-marks="off"]) [data-hideable="team"] {
    opacity: 0.45;
  }

  /* --- legal pages ------------------------------------------------------ */
  .prose { grid-column: content-start / span 8; }
  .prose h2 { margin-block: 2.5rem 0.9rem; }
  .prose h2:first-child { margin-block-start: 0; }
  .prose h3 { margin-block: 1.6rem 0.5rem; }
  .prose ul { display: grid; gap: 0.4rem; margin-block-end: 1.05em; max-inline-size: 52ch; }
  .prose li { padding-inline-start: 1.1rem; position: relative; }
  .prose li::before {
    content: "";
    position: absolute;
    inset-block-start: 0.72em;
    inset-inline-start: 0;
    inline-size: 0.5rem;
    block-size: 1px;
    background: var(--accent);
  }
  .prose a {
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-underline-offset: var(--uo-s);
    text-decoration-thickness: 2px;
    padding-block: 0.2rem;
  }
  .prose a:hover { text-decoration-thickness: 2px; }
  @media (width < 56.25em) {
    .prose { grid-column: content; }
  }
}

/* ------------------------------------------------------------------ */

@layer utilities {
  .vh {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
  .full { grid-column: full; }
}
