/* ==========================================================================
   Sümegi Gábor – víziközmű-tervezés
   Design system. Built from the Premium Web Design Field Manual, Steps 5–15.

   Section map:
     1. Tokens                    (Steps 5, 6, 7, 8, 9, 13 — Appendix A)
     2. Reset and base
     3. Layout primitives         (Step 5)
     4. Typography roles          (Step 7)
     5. Bands and density rhythm  (Step 4.4)
     6. Components                (Step 11)
     7. Content blocks
     8. Forms                     (Step 11.3)
     9. Responsive + a11y         (Steps 12, 14)
    10. Print
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */

:root {
  /* --- Width roles (5.1) ------------------------------------------------ */
  --gutter: clamp(1rem, 0.5rem + 2.5vw, 3rem);
  --container: 72rem;         /* standard marketing container            */
  --container-narrow: 38rem;  /* forms, FAQs, focused explanations       */
  --measure: 66ch;            /* reading measure, 45–75 char target      */
  --measure-lead: 48ch;
  --measure-heading: 22ch;

  /* --- Spacing scale (6.1) ---------------------------------------------- */
  --s1: 0.25rem;   /*  4px — optical correction only */
  --s2: 0.5rem;    /*  8px */
  --s3: 0.75rem;   /* 12px */
  --s4: 1rem;      /* 16px */
  --s5: 1.5rem;    /* 24px */
  --s6: 2rem;      /* 32px */
  --s7: 3rem;      /* 48px */
  --s8: 4rem;      /* 64px */
  --s9: 6rem;      /* 96px */

  /* --- Fluid section spacing (6.3) -------------------------------------- */
  --section-standard: clamp(4rem, 3rem + 4vw, 7rem);
  --section-large: clamp(5rem, 3.5rem + 6vw, 9rem);

  /* --- Type scale (7.2, 7.3) --------------------------------------------
     H1 narrow is 34px, below the manual's 38–52px narrow default.
     Deliberate: Hungarian compounds (csatornabekötés, csapadékvíz,
     engedélyezési) are 11–19 unbreakable characters. Per 7.7 the fix order is
     measure → wording → font size → tracking; wording is already shortened to
     the layman term, so font size is the next legitimate lever.            */
  --text-sm: clamp(0.875rem, 0.85rem + 0.12vw, 0.9375rem);
  --text-label: clamp(0.9375rem, 0.9rem + 0.15vw, 1.0625rem);
  --text-body: clamp(1.0625rem, 1.02rem + 0.2vw, 1.1875rem);
  --text-lead: clamp(1.1875rem, 1.1rem + 0.4vw, 1.375rem);
  --text-h4: clamp(1.1875rem, 1.13rem + 0.28vw, 1.375rem);
  --text-h3: clamp(1.375rem, 1.25rem + 0.6vw, 1.75rem);
  --text-h2: clamp(1.75rem, 1.45rem + 1.3vw, 2.5rem);
  --text-h1: clamp(2.125rem, 1.7rem + 1.9vw, 3.25rem);

  /* --- Color, semantic roles only (8.1) ---------------------------------
     Proportion target (8.2): ~85% neutral, ~10% cool surface tint,
     ~5% action blue. Contrast verified in 9. below.                       */
  --color-canvas: #fcfcfb;
  --color-surface: #ffffff;
  --color-surface-sunken: #edf0f3;
  --color-surface-dark: #12181e;

  --color-text: #15191d;
  --color-text-muted: #55606b;

  --color-border: #dde1e5;        /* decorative separators   */
  --color-border-input: #767f88;  /* 4.07:1 on white — a UI boundary (8.3) */

  --color-action: #12507e;        /* 8.49:1 on white */
  --color-action-hover: #0d3f65;
  --color-action-active: #0a3252;
  --color-on-action: #ffffff;

  --color-focus: #15191d;
  --color-success: #17603a;
  --color-danger: #a32219;

  /* --- Geometry (9.1, 9.2, 9.3) ----------------------------------------- */
  --radius-sm: 0.375rem;
  --radius-md: 0.75rem;
  --shadow-1: 0 1px 2px rgb(18 24 30 / 0.05), 0 4px 12px rgb(18 24 30 / 0.05);

  /* --- Motion (13.2, 13.3) ---------------------------------------------- */
  --duration-fast: 120ms;
  --duration-normal: 200ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* --- Type family (7.1) ------------------------------------------------
     One family. A system stack: full Hungarian coverage guaranteed, zero font
     files, zero render-blocking requests, no FOUT. See README for the
     trade-off against a self-hosted display face.                         */
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", "Noto Sans", Arial, sans-serif;
}

