/* Site styles — overrides and additions on top of the theme.
 *
 * Theme tokens + base components are loaded from ../theme/tokens.css and ../theme/components.css
 * via @import below. Site-specific styles go after the imports.
 *
 * If you find yourself overriding a lot here, consider whether the theme itself needs updating —
 * see `update-theme.sh` to cascade changes back to all sites using the same theme.
 */

@import url("theme/tokens.css");
@import url("theme/components.css");

/* ===========================================================
 * Site-specific overrides and additions go below this line.
 * BURA — Swiss technical datasheet. See DESIGN.md for the contract.
 * ========================================================== */

/* -----------------------------------------------------------
 * 1. Local type token + heading overrides
 * The theme's heading clamps are marketing-loud; a datasheet is quieter.
 * ----------------------------------------------------------- */

:root {
  --font-mono: "Chivo Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

h1 { font-size: clamp(2rem, 3.6vw, 3rem); line-height: 1.08; letter-spacing: -0.02em; font-weight: 700; }
h2 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); line-height: 1.14; letter-spacing: -0.015em; font-weight: 600; }
h3 { font-size: clamp(1.1rem, 1.5vw, 1.3rem); line-height: 1.25; letter-spacing: -0.01em; font-weight: 600; }

/* -----------------------------------------------------------
 * 2. Chrome — header, footer
 * .site-header, .header-inner, .logo-link, .logo-wordmark, .site-footer,
 * .footer-trust, .partner-bar* come from the theme untouched.
 * ----------------------------------------------------------- */

.logo-mark { display: block; }

.header-sub {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-left: 0.35rem;
  white-space: nowrap;
}
/* Below tablet width the logo, the language switch and the CTA already fill the
   header gutter. The descriptor is the only decorative item in that row, so it
   is the one that goes: keeping it collided it with the language switch. */
@media (max-width: 720px) {
  .header-sub { display: none; }
}

.header-end { display: flex; align-items: center; gap: 1rem; }

/* In-page anchor nav: reachable via scroll/TOC on small screens, shown from
   tablet width up so it never fights the logo/lang/CTA row in the header gutter. */
.site-nav { display: none; }
@media (min-width: 900px) {
  .site-nav { display: flex; align-items: center; gap: 1.3rem; }
  .site-nav a {
    color: var(--ink-muted);
    text-decoration: none;
    font-size: var(--text-sm);
    font-weight: 500;
  }
  .site-nav a:hover { color: var(--navy-700); }
  /* Legal use #6 of 6: current-page marker in the header nav (subpage only). */
  .site-nav a[aria-current="page"] { color: var(--clay-600); font-weight: 700; }
}

.lang-switch {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.76rem;
}
.lang-switch a {
  color: var(--ink-muted);
  text-decoration: none;
  padding: 0.1rem 0.3rem;
}
.lang-switch a:hover { color: var(--navy-700); }
/* Legal use #3 of 6 (header half): current language marker. */
.lang-switch a[aria-current="true"] { color: var(--clay-600); font-weight: 700; }

.header-contact {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.header-contact:hover { border-color: var(--navy-700); color: var(--navy-700); }

.footer-top {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--navy-800);
}
@media (min-width: 700px) {
  .footer-top { flex-direction: row; justify-content: space-between; align-items: flex-start; gap: var(--space-6); }
}

.footer-brand { display: flex; flex-direction: column; gap: 0.5rem; max-width: 34ch; }
.footer-name { font-family: var(--font-display); font-weight: 700; font-size: var(--text-xl); color: var(--on-navy); }
.footer-tagline { margin: 0; color: var(--on-navy-muted); }

.footer-links {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  font-size: var(--text-sm);
}
@media (min-width: 700px) {
  .footer-links { flex-direction: row; gap: 1.4rem; }
}

.footer-bottom {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding-top: var(--space-5);
}
@media (min-width: 700px) {
  .footer-bottom { flex-direction: row; align-items: center; justify-content: space-between; }
}

.footer-bottom-end { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; }

.footer-lang {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.76rem;
}
.footer-lang a:hover { color: var(--on-navy); }
/* Legal use #3 of 6 (footer half): current language marker. */
.footer-lang a[aria-current="true"] { color: var(--clay-600); font-weight: 700; }

.footer-legal { display: flex; align-items: center; gap: 1rem; font-size: var(--text-sm); }

.footer-company { margin: 0; font-size: var(--text-xs); color: var(--on-navy-muted); }

/* -----------------------------------------------------------
 * 3. Primitives
 * ----------------------------------------------------------- */

.label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.rule {
  border: none;
  border-top: 1px solid var(--line);
  margin: var(--space-5) 0;
}

.crumb {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-decoration: none;
  margin-bottom: var(--space-4);
}
.crumb::before { content: "\2190"; }
.crumb:hover { color: var(--navy-700); }

