/*
Theme Name: Kanzlei Veeckman
Description: Custom block theme for Rechtsanwältin Verena Veeckman (Migrationsrecht, Asylrecht, Sozialrecht), Darmstadt. Not for redistribution.
Author: Daniel Veeckman
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 8.1
Version: 0.2.2
License: Proprietary
Text Domain: veeckman-recht
*/

/* This file's WordPress-required header comment above is the whole reason
   it exists — a "classic" theme would put all CSS here, but a block theme
   puts colors/fonts/spacing in theme.json instead (so the block editor UI
   can offer them as choices) and only uses this file for CSS that theme.json
   genuinely can't express — here: the diagonal hero cut, the card/pill
   shapes, and other custom-drawn bits ported from
   ../../design/mockups/07-dunkel-diagonaler-hero.html now that Phase 4 has
   a live instance to check them against. Uses the color variables
   theme.json generates from its palette (--wp--preset--color--<slug>) so
   there is exactly one place the actual colors are defined. */

/* One centering rule, reused everywhere the mockup used class="wrap" —
   deliberately NOT using WP's own `layout: constrained` block attribute for
   this: that only centers a block's *children*, not the block itself, and
   fighting it with our own display:grid/flex caused the "not centered" bug
   caught 2026-08-24. Explicit CSS here instead — same technique the mockup
   used, one rule, no surprises.

   The column width itself is a single constant, defined once — in
   theme.json's settings.layout.contentSize, not here. WordPress compiles
   that into the --wp--style--global--content-size variable used below, so
   changing that one theme.json value changes it everywhere at once: this
   CSS, and the width guides the Block Editor itself shows. Never hardcode
   960px anywhere else in this file. */
.wrap { max-width: var(--wp--style--global--content-size); margin: 0 auto; padding: 0 1.25rem; }

.site-header {
	position: sticky;
	top: 0;
	z-index: 10;
	background: var(--wp--preset--color--header-bg);
	color: var(--wp--preset--color--cream);
	border-bottom: 1px solid var(--wp--preset--color--header-border);
}
.header-bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem 0.75rem;
	padding: 0.65rem 1.25rem;
	max-width: var(--wp--style--global--content-size);
	margin: 0 auto;
}
.brand a { color: inherit; text-decoration: none; font-weight: 600; white-space: nowrap; }
.header-contact { display: flex; flex-wrap: wrap; align-items: center; gap: 0.9rem; row-gap: 0.2rem; font-size: 0.85rem; }
.header-contact p { margin: 0; }
.header-contact a { color: inherit; text-decoration: none; }
.header-contact a:hover { text-decoration: underline; }

/* Second row, below header-bar — separate bar on purpose, not squeezed
   into the same row as the contact info (see note in parts/header.html).
   Two independent nav blocks inside, pushed to opposite ends: main menu
   (hamburger on narrow screens) left, language switcher right — on both
   mobile and desktop, which is what gives desktop its visual gap between
   them for free. */
.nav-bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	border-top: 1px solid var(--wp--preset--color--header-border);
	max-width: var(--wp--style--global--content-size);
	margin: 0 auto;
	padding: 0.5rem 1.25rem;
	font-size: 0.9rem;
}
.primary-nav a, .lang-nav a { color: inherit; text-decoration: none; }
.primary-nav a:hover, .lang-nav a:hover { text-decoration: underline; }
.lang-nav ul { display: flex; gap: 0.9rem; margin: 0; padding: 0; list-style: none; }
.lang-nav a[aria-current] { font-weight: 700; text-decoration: underline; text-underline-offset: 0.25em; }