/* ==========================================================================
   2. RESET AND BASE
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--color-canvas);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

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

h1, h2, h3, h4, p, ul, ol, dl, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }

main { flex: 1 0 auto; }

/* Focus (14.2). Near-black ring with an offset, so the adjacent color is the
   page background in every case — 15:1 on canvas, 12:1 on the sunken tint. */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

::selection {
  background: var(--color-action);
  color: var(--color-on-action);
}

.skip-link {
  position: absolute;
  left: var(--s4);
  top: var(--s4);
  z-index: 100;
  padding: var(--s3) var(--s5);
  background: var(--color-text);
  color: var(--color-canvas);
  font-weight: 600;
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}
.skip-link:focus-visible { transform: none; }

/* ==========================================================================
   3. LAYOUT PRIMITIVES (Step 5)
   ========================================================================== */

.container {
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
}

.container-narrow {
  width: min(100% - 2 * var(--gutter), var(--container-narrow));
  margin-inline: auto;
}

.prose { max-inline-size: var(--measure); }
.prose p + p { margin-top: var(--s5); }

.section { padding-block: var(--section-standard); }
.section--large { padding-block: var(--section-large); }

/* Intrinsic card grid (5.5) */
.auto-grid {
  display: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(100%, var(--card-min, 17rem)), 1fr)
  );
  gap: clamp(1rem, 0.75rem + 1vw, 2rem);
}

/* Four-item sets break badly under auto-fit: at the 72rem container three
   tracks fit and the fourth card drops to a row of its own, so an even set
   reads as 3 + 1. This modifier caps the grid at two tracks, which keeps the
   set even (2 x 2) and gives each card a wider measure. Below the breakpoint
   the single column is unchanged. */
@media (min-width: 48rem) {
  .auto-grid--pairs { grid-template-columns: repeat(2, 1fr); }
}

/* Text + supporting column, 3:2 (5.4) */
.split {
  display: grid;
  gap: var(--s7);
}
@media (min-width: 60rem) {
  .split { grid-template-columns: 3fr 2fr; align-items: start; }
}

.stack > * + * { margin-top: var(--s5); }
.stack-loose > * + * { margin-top: var(--s6); }

/* ==========================================================================
   4. TYPOGRAPHY ROLES (Step 7)
   Nine visible roles, at the manual's 7–9 limit:
   eyebrow, h1, h2, h3, h4, lead, body, small/meta, label/button.
   ========================================================================== */

/* Now used only by the three status pages (/koszonom/, /kapcsolat-hiba/,
   404), where it carries state — "Elküldve", "Hiba", "404" — rather than a
   category label. The 31 section eyebrows it used to style were removed: they
   repeated the heading beneath them often enough that the whole device was not
   earning its place. */
.eyebrow {
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  line-height: 1.4;
}

h1 {
  font-size: var(--text-h1);
  line-height: 1.05;
  font-weight: 700;
  letter-spacing: -0.022em;
  max-inline-size: var(--measure-heading);
}

h2, .h2 {
  font-size: var(--text-h2);
  line-height: 1.12;
  font-weight: 700;
  letter-spacing: -0.018em;
  max-inline-size: 26ch;
}

h3, .h3 {
  font-size: var(--text-h3);
  line-height: 1.2;
  font-weight: 650;
  letter-spacing: -0.012em;
  max-inline-size: 34ch;
}

h4, .h4 {
  font-size: var(--text-h4);
  line-height: 1.28;
  font-weight: 650;
  letter-spacing: -0.008em;
}

/* Hungarian compounds are long and unbreakable. Hyphenation with lang="hu"
   is the real fix flagged in the brief's typographic warning (§3.3). */
h1, h2, h3, h4, .h2, .h3, .h4 {
  hyphens: auto;
  overflow-wrap: break-word;
  text-wrap: balance;
}

.lead {
  font-size: var(--text-lead);
  line-height: 1.5;
  color: var(--color-text-muted);
  max-inline-size: var(--measure-lead);
}