.toc {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.toc li { border-bottom: 1px solid var(--line); }
.toc a {
  display: block;
  padding: 0.6rem 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink);
  text-decoration: none;
}
.toc a:hover { color: var(--navy-700); text-decoration: underline; }
@media (min-width: 640px) {
  .toc { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--space-5); }
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.sheet {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--bg);
  overflow: hidden;
}
.sheet-head {
  padding: 0.7rem 1rem;
  background: var(--surface);
  border-bottom: 1px solid var(--line-strong);
}
.sheet-body { padding: 0; }
.sheet-body .spec-table { border: none; border-radius: 0; }

.spec-table {
  width: 100%;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg);
}
.spec-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem 1rem;
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--line);
}
.spec-row:last-child { border-bottom: none; }
.spec-key {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink-muted);
}
.spec-val {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
/* Legal use #1 of 6: the single most important figure in a spec table.
   Sized as WCAG large text (>=24px) so clay-600's 3.67:1-on-bg ratio clears
   the 3:1 large-text floor -- clay-500 (2.58:1) and clay-600 at body size
   (3.67:1 but the 4.5:1 floor applies) both fail here. See report. */
.spec-val--signal {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--clay-600);
}

.figure { margin: var(--space-5) 0; }
.figure-frame {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--bg);
}
.figure-cap {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  margin-top: 0.6rem;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}
.figure-num {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.module-row {
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: 0 1rem;
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--line);
}
.module-row:last-of-type { border-bottom: none; }
.module-index {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  padding-top: 0.2rem;
}
.module-name { font-size: var(--text-lg); margin: 0 0 0.25rem; }
.module-job { color: var(--ink-muted); margin: 0 0 0.7rem; }
.chip-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-muted);
}

.module-section .container { max-width: var(--maxw-narrow); }
.module-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line-strong);
}

/* Real <table>, mobile-safe: the table itself scrolls horizontally inside
   its own border box rather than the page overflowing at 320px. */
.sites-table {
  display: block;
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  border-collapse: collapse;
}
.sites-table caption {
  text-align: left;
  padding: 0.7rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
  background: var(--surface);
  border-bottom: 1px solid var(--line-strong);
}
.sites-table th,
.sites-table td {
  padding: 0.6rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--line);
  font-size: var(--text-sm);
  white-space: nowrap;
}
.sites-table tbody tr:last-child th,
.sites-table tbody tr:last-child td { border-bottom: none; }
.sites-table thead th {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-muted);
  background: var(--surface);
}
.sites-table td {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.grid-2,
.grid-3 { display: grid; grid-template-columns: 1fr; gap: var(--space-5); }
@media (min-width: 900px) {
  .grid-2 { grid-template-columns: 1fr 1fr; }
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
}

/* -----------------------------------------------------------
 * 4. Visualisation — SVG diagrams + their always-in-DOM fallback.
 * Rest state IS the final state (motion contract, section 9): nothing here
 * starts hidden or offset. src/main.js sets the *from* state only inside a
 * prefers-reduced-motion: no-preference matchMedia branch.
 * ----------------------------------------------------------- */

.viz { margin: var(--space-5) 0; }

.viz-frame {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--bg);
}
.viz--integration .viz-frame { aspect-ratio: 1200 / 680; }
.viz--rail .viz-frame { aspect-ratio: 1200 / 240; }
.viz--map .viz-frame { aspect-ratio: 1200 / 520; }