.hero-diagonal {
	background: var(--wp--preset--color--green-deep);
	color: var(--wp--preset--color--cream);
	padding: 2.75rem 0 6rem;
	clip-path: polygon(0 0, 100% 0, 100% 88%, 0 100%);
}
.hero-diagonal .kicker {
	text-transform: uppercase;
	letter-spacing: 0.06em;
	font-size: 0.82rem;
	color: #cfe3d7;
	margin-bottom: 0.9rem;
}
.hero-diagonal h1 {
	font-size: clamp(2rem, 5.5vw, 3.3rem);
	max-width: 16ch;
	line-height: 1.08;
	margin: 0 0 1rem;
	display: flex;
	flex-direction: column;
}
.hero-diagonal h1 .role-line { color: var(--wp--preset--color--green-bright); }
.hero-diagonal h1 .name-line { color: var(--wp--preset--color--cream); }
.hero-diagonal .lead { max-width: 46ch; font-size: 1.05rem; color: #d8e6dd; margin: 0 0 1.3rem; }
.cta-light {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.75rem 1.4rem;
	background: var(--wp--preset--color--cream);
	color: var(--wp--preset--color--green-deep);
	text-decoration: none;
	border-radius: 999px;
	font-weight: 700;
}

.cards {
	display: grid;
	gap: 1rem;
	grid-template-columns: 1fr;
	padding: 2.5rem 0;
	/* sits inside a .wrap div in the markup — no width rule needed here */
}
@media (min-width: 700px) { .cards { grid-template-columns: repeat(3, 1fr); } }
.card {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	padding: 1.25rem 1.3rem;
	background: var(--wp--preset--color--card-bg);
	color: var(--wp--preset--color--card-text);
	border-radius: 8px;
	text-decoration: none;
	border: 1px solid var(--wp--preset--color--card-border);
}
.card h3 { font-size: 1.05rem; margin: 0; }
.card .arrow { color: var(--wp--preset--color--accent); font-size: 1.15rem; font-weight: 700; }

/* Deliberately transparent — matches the dark canvas behind it. The visible
   light card is `.accent-block .wrap`, sized to the .wrap content column
   (960px), not the full-bleed .accent-block itself. This exact split is
   the fix for the "trust block ran edge-to-edge" bug caught earlier on
   mockup 03 — see design/mockups/README.md. */
.accent-block { margin: 0 0 2.5rem; }
.accent-block .wrap {
	background: #f2f1ec;
	color: #232725;
	padding: 1.75rem 2rem;
	border-radius: 10px;
}
.accent-block h2 { font-size: 1.3rem; }
.accent-block .grid { display: flex; flex-wrap: wrap; gap: 1.2rem; }
.accent-block .grid p { flex: 1 1 260px; margin: 0; font-size: 0.95rem; }

/* Auch als Block-Style registriert (functions.php, Label "Hinweis") -- der
   Editor ergänzt dann "is-style-access-note" statt der handgetippten
   Klasse. Beide bleiben nötig: page-kontakt.html setzt den Kasten z.B. noch
   als rohes <div class="access-note"> im Template, wo kein Block und damit
   auch kein is-style-* existieren kann. :is() hält beide Schreibweisen auf
   einer Regel bei gleicher Spezifität -- :where() wäre 0 und theme.json
   würde einzelne Regeln (z.B. Absatz-Abstand) überschreiben. */
:is(.access-note, .is-style-access-note) {
	padding: 1rem 1.2rem;
	border-left: 3px solid var(--wp--preset--color--accent);
	background: #f2f1ec;
	color: #232725;
	font-size: 0.9rem;
	/* !important, 2026-09-01: on Kontakt this note is the LAST block inside
	   post_content, before the Eingangstool box (a separate sibling .wrap,
	   not inside the same flow container). WordPress's own global style
	   ":root :where(.is-layout-flow) > :last-child { margin-block-end: 0 }"
	   uses two pseudo-classes -> higher specificity than a single class
	   here, and was silently zeroing this gap (found by Daniel: no space
	   above the Eingangstool form). Same category of bug as the
	   .topic-grid-wrap margin-top fix above, mirrored for the opposite
	   margin/child position. */
	margin-bottom: 2.5rem !important;
}
:is(.access-note, .is-style-access-note) p { margin: 0 0 0.6rem; }
:is(.access-note, .is-style-access-note) > :last-child { margin-bottom: 0; }

/* ---- Interior pages: Rechtsgebiete subpages + generic Pages (Kanzlei,
   Kontakt) — ported from mockups/07-unterseite-rechtsgebiet.html, verified
   2026-08-24 ---- */
.page-hero {
	background: var(--wp--preset--color--green-deep);
	color: var(--wp--preset--color--cream);
	padding: 2.5rem 0 5.5rem;
	clip-path: polygon(0 0, 100% 0, 100% 88%, 0 100%);
}
.page-hero .kicker {
	text-transform: uppercase;
	letter-spacing: 0.06em;
	font-size: 0.8rem;
	color: #cfe3d7;
	margin-bottom: 0.5rem;
}
/* Plain text (Rechtsgebiete titles) stays solid green-bright, one line — the
   two-tone stacked treatment (role-line/name-line spans, same as the
   homepage hero) only kicks in where those classes are actually used
   (Kanzlei's title). display:flex on a heading with no spans just renders
   as normal single-line text, so this is safe for both cases at once. */
.page-hero h1 { font-size: clamp(2rem, 5.5vw, 3.3rem); line-height: 1.08; color: var(--wp--preset--color--green-bright); margin-bottom: 0.9rem; display: flex; flex-direction: column; }
.page-hero h1 .role-line { color: var(--wp--preset--color--green-bright); }
.page-hero h1 .name-line { color: var(--wp--preset--color--cream); }
.page-hero h2 { font-size: 1.15rem; color: var(--wp--preset--color--cream); }
.page-hero p { margin: 0 0 0.9rem; color: #d8e6dd; max-width: 60ch; }
.page-hero .topics-label { margin: 0; color: var(--wp--preset--color--cream); font-weight: 600; }

/* Topic chips deliberately cross the diagonal seam — a sibling element
   outside the clipped .page-hero, pulled up with a negative margin and
   raised z-index. Offset is half the grid's own height (2 rows ≈ 7.25rem,
   half ≈ 3.6rem) — a simple rule of thumb, not pixel-exact; the diagonal
   itself stays untouched on purpose (explicit call from feedback: don't
   flatten the slope to force perfect centering). */
/* margin-top !important, 2026-09-01: seit die Pillen aus post_content statt
   direkt aus dem Template kommen, ist dieser Block das erste Kind einer
   WordPress-Flow-Layout-Zone (".entry-content"/"main"). WordPress setzt
   dafür selbst eine globale Regel ":root :where(.is-layout-flow) >
   :first-child { margin-block-start: 0 }" -- durch zwei Pseudoklassen
   (:root + :first-child) hat die trotz :where() mehr Spezifität als eine
   einzelne Klasse hier und würde die Verschiebung sonst stillschweigend
   auf 0 zurücksetzen. margin-bottom ist davon nicht betroffen (dort
   gewinnt diese Regel schon ohne !important). */
.topic-grid-wrap { position: relative; z-index: 2; margin-top: -3.6rem !important; margin-bottom: 2.5rem; }
/* 2026-09-01: die Pillen sind jetzt eine echte Liste (core/list, Block-Style
   "topic-grid" / Label "Themen-Pillen" in functions.php) statt handgesetzter
   <span>-Elemente im Template -- jede Pille ein eigener, editierbarer
   Listenpunkt. ".topic-grid .topic" bleibt als Alt-Selektor bestehen, falls
   irgendwo noch die alte <span class="topic">-Variante existiert. */
:is(.topic-grid, .is-style-topic-grid) {
	display: grid; grid-template-columns: 1fr; gap: 0.75rem;
	max-width: 40rem; margin: 0; padding: 0; list-style: none;
}
@media (min-width: 480px) {
	:is(.topic-grid, .is-style-topic-grid) { grid-template-columns: 1fr 1fr; }
}
:is(.topic-grid, .is-style-topic-grid) > li,
.topic-grid .topic {
	background: var(--wp--preset--color--card-bg);
	color: var(--wp--preset--color--card-text);
	border-radius: 8px;
	padding: 0.9rem 1.1rem;
	font-size: 0.92rem;
	font-weight: 600;
	box-shadow: 0 6px 16px rgba(0, 0, 0, 0.28);
}

/* Pages without a topic-grid (Kanzlei, Kontakt) have nothing pulling
   content up into the diagonal's cut, so the first section needs its own
   top margin instead — Rechtsgebiete pages get this for free from
   .topic-grid-wrap's own margin-bottom. Matches .section-box's own
   margin-bottom (1.5rem) on purpose — 2026-08-24 feedback: the top gap
   was a different, larger size than the gap between boxes, breaking the
   page's vertical rhythm. */
.page-content { margin-top: 1.5rem; }

/* Auch als Block-Style registriert (functions.php, Label "Themenbox") --
   gleiche Doppel-Selektor-Begründung wie bei .access-note oben; hier zudem
   dauerhaft nötig, weil page-kontakt.html den Eingangstool-Kasten und
   single.html den Blogbeitrags-Kasten beide als rohes <div class="section-
   box"> im Template setzen, nie als Block. */
:is(.section-box, .is-style-section-box) {
	background: var(--wp--preset--color--card-bg);
	color: var(--wp--preset--color--card-text);
	border-radius: 10px;
	padding: 1.75rem 2rem;
	margin-bottom: 1.5rem;
}
/* :last-child statt :last-of-type (bis 2026-09-01: passte nur zufällig,
   weil jedes Geschwisterelement zufällig ebenfalls ein <div> war --
   :last-of-type meint "letztes Element dieses Tags", nicht "letztes mit
   dieser Klasse"). */
:is(.section-box, .is-style-section-box):last-child { margin-bottom: 2.5rem; }
:is(.section-box, .is-style-section-box) h2 { font-size: 1.15rem; margin: 0 0 0.75rem; }
/* margin-top 1.5rem, not 0, 2026-09-01: found by Daniel on Sozialrecht --
   every list-then-heading transition inside the Themenbox had zero gap.
   Cause was this rule itself: h3 only ever follows a paragraph or a list
   here, never opens a box the way h2 does, so zeroing its top margin (the
   same pattern used for h2, which DOES always open a box) was simply
   wrong, not a WordPress-global-styles conflict this time. 1.5rem matches
   the existing heading-to-list gap below it, for visual symmetry. */
:is(.section-box, .is-style-section-box) h3 { font-size: 1.05rem; margin: 1.5rem 0 0.6rem; }
:is(.section-box, .is-style-section-box) p { margin: 0 0 0.9rem; }
/* ">:last-child" statt "p:last-child" (bis 2026-09-01: ein Kasten, der mit
   einer Liste statt einem Absatz endet -- z.B. Sozialrecht -- behielt einen
   ungewollten Abstand unten). */
:is(.section-box, .is-style-section-box) > :last-child { margin-bottom: 0; }

/* ---- Aktuelles: post cards on the archive, reuse .section-box's light
   card look, add title/date/excerpt-specific rules ---- */
.post-card h3 { margin: 0 0 0.25rem; font-size: 1.1rem; }
.post-card h3 a { color: inherit; text-decoration: none; }
.post-card h3 a:hover { text-decoration: underline; }
.post-card .wp-block-post-date {
	display: block;
	font-size: 0.85rem;
	color: var(--wp--preset--color--card-muted);
	margin-bottom: 0.75rem;
}
/* Hard 3-line cap regardless of excerpt length or box width — the
   excerptLength block setting is a word-count approximation, this is what
   actually enforces "max 3 lines" visually. */
.post-excerpt {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin: 0 0 0.9rem;
}
.post-card .wp-block-read-more {
	display: inline-block;
	color: var(--wp--preset--color--accent);
	font-weight: 700;
	text-decoration: none;
	font-size: 0.92rem;
}
.post-card .wp-block-read-more:hover { text-decoration: underline; }

/* Single-post page: deliberately no green diagonal hero (unlike every
   other page) — just a back-link on the dark canvas, then the whole post
   in one plain white box. .post-page needs its own top margin since
   there's no hero pushing content down for it. */
.post-page { margin-top: 2.5rem; }
.back-link { margin: 0 0 1rem; }
.back-link a { color: var(--wp--preset--color--text); text-decoration: none; font-size: 0.9rem; font-weight: 600; }
.back-link a:hover { text-decoration: underline; }
.post-full h1 { font-size: clamp(1.8rem, 4vw, 2.6rem); margin: 0 0 0.5rem; }
.post-date-single {
	display: block;
	font-size: 0.85rem;
	color: var(--wp--preset--color--card-muted);
	margin-bottom: 1rem;
}

.site-footer {
	background: var(--wp--preset--color--header-bg);
	color: var(--wp--preset--color--muted);
	padding: 2rem 0;
	font-size: 0.85rem;
}
.site-footer .cols { max-width: var(--wp--style--global--content-size); margin: 0 auto; padding: 0 1.25rem; }
.site-footer a { color: inherit; text-decoration: none; opacity: 0.85; }
.site-footer a:hover { text-decoration: underline; }
.site-footer h4 {
	font-family: var(--wp--preset--font-family--body);
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	opacity: 0.7;
	margin: 0 0 0.5rem;
}