.meta {
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-text-muted);
  max-inline-size: var(--measure);
}

.muted { color: var(--color-text-muted); }

/* A footnote to the card grid above it, deliberately not a fourth option:
   small, muted, no button, no border.

   .meta caps itself at var(--measure) for readability, which is right for a
   paragraph and wrong for a single link that is supposed to sit at the far
   edge — the cap was holding it 528px short of the container. Released here,
   then pushed to the right end so it trails the grid instead of starting a
   new left-hand column of its own. */
.services__more {
  margin-top: var(--s6);
  max-inline-size: none;
  text-align: right;
}
/* Deliberately not link-coloured and not underlined at rest: this is an aside
   about scope, not an offer, and it sits directly under three cards that are
   the real choices. It inherits .meta's grey and earns colour only on pointing
   — the same muted → action move the card footers make, so the two read as one
   behaviour rather than two.

   Safe to strip the underline here because this is a standalone line ending in
   an arrow, not a link buried inside a sentence: there is no ambiguity about
   which words are clickable, which is what WCAG 1.4.1 actually guards against.
   Keyboard users are unaffected — the global :focus-visible ring still fires. */
.services__more a {
  /* The muted token by name rather than `inherit`. Same grey, but it survives
     being read out of context and does not depend on the parent's colour
     staying put. */
  color: var(--color-text-muted);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-out);
}
.services__more a:hover { color: var(--color-action); }
/* Keyboard focus gets the underline back. The ring alone marks position, but
   the underline is what says "link" — and a keyboard user never saw the hover
   state that would otherwise have told them. */
.services__more a:focus-visible {
  color: var(--color-action);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

strong, b { font-weight: 650; }

a {
  color: var(--color-action);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
a:hover { color: var(--color-action-hover); }

/* A link sitting inside a sentence of muted body copy. It keeps the sentence's
   colour so the line still reads as one voice, but keeps the underline — unlike
   `.services__more a` this one IS buried mid-sentence, so the underline is the
   only thing marking which words are clickable (WCAG 1.4.1). Hover moves the
   colour to the action token, the same travel the rest of the site uses. */
.link-quiet {
  color: var(--color-text-muted);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  transition: color var(--duration-fast) var(--ease-out);
}
.link-quiet:hover { color: var(--color-action); }
.link-quiet:focus-visible { color: var(--color-action); }

/* ==========================================================================
   5. BANDS AND DENSITY RHYTHM (Step 4.4)
   Sections alternate treatment so no two neighbours read the same.
   ========================================================================== */

.band--tint { background: var(--color-surface-sunken); }

.band--dark {
  background: var(--color-surface-dark);
  color: #f4f6f8;
  /* Role inversion, not a new palette (8.6): on dark, the action surface is
     light and the action text is dark. Same role, inverted values. */
  --color-text: #f4f6f8;
  --color-text-muted: #b3bcc5;   /* 9.29:1 on the dark surface */
  --color-action: #ffffff;
  --color-action-hover: #dde5ec;
  --color-action-active: #c6d2dc;
  --color-on-action: #12181e;
  --color-border: #3d4753;
  --color-focus: #ffffff;
  /* The surface role inverts too. Without this a `.card` in a dark band keeps
     the light surface and renders its inverted (near-white) text on white.
     A raised dark surface keeps the card readable and still reads as sitting
     on top of the band: #f4f6f8 on #1c242c is 14.2:1, muted 8.2:1. */
  --color-surface: #1c242c;
  --color-border-input: #8a949e;  /* 5.4:1 on the raised surface */
}

/* ==========================================================================
   6. COMPONENTS (Step 11)
   ========================================================================== */

/* --- 6.1 Buttons (11.1) ------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 48px;
  padding: var(--s3) var(--s5);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-label);
  font-weight: 650;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}

.btn--primary {
  background: var(--color-action);
  color: var(--color-on-action);
}
.btn--primary:hover { background: var(--color-action-hover); color: var(--color-on-action); }
.btn--primary:active { background: var(--color-action-active); }

.btn--secondary {
  background: transparent;
  color: var(--color-action);
  border-color: var(--color-action);
}
.btn--secondary:hover { background: rgb(18 80 126 / 0.07); color: var(--color-action-hover); }
.band--dark .btn--secondary:hover { background: rgb(255 255 255 / 0.12); }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  align-items: center;
}

/* --- 6.2 Header (11.5) --------------------------------------------------
   No hamburger, no JavaScript, nothing hidden. At narrow widths the five
   destinations wrap to two rows. Manual 2.4: do not hide desktop content on
   mobile merely because the layout is crowded.                            */

.site-header {
  position: relative;   /* containing block for the dropdown panel */
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

/* Below the width where the five destinations fit on the logo's row, the nav
   is a dropdown; above it, a plain inline row. These are two separate elements
   swapped at the breakpoint, not one element restyled — see §9.
   Zero JavaScript: <details>/<summary> is the native disclosure element, so
   keyboard operation, Escape, and screen-reader state come for free. */
.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3) var(--s6);
  padding-block: var(--s3);
}

.brand {
  display: block;
  text-decoration: none;
  color: var(--color-text);
  margin-right: auto;
  order: 1;
}
.header-cta { order: 2; }
/* Static, not relative: the panel below anchors to .site-header, so it cannot
   be dragged off-screen by wherever the toggle happens to wrap to. */
.nav-details { order: 3; position: static; }
/* Below the breakpoint the disclosure is the menu, so the inline row is out.
   display:none, not visibility/clip: it must leave the accessibility tree too,
   or a screen reader meets two Főmenü landmarks.

   order is declared here rather than only in the desktop block on purpose. A
   <nav> defaults to order:0 and .brand is order:1, so any state where this
   element renders without the desktop rules — a stale cached stylesheet
   against fresh markup, most likely — lays the menu out BEFORE the logo.
   Pinning the order in the base rules makes that failure invisible instead of
   spectacular. */
.site-nav--bar { display: none; order: 2; }

/* --- The toggle ---------------------------------------------------------- */

.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;
  padding: var(--s2) var(--s4);
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: var(--text-label);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.nav-toggle::-webkit-details-marker { display: none; }
.nav-toggle:hover { border-color: var(--color-text-muted); }

/* Three bars, drawn without an icon font or an SVG request. The middle bar is
   the element's own background; the outer two are box-shadows. */
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 1.125rem;
  height: 2px;
  background: var(--color-text);
  border-radius: 1px;
}
.nav-toggle__bars {
  position: relative;
  transition: background-color var(--duration-fast) var(--ease-out);
}
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
  transition: transform var(--duration-normal) var(--ease-out);
}
.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after { top: 6px; }