.viz-caption {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  margin-top: 0.6rem;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

/* Above 760px: SVG shows, this is clipped out of view but stays in the
   accessibility tree (clip-rect technique, never display:none). */
.viz-fallback {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* Below the diagram breakpoint the fallback IS the content, so it has to survive
   320px. A long unbreakable mono header (TELEPHELYSZAM) otherwise pushes the
   whole page wide, so the table scrolls inside its own box like .sites-table. */
.viz-fallback {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.viz-fallback table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
  table-layout: auto;
}
.viz-fallback th,
.viz-fallback td {
  overflow-wrap: anywhere;
}
.viz-fallback caption {
  text-align: left;
  padding-bottom: 0.5rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.viz-fallback th,
.viz-fallback td {
  padding: 0.5rem 0.7rem;
  text-align: left;
  border-bottom: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
}
.viz-fallback thead th {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-muted);
  background: var(--surface);
}
.viz-fallback ol {
  list-style: none;
  counter-reset: viz-step;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.viz-fallback ol li {
  counter-increment: viz-step;
  display: flex;
  gap: 0.7rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--text-sm);
}
.viz-fallback ol li::before {
  content: counter(viz-step, decimal-leading-zero);
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

/* At 760px and below: the SVG hides, the fallback becomes the real datasheet. */
@media (max-width: 760px) {
  .viz-frame { display: none; }
  .viz-fallback {
    position: static;
    width: auto;
    height: auto;
    padding: 0;
    margin: 0;
    overflow: visible;
    clip: auto;
    white-space: normal;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--bg);
  }
  .viz-fallback table { border: none; }
}

/* Rest states -- the CSS default IS the finished diagram. */
.viz-grid { stroke: var(--line); stroke-width: 1; }

.viz-link {
  fill: none;
  stroke: var(--line-strong);
  stroke-width: 1.5;
  stroke-dashoffset: 0;
}

.viz-node { opacity: 1; }
.viz-node rect,
rect.viz-node {
  fill: var(--bg);
  stroke: var(--line-strong);
  stroke-width: 1;
}
.viz-node-label {
  font-family: var(--font-mono);
  font-size: 11px;
  fill: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* The 22 deployment-matrix site cells (#viz-map-cells) carry a quiet mono
   index. Scoped by the group id so it wins over the default .viz-node-label
   fill (--ink) without a new class. */
#viz-map-cells text.viz-node-label { fill: var(--ink-muted); }

.viz-tag {
  font-family: var(--font-mono);
  font-size: 10px;
  fill: var(--ink-muted);
  opacity: 1;
}

.viz-core rect,
rect.viz-core { fill: var(--navy-700); stroke: var(--navy-700); }
/* .viz-core lives on the <rect> only (see DESIGN.md §7.1/§7.3), never on a
   wrapping group, so ".viz-core text" never matched its sibling <text>
   elements -- SVG text needs its own fill; `color` does nothing for it, and
   an unmatched selector silently left it at .viz-node-label's --ink, dark on
   the navy fill. Scope by the group id instead. */
#viz-int-core text,
#viz-map-total text {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
#viz-map-total text { fill: var(--on-navy); }
/* Integration core: wordmark line fully on-navy, the module-list line muted. */
#viz-int-core text:first-of-type { fill: var(--on-navy); }
#viz-int-core text:last-of-type { fill: var(--on-navy-muted); }

.viz-station {
  opacity: 1;
  transform: none;
  transform-box: fill-box;
  transform-origin: center;
}
.viz-station rect,
rect.viz-station {
  fill: var(--bg);
  stroke: var(--line-strong);
  stroke-width: 1.5;
}
.viz-station-label {
  font-family: var(--font-mono);
  font-size: 10px;
  fill: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

/* Legal uses #2 and #5 of 6: the rail's terminal station/segment and the
   integration map's Navision route/node. .viz-signal is worn by three
   different element shapes across the three diagrams (polyline/path, rect,
   tspan) and a single unscoped ".viz-signal { fill: ... }" rule applied that
   fill to all of them alike -- CSS wins over the markup's fill="none"
   presentation attribute, so the open Navision route rendered as a filled
   triangle. Every declaration below is scoped to the element type it
   actually appears on. Shapes (rect) use clay-600, which clears the 3:1
   non-text floor on --bg (3.67:1; clay-500 is only 2.58:1 there). The "22"
   numeral is a <tspan>, not a <text>, and sits on the --navy-700 .viz-core
   fill, where clay-500 already reaches 4.77:1, so text gets the brighter
   token. */
.viz-link.viz-signal {
  fill: none;
  stroke: var(--clay-600);
}
/* A highlighted node still carries a label, so it gets a tint plus a clay edge:
   a solid fill would drop its text to roughly 2.5:1 and shout louder than any
   hairline on the page. The rail station square holds no text, so there the
   solid fill is correct and reads as the end of the line. */
rect.viz-signal {
  fill: var(--clay-100);
  stroke: var(--clay-600);
}
#viz-rail-stations rect.viz-signal {
  fill: var(--clay-600);
  stroke: var(--clay-600);
}
tspan.viz-signal,
text.viz-signal {
  fill: var(--clay-500);
}

/* -----------------------------------------------------------
 * 5. Section register -- band rhythm. No two adjacent bands repeat.
 * ----------------------------------------------------------- */

.spec-hero { background: var(--bg); }
.spec-hero .container {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
}
@media (min-width: 900px) {
  .spec-hero .container { grid-template-columns: 1.1fr 0.9fr; }
}

.rail { background: var(--surface); }
.modules { background: var(--bg); }
.integrations { background: var(--surface); }
.trace { background: var(--bg); }
.deployments { background: var(--navy-100); }
.stack { background: var(--bg); }
.makers { background: var(--surface); }

.contact { background: var(--navy-700); }
.contact h2 { color: var(--on-navy); }
.contact p { color: var(--on-navy-muted); }

.page-head { background: var(--bg); }

/* Subpage module-section band alternation, keyed by id (six named module
   sections plus the two cross-cutting sections share one class, .module-section,
   so the alternation lives on the ids, not on nth-of-type of a shared class). */
#wms, #minoseg, #flotta, #ertesitesek { background: var(--surface); }
#gyartas, #karbantartas, #rendelesek, #statisztika { background: var(--bg); }
#telephelyek { background: var(--navy-100); }

/* -----------------------------------------------------------
 * 6. Reduced motion
 * Satisfies pre-deploy check 9f (looks for the literal string in both
 * style.css and main.js). The rest states above are already the finished
 * diagram, so there is nothing to freeze -- this only removes incidental
 * hover/scroll motion for users who asked for less of it.
 * ----------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .btn:hover { transform: none; }
  .viz-link, .viz-node, .viz-station, .viz-tag, .viz-signal {
    transition: none;
  }
}