/* Open state: bars become an X. State is also carried by the native
   aria-expanded on <summary>, so this is not color- or shape-only (14.3). */
.nav-details[open] .nav-toggle__bars { background: transparent; }
.nav-details[open] .nav-toggle__bars::before { transform: translateY(6px) rotate(45deg); }
.nav-details[open] .nav-toggle__bars::after { transform: translateY(-6px) rotate(-45deg); }

/* --- The dropdown panel -------------------------------------------------- */

/* Anchored to the header, spanning its full width, so it never overflows the
   viewport at any width and never depends on where the toggle wrapped to.
   The links are inset to the container gutter so they line up with the brand. */
.nav-details[open] > .site-nav {
  position: absolute;
  inset-inline: 0;
  top: 100%;
  z-index: 30;
  padding: var(--s2) 0 var(--s3);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--shadow-2);   /* elevation 2: dropdown (9.3) */
}
/* nowrap: this is a vertical list, and the inherited wrap let the flex
   container distribute stray space into some rows (48px links inside 66px
   items) so the menu read as unevenly spaced. */
.nav-details[open] > .site-nav ul {
  flex-direction: column;
  flex-wrap: nowrap;
  gap: 0;
}
.nav-details[open] > .site-nav li { display: block; }
.nav-details[open] > .site-nav a {
  display: flex;
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
  min-height: 48px;
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
}
.nav-details[open] > .site-nav a:hover {
  background: var(--color-surface-sunken);
  text-decoration: none;
}
/* Current page inside the panel: the inset underline reads as an artefact in
   a vertical list, so switch to a leading bar. Weight still carries it too. */
.nav-details[open] > .site-nav a[aria-current="page"] {
  box-shadow: inset 3px 0 0 var(--color-action);
  background: var(--color-surface-sunken);
}
.brand__name {
  display: block;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.brand__role {
  display: block;
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  letter-spacing: 0.02em;
  line-height: 1.3;
  margin-top: 2px;
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--s5);
}
.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--color-text);
  font-size: var(--text-label);
  font-weight: 500;
  text-decoration: none;
}
.site-nav a:hover { text-decoration: underline; text-underline-offset: 0.2em; }

/* Current location, not by color alone (11.5, 14.3): a weight change plus a
   rule beneath, plus aria-current in the markup. */
.site-nav a[aria-current="page"] {
  font-weight: 700;
  box-shadow: inset 0 -2px 0 var(--color-action);
}

.header-cta { flex-shrink: 0; }

/* --- 6.3 Cards (11.4) --------------------------------------------------- */

.card {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s5);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.card__title { font-size: var(--text-h4); }
.card__title a { text-decoration: none; color: var(--color-text); }
/* No underline on the title: the card's reaction now lives on .card__foot
   below, which is the line that actually names where the card goes. */
.card__title a:hover { text-decoration: none; }
.card p { color: var(--color-text-muted); }
.card__foot {
  margin-top: auto;
  padding-top: var(--s3);
  font-weight: 650;
  font-size: var(--text-label);
  /* Colour is inherited from `.card p` (muted) rather than set here, so the
     hover rule below has something to travel from. The transition lives here
     because it applies in both directions. */
  transition: color var(--duration-fast) var(--ease-out);
}

/* Whole card is one destination and holds no nested controls, so the whole
   surface is the target (11.4). */
.card--linked { position: relative; transition: border-color var(--duration-fast) var(--ease-out); }
.card--linked:hover { border-color: var(--color-border-input); }
/* Pointing at the card promotes its footer from muted to the action role, so
   the line that names the destination is the part that lights up.
   :focus-within is not optional here — the whole card is one link, so a
   keyboard visitor lands on the title and would otherwise get the border
   change with no confirmation of where they are. Same cue, both input
   methods (14.3: the state is also carried by the focus ring and the title
   underline, never by colour alone). */
.card--linked:hover .card__foot,
.card--linked:focus-within .card__foot {
  color: var(--color-action);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.card--linked .card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-md);
}

/* Cards that are not destinations. The vízjogi "Kapcsolódó tervezői feladatok"
   grid is the only such set on the site: four cards of copy, no link inside
   them. They were the one component here that answered the pointer with
   nothing at all, which reads as a rendering fault sitting next to the linked
   grids rather than as restraint.

   The response is deliberately a weaker relative of .card--linked's, not a
   copy of it: the border firms to the UI boundary and the surface lifts onto
   --shadow-1, but no colour travels to the action role and nothing underlines.
   Elevation says "surface", the action blue says "destination" — keeping the
   two apart is what stops these cards from promising a click they cannot
   honour (11.4).

   §9's blanket reduced-motion rule flattens the duration but would leave the
   2px lift snapping into place, so the transform is dropped outright there. */
.card:not(.card--linked) {
  transition: border-color var(--duration-normal) var(--ease-out),
              box-shadow var(--duration-normal) var(--ease-out),
              transform var(--duration-normal) var(--ease-out);
}
.card:not(.card--linked):hover {
  border-color: var(--color-border-input);
  box-shadow: var(--shadow-1);
  transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
  .card:not(.card--linked):hover { transform: none; }
}

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

/* One centred identity line over the company data the law requires. The three
   link columns that used to sit here repeated the header nav word for word, and
   the full company name and seat address are on /adatkezeles/ — the footer only
   has to name the firm and stay findable. */

.site-footer {
  background: var(--color-surface-dark);
  color: #f4f6f8;
  padding-block: var(--s6);
  text-align: center;
  --color-text-muted: #b3bcc5;
  --color-border: #333c45;
  --color-focus: #ffffff;
  --color-action: #ffffff;
  --color-action-hover: #dde5ec;
  --color-on-action: #12181e;
}
.site-footer a { color: #ffffff; }
.site-footer__company { font-weight: 700; letter-spacing: 0.02em; }
.site-footer__legal {
  margin-top: var(--s2);
  margin-inline: auto;
  max-inline-size: 54ch;
  font-size: var(--text-sm);
  line-height: 1.7;
  color: #b3bcc5;
}

/* ==========================================================================
   7. CONTENT BLOCKS
   ========================================================================== */

/* --- 7.1 Hero (Appendix B: orientation hero) ---------------------------- */

.hero { padding-block: var(--section-large) var(--section-standard); }
.hero h1 { margin-bottom: var(--s5); }
.hero .lead { margin-bottom: var(--s6); }
/* Only when something follows. The proof-cue list used to sit under the
   buttons on every service hero; with it gone the btn-row is last, and an
   unconditional margin would pad the hero out with nothing in the gap. */
.hero .btn-row:not(:last-child) { margin-bottom: var(--s6); }

.hero--narrow h1 { max-inline-size: 20ch; }

/* --- 7.2 Trust strip ---------------------------------------------------- */

.trust-strip {
  display: grid;
  gap: var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}
.trust-strip__item { border-left: 2px solid var(--color-action); padding-left: var(--s4); }
.trust-strip__value { display: block; font-size: var(--text-h4); font-weight: 700; line-height: 1.2; }
.trust-strip__label { display: block; font-size: var(--text-sm); color: var(--color-text-muted); margin-top: var(--s1); }

/* --- 7.3 Steps (Appendix B: mechanism or process) ----------------------- */

.steps { counter-reset: step; }
.steps > li {
  counter-increment: step;
  position: relative;
  padding-left: calc(var(--s8) - var(--s2));
  padding-bottom: var(--s6);
}
.steps > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--color-action);
  color: var(--color-on-action);
  font-size: var(--text-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Connector line between steps. Decorative only; the ordered list carries
   the sequence for assistive technology. */
.steps > li::after {
  content: "";
  position: absolute;
  left: calc(1.125rem - 1px);
  top: 2.75rem;
  bottom: var(--s2);
  width: 2px;
  background: var(--color-border);
}
.steps > li:last-child { padding-bottom: 0; }
.steps > li:last-child::after { display: none; }
.steps h3 { font-size: var(--text-h4); margin-bottom: var(--s2); }
.steps p { color: var(--color-text-muted); max-inline-size: var(--measure); }

/* --- 7.4 Timeline (the differentiating block) ---------------------------
   A list, not a table: the rows are independent components of a total, not
   values to compare across columns, so it reflows to 320px without loss. */

.timeline {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  overflow: hidden;
}
.timeline__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s5);
  align-items: baseline;
  justify-content: space-between;
  padding: var(--s4) var(--s5);
}
.timeline__row + .timeline__row { border-top: 1px solid var(--color-border); }
.timeline__label { font-weight: 600; flex: 1 1 14rem; }
.timeline__note {
  display: block;
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--color-text-muted);
  margin-top: var(--s1);
}
/* The value is a duration plus its "who controls this" tag. It must wrap as a
   unit at 200% text — nowrap here forced horizontal scrolling. */
.timeline__value {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.timeline__row--total {
  background: var(--color-surface-sunken);
  border-top: 2px solid var(--color-text) !important;
  font-size: var(--text-h4);
}
.timeline__row--total .timeline__label,
.timeline__row--total .timeline__value { font-weight: 700; }

/* Who controls the wait. Text label, never color alone (14.3). */
.tag {
  display: inline-block;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 2px var(--s2);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-input);
  color: var(--color-text-muted);
}
.tag--own { border-color: var(--color-action); color: var(--color-action); }

/* --- 7.5 Scope boundary: what the fee covers, and what it does not ------
   Meaning is carried by the two headings, not by color or icon (14.3). */

.scope {
  display: grid;
  gap: var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}
.scope__col {
  padding: var(--s5);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
}
.scope__col--excluded { background: transparent; border-style: dashed; }
.scope__col h3 { font-size: var(--text-h4); margin-bottom: var(--s4); }
.scope__list li {
  position: relative;
  padding-left: var(--s6);
  color: var(--color-text-muted);
}
.scope__list li + li { margin-top: var(--s3); }
.scope__list li::before {
  position: absolute;
  left: 0;
  top: 0;
  font-weight: 700;
}
.scope__col--included .scope__list li::before { content: "✓"; color: var(--color-success); }
.scope__col--excluded .scope__list li::before { content: "✕"; color: var(--color-danger); }

/* --- 7.6 Plain scannable list (homepage section 7) ----------------------
   No cards, no links. One block instead of ten thin pages.               */

.term-list {
  columns: 2;
  column-gap: var(--s7);
  max-inline-size: 56rem;
}
@media (max-width: 40rem) { .term-list { columns: 1; } }
.term-list li {
  break-inside: avoid;
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-muted);
}

/* --- 7.7 Settlement list ------------------------------------------------ */

.pill-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s3);
}
.pill-list li {
  padding: var(--s2) var(--s4);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  font-size: var(--text-label);
}

/* --- 7.8 FAQ (Appendix B: objection section) ---------------------------
   <details> is native and needs no JavaScript. Used only where the content
   is optional depth. Never used for timelines — 2.4: decision-critical facts
   stay visible.                                                           */

.faq { max-inline-size: 44rem; }
.faq details {
  border-bottom: 1px solid var(--color-border);
}
.faq summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s5) 0;
  min-height: 48px;
  font-size: var(--text-h4);
  font-weight: 650;
  line-height: 1.35;
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  flex-shrink: 0;
  width: 0.75rem;
  height: 0.75rem;
  margin-top: 0.4em;
  border-right: 2px solid var(--color-action);
  border-bottom: 2px solid var(--color-action);
  transform: rotate(45deg);
  transition: transform var(--duration-normal) var(--ease-out);
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq summary:hover { color: var(--color-action); }
.faq__answer { padding-bottom: var(--s5); color: var(--color-text-muted); max-inline-size: var(--measure); }
.faq__answer > * + * { margin-top: var(--s4); }

/* --- 7.9 Callout -------------------------------------------------------- */

.callout {
  padding: var(--s5) var(--s6);
  border-left: 3px solid var(--color-action);
  background: var(--color-surface-sunken);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  max-inline-size: 46rem;
}
/* The box may be wide; its text may not. Without this a callout paragraph
   runs to ~95 characters per line, well past the 45–75 target. */
.callout > * { max-inline-size: var(--measure); }
.band--tint .callout { background: var(--color-surface); }

/* --- 7.10 Section head -------------------------------------------------- */

.section-head { margin-bottom: var(--s7); }
.section-head .lead { margin-top: var(--s4); }

/* --- 7.11 Placeholder for unresolved facts (§6 of the brief) ------------
   Deliberately loud. Nothing here may ship. See README, "Open questions". */

.todo {
  display: inline-block;
  padding: 1px var(--s2);
  background: #ffe8a3;
  color: #5c4600;
  border: 1px dashed #9a7b00;
  border-radius: 3px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.85em;
  font-weight: 600;
}
.band--dark .todo, .site-footer .todo { color: #5c4600; }

/* ==========================================================================
   8. FORMS (11.3)
   ========================================================================== */

.form { max-inline-size: 34rem; }

/* Honeypot. Removed from layout, from the tab order and from the
   accessibility tree — a real visitor can never reach it, so anything in it
   came from a bot. Zero JavaScript. Not display:none, which some bots skip. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.field + .field { margin-top: var(--s5); }
.field-group + .field-group { margin-top: var(--s7); }

.field label {
  display: block;
  font-size: var(--text-label);
  font-weight: 600;
  margin-bottom: var(--s2);
}
.field__hint {
  display: block;
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--color-text-muted);
  margin-top: 2px;
}
.field__req { color: var(--color-danger); font-weight: 700; }

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 48px;
  padding: var(--s3) var(--s4);
  font: inherit;
  font-size: 1.0625rem;         /* ≥16px: prevents iOS zoom-on-focus */
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border-input);
  border-radius: var(--radius-sm);
  transition: border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.field textarea { min-height: 8rem; resize: vertical; line-height: 1.6; }

.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%2355606b' stroke-width='2'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s4) center;
  padding-right: var(--s7);
}

.field input:hover,
.field select:hover,
.field textarea:hover { border-color: var(--color-text-muted); }

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--color-action);
  box-shadow: inset 0 0 0 1px var(--color-action);
}

/* Error state. :user-invalid fires only after the user has interacted, so
   fields are never red before they have been touched. Pairs a border with a
   message — never color alone (14.3). */
.field input:user-invalid,
.field select:user-invalid,
.field textarea:user-invalid {
  border-color: var(--color-danger);
  box-shadow: inset 0 0 0 1px var(--color-danger);
}
.field__error {
  display: none;
  margin-top: var(--s2);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-danger);
}
.field:has(:user-invalid) .field__error { display: block; }

.form__submit { margin-top: var(--s7); }
.form__note { margin-top: var(--s4); font-size: var(--text-sm); color: var(--color-text-muted); max-inline-size: 34rem; }

/* Status panel used by /koszonom/ and /kapcsolat-hiba/ */
.status {
  padding: var(--s6);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  border-left: 4px solid var(--color-success);
}
.status--error { border-left-color: var(--color-danger); }

/* ==========================================================================
   9. RESPONSIVE + ACCESSIBILITY (Steps 12, 14)
   ========================================================================== */

/* Content pressure, not a device name, sets this breakpoint. Measured: the
   five destinations need 632px, the brand 124px and the call button 189px —
   1010px of content, plus two ~36px gutters. 70rem (1120px) clears that with
   margin; 64rem does not, which is why the obvious round number is wrong here.
   Above it the whole disclosure is removed and the inline row takes over.

   This used to force the CLOSED <details> to render its contents instead, via
   ::details-content plus a display:block "fallback" for the other engines.
   ::details-content is Safari 18.4+ and Firefox 139+, and the fallback does
   nothing at all in those engines — the content sits in a shadow slot that
   author CSS on the child cannot reveal. So on any older Safari or Firefox the
   nav computed to zero width while the toggle was already hidden: no menu on
   desktop, at all. Swapping two elements has no such dependency and needs no
   engine-specific declarations. */
@media (min-width: 70rem) {
  .site-header__inner { flex-wrap: nowrap; padding-block: var(--s4); }
  /* Brand pinned to the container's left edge, CTA to its right, nav centred
     in whatever is left between them.

     The brand's margin-right:auto is released here so the nav's two auto
     margins are the only ones competing: flex then splits the free space
     equally on either side of it. Previously the brand kept an auto margin
     too, so the space was shared between brand-right and nav-left and the nav
     ended up shoved against the CTA (199px of air on its left, 33px on its
     right).

     Note this centres the nav between the brand and the CTA, not in the
     container — those two are 124px and 186px wide, so the two are not the
     same thing. Between them is what was asked for and what reads correctly. */
  .brand { margin-right: 0; }
  .site-nav--bar { display: block; margin-inline: auto; }
  .nav-details { display: none; }
  .header-cta { order: 3; }
}

@media (max-width: 30rem) {
  .btn { width: 100%; }
  .btn-row { flex-direction: column; align-items: stretch; }
  /* The header call button keeps its own width so the brand and the menu
     toggle can sit beside it; this is a phone-first business and the number
     should not be pushed below the fold by its own prominence. */
  .site-header .btn { width: auto; padding-inline: var(--s3); }
}

/* Below the width where brand + call button + toggle share a row (measured at
   ~34rem), the call button takes its own full-width row. That keeps the menu
   toggle beside the brand and makes the number the biggest target on screen —
   correct for a business where the phone is the primary action. */
@media (max-width: 34rem) {
  .header-cta { order: 4; flex-basis: 100%; width: 100%; }
  .site-header .header-cta { width: 100%; }
}

/* 13.5 — component-level would be better where motion carries state, but no
   motion on this site carries state, so the blanket reduction is correct. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media (prefers-contrast: more) {
  :root {
    --color-text-muted: #33393f;
    --color-border: #767f88;
  }
}

/* ==========================================================================
   10. PRINT
   Quotes and process pages get printed and taken to the vízmű.
   ========================================================================== */

@media print {
  .site-header__inner, .site-nav, .btn, .skip-link { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  /* Reset the inverted roles rather than overpainting them, so nested
     components (cards) come back to paper colours with their text. */
  .band--dark, .site-footer {
    background: #fff !important;
    color: #000 !important;
    --color-text: #000;
    --color-text-muted: #333;
    --color-surface: #fff;
    --color-border: #999;
  }
  .site-footer a, .band--dark a { color: #000 !important; }
  .band--dark .card { background: #fff !important; border-color: #999 !important; }
  .section { padding-block: 1.5rem; }
  /* Force every FAQ answer open on paper. Chrome hides collapsed content with
     content-visibility on the internal slot, so display alone is not enough. */
  .faq details { display: block; }
  .faq details::details-content { content-visibility: visible !important; }
  .faq__answer { display: block !important; content-visibility: visible !important; }
  .faq summary::after { display: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}
