/* =========================================================================
   SafeAll Asia — corporate site stylesheet
   Design language (owned by ui-ux):
     Red #C00000 (primary / alert accent) · Black #1A1A1A · White
     Thai typography: IBM Plex Sans Thai · Dark theme by default
   ========================================================================= */

/* ---------- tokens ---------- */
:root {
  --red:          #C00000;
  --red-bright:   #E11D1D;
  --red-text:     #FF5A5A; /* AA-safe (>=6:1) on --bg / --bg-alt for small text; --red-bright is for large text/hover only */
  --red-dim:      rgba(192, 0, 0, 0.14);
  --red-line:     rgba(192, 0, 0, 0.38);

  --bg:           #101012;
  --bg-alt:       #0B0B0D;
  --surface:      #1A1A1A;
  --surface-2:    #212126;
  --line:         #2C2C33;
  --line-soft:    rgba(255, 255, 255, 0.07);

  --text:         #F4F4F5;
  --text-2:       #C6C6CC;
  --muted:        #8E8E98;

  --ok:           #12B76A;
  --warn:         #F5A524;
  --crit:         #C00000;
  --offline:      #6B6B75;

  --font: "IBM Plex Sans Thai", "IBM Plex Sans", -apple-system,
          BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --maxw: 1180px;
  --pad: clamp(20px, 5vw, 48px);
  --radius: 14px;
  --radius-sm: 8px;

  --shadow: 0 18px 48px rgba(0, 0, 0, 0.5);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  --grid-line: rgba(255, 255, 255, 0.045);
  --lh-th: 1.5;

  /* left edge of the page column and the width of the text column used by the scroll stage (text stays in the left 44%) */
  --L: max(var(--pad), calc((100vw - var(--maxw)) / 2 + var(--pad)));
  --pw: max(340px, calc(44vw - var(--L)));
  /* homepage hero only: solid enough under the text column that body text keeps >= 7:1 even over the brightest lit windows,
     then fades out so the city stays strong on the right half. The flow section keeps --scrim. */
  --scrim-hero: linear-gradient(90deg, rgba(16, 16, 18, 0.93) 0, rgba(16, 16, 18, 0.91) 50%, rgba(16, 16, 18, 0.45) 60%, rgba(16, 16, 18, 0.10) 72%, rgba(16, 16, 18, 0) 84%);
  /* bottom edge of the hero melts into the page background, no seam where the canvas/poster ends */
  --hero-fade: linear-gradient(0deg, var(--bg) 0, rgba(16, 16, 18, 0) 160px);
  --scrim: linear-gradient(90deg, rgba(16, 16, 18, 0.90) 0, rgba(16, 16, 18, 0.74) 36%, rgba(16, 16, 18, 0.22) 62%, rgba(16, 16, 18, 0) 82%);
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.75;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 {
  margin: 0;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -0.01em;
}

p { margin: 0; }

ul { margin: 0; padding: 0; list-style: none; }

/* ---------- layout ---------- */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.section { padding-block: clamp(64px, 9vw, 118px); }
.section--tight { padding-block: clamp(48px, 6vw, 76px); }
.section--alt { background: var(--bg-alt); border-block: 1px solid var(--line-soft); }

.stack > * + * { margin-top: 18px; }

/* anchor targets must clear the sticky 70px header */
[id] { scroll-margin-top: 88px; }

/* ---------- type helpers ---------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--red-text);
  margin-bottom: 16px;
}
.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--red);
  flex: none;
}

/* Thai glyphs are wider and taller than Latin at the same px size, so these
   caps sit lower than a Latin-only site would use. */
.h1 { font-size: clamp(31px, 4.4vw, 50px); letter-spacing: -0.02em; line-height: 1.32; }
.h2 { font-size: clamp(25px, 3.2vw, 36px); letter-spacing: -0.015em; line-height: 1.34; }
.h3 { font-size: clamp(19px, 2vw, 22px); }

.lead {
  font-size: clamp(17px, 1.7vw, 20px);
  color: var(--text-2);
  max-width: 62ch;
}

.muted { color: var(--muted); }
.card .small a { text-decoration: underline; text-underline-offset: 3px; }
.small { font-size: 14.5px; line-height: 1.65; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 13px 26px;
  border-radius: 999px;
  border: 1px solid transparent;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease),
              transform .2s var(--ease), color .2s var(--ease);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--red); color: #fff; }
.btn--primary:hover { background: var(--red-bright); }

.btn--ghost { border-color: var(--line); color: var(--text); background: transparent; }
.btn--ghost:hover { border-color: var(--red); color: #fff; background: var(--red-dim); }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }

/* ---------- header ---------- */
.hdr {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(16, 16, 18, 0.86);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line-soft);
}
.hdr__in {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: 70px;
}

.logo { display: flex; align-items: center; gap: 11px; flex: none; }
.logo__mark {
  width: 32px; height: 32px;
  object-fit: contain;
  flex: none;
}
.logo__text { font-size: 18.5px; font-weight: 700; letter-spacing: -0.02em; }
.logo__text span { color: var(--muted); font-weight: 400; }

.nav { display: flex; align-items: center; gap: 4px; }
.nav a {
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 15.5px;
  color: var(--text-2);
  transition: color .18s var(--ease), background .18s var(--ease);
}
.nav a:hover { color: #fff; background: rgba(255, 255, 255, 0.06); }
.nav a[aria-current="page"] { color: #fff; background: var(--red-dim); }

.hdr__cta { display: flex; align-items: center; gap: 10px; }
.hdr__cta .btn { padding: 10px 20px; font-size: 15px; }

/* language switcher (TH | EN): lives in .hdr__cta, outside #nav, so it stays visible at every width.
   The bar stays 70px; the ::after pads the touch target to 44px tall. */
.lang { display: flex; align-items: center; gap: 2px; flex: none; }
.lang a {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 8px 10px;
  border-radius: 999px;
  font-size: 15px;
  line-height: 1.4;
  white-space: nowrap;
  color: var(--text-2);
  transition: color .18s var(--ease), background .18s var(--ease);
}
.lang a::after { content: ""; position: absolute; top: -4px; bottom: -4px; left: -1px; right: -1px; }
.lang a:hover { color: #fff; background: rgba(255, 255, 255, 0.06); }
.lang a[aria-current="true"] { color: #fff; background: var(--red-dim); }

.burger {
  display: none;
  width: 42px; height: 42px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
  padding: 0;
  place-items: center;
}
.burger span {
  display: block;
  width: 17px; height: 2px;
  background: var(--text);
  position: relative;
  transition: background .18s var(--ease);
}
.burger span::before, .burger span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 17px; height: 2px;
  background: var(--text);
  transition: transform .22s var(--ease);
}
.burger span::before { top: -5.5px; }
.burger span::after  { top:  5.5px; }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { transform: translateY(5.5px) rotate(45deg); }
.burger[aria-expanded="true"] span::after  { transform: translateY(-5.5px) rotate(-45deg); }

/* ---------- hero ---------- */
.hero {
  position: relative;
  padding-block: clamp(64px, 10vw, 118px);
  overflow: hidden;
  display: flex;
  align-items: center;
}
/* full-height hero, scrim and poster belong to the homepage hero only (inner pages use .hero--page) */
.hero:not(.hero--page) {
  min-height: min(calc(100vh - 70px), 760px);
  min-height: min(calc(100svh - 70px), 760px);
}
/* scrim keeps the text legible over the poster / the live canvas */
.hero:not(.hero--page)::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--hero-fade), var(--scrim-hero);
  pointer-events: none;
}
/* poster: paints first (pure CSS), sits behind the canvas, which fades in over it */
.hero:not(.hero--page)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--bg) url(img/city-poster-1600.webp) center / cover no-repeat fixed;
  pointer-events: none;
}
@media (max-width: 800px) {
  .hero:not(.hero--page)::after { background-image: url(img/city-poster-800.webp); background-attachment: scroll; background-position: 50% 22%; }
}
.hero__in { position: relative; z-index: 1; }
.hero__tag { position: absolute; right: var(--pad); bottom: 18px; z-index: 1; background: rgba(16, 16, 18, 0.72); }
@media (min-width: 701px) {
  .hero:not(.hero--page) .lead { max-width: min(62ch, var(--pw)); }
}
/* Thai home headline is longer than the old two-phrase one: a wider measure keeps it to three lines (24ch fits "กล้องและระบบความปลอดภัย" on one line) */
@media (min-width: 1101px) {
  html[lang="th"] .hero:not(.hero--page) .h1--hero { max-width: 24ch; }
}
/* narrow tablets: the headline wraps inside the same text column as the lead, so it never runs out over the lit city */
@media (min-width: 701px) and (max-width: 1100px) {
  .hero:not(.hero--page) .h1--hero { max-width: min(20ch, var(--pw)); }
}
@media (max-width: 700px) {
  .hero { align-items: flex-end; padding-bottom: 36px; }
  /* phone: the text block is stacked at the bottom, so eyebrow, h1 and lead all sit on the solid part;
     percentages of the hero box (always as tall as its content) need no vh/svh fallback */
  .hero:not(.hero--page)::before { background: var(--hero-fade), linear-gradient(0deg, rgba(16, 16, 18, 0.92) 0, rgba(16, 16, 18, 0.9) 90%, rgba(16, 16, 18, 0.55) 95%, rgba(16, 16, 18, 0) 100%); }
  .hero__tag { right: auto; left: var(--pad); top: 14px; bottom: auto; }
}

.hero--page { padding-bottom: clamp(20px, 3vw, 40px); }
.hero .lead { margin-top: 22px; }

/* ---------- inner-page hero scene (data-scene) ----------
   Poster = fallback and first paint (no canvas, no three.js request). The ambient canvas sits above it and under the
   scrim (the hero is its own stacking context); .hero__in stays on top. Only .hero--page[data-scene] is touched here. */
.hero--page[data-scene] {
  --scene-h: 420px;
  --poster-y: 20%;
  isolation: isolate;
  min-height: var(--scene-h);
  background: var(--bg) url(img/city-poster-800.webp) 50% var(--poster-y) / cover no-repeat;
}
.hero--page[data-scene="platform"] { --scene-h: 420px; --poster-y: 12%; }
.hero--page[data-scene="integrations"] { --scene-h: 400px; --poster-y: 34%; }
.hero--page[data-scene="industries"] { --scene-h: 400px; --poster-y: 58%; }
.hero--page[data-scene="security"] { --scene-h: 360px; --poster-y: 4%; }
.hero--page[data-scene="about"] { --scene-h: 340px; --poster-y: 76%; }
.hero--page[data-scene="contact"] { --scene-h: 260px; --poster-y: 92%; }
/* wide screens: the 1600 poster is landscape, so the hero strip (about 3.6:1) shows a band of it; each page picks a band
   that holds a skyline rather than the sky above it (the narrow screens keep the portrait 800 poster and the values above) */
@media (min-width: 701px) {
  .hero--page[data-scene] { background-image: url(img/city-poster-1600.webp); }
  .hero--page[data-scene="platform"] { --poster-y: 52%; }
  .hero--page[data-scene="integrations"] { --poster-y: 60%; }
  .hero--page[data-scene="industries"] { --poster-y: 68%; }
  .hero--page[data-scene="security"] { --poster-y: 46%; }
  .hero--page[data-scene="about"] { --poster-y: 80%; }
  .hero--page[data-scene="contact"] { --poster-y: 100%; }
  /* industries: the zones run over the first half of the hero exit, so the hero needs room to be seen doing it */
  .hero--page[data-scene="industries"] { --scene-h: 480px; min-height: var(--scene-h); min-height: clamp(480px, 66svh, 640px); }
}
/* scrim: >= .88 under the text column (about 54vw), gone by about 80% of the width; the bottom edge melts into the page */
.hero--page[data-scene]::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, var(--bg) 0, rgba(16, 16, 18, 0) 72px),
    linear-gradient(90deg, rgba(16, 16, 18, 0.94) 0, rgba(16, 16, 18, 0.9) 54%, rgba(16, 16, 18, 0.42) 64%, rgba(16, 16, 18, 0.1) 73%, rgba(16, 16, 18, 0) 80%);
  pointer-events: none;
}
.hero--page[data-scene] .stage-canvas--ambient { position: absolute; inset: 0; z-index: -1; }
.hero--page[data-scene] .hero__ctl {
  position: absolute; right: var(--pad); bottom: 18px; z-index: 2;
  display: flex; align-items: center; gap: 8px;
}
@media (min-width: 701px) {
  .hero--page[data-scene] .h1, .hero--page[data-scene] .lead { max-width: min(62ch, calc(54vw - var(--L))); }
}
@media (max-width: 700px) {
  .hero--page[data-scene] { --scene-h: 340px; padding-top: 176px; }
  .hero--page[data-scene="integrations"] { --scene-h: 320px; }
  .hero--page[data-scene="industries"] { --scene-h: 320px; padding-top: 340px; }
  .hero--page[data-scene="security"] { --scene-h: 300px; }
  .hero--page[data-scene="about"] { --scene-h: 280px; }
  .hero--page[data-scene="contact"] { --scene-h: 220px; }
  /* phone: the text block sits at the bottom, so the scrim runs bottom-up and leaves the top strip to the scene */
  .hero--page[data-scene]::before {
    background: linear-gradient(0deg, var(--bg) 0, rgba(16, 16, 18, 0) 56px),
      linear-gradient(0deg, rgba(16, 16, 18, 0.93) 0, rgba(16, 16, 18, 0.9) calc(100% - 168px), rgba(16, 16, 18, 0) calc(100% - 96px));
  }
  /* industries: the 280px canvas strip must stay clear (the zones are played in it), so the scrim starts below the strip and is full by 340px from the top */
  .hero--page[data-scene="industries"]::before {
    background: linear-gradient(0deg, var(--bg) 0, rgba(16, 16, 18, 0) 56px),
      linear-gradient(0deg, rgba(16, 16, 18, 0.93) 0, rgba(16, 16, 18, 0.9) calc(100% - 340px), rgba(16, 16, 18, 0) calc(100% - 280px));
  }
  .hero--page[data-scene] .hero__ctl { right: auto; left: var(--pad); top: 14px; bottom: auto; }
  .hero--page[data-scene] .stage-canvas--ambient { bottom: auto; height: 280px; }
}

/* photo hero (only when a real photo exists; markup must not reference a missing file) */
.hero--photo { background: var(--bg); }
.hero__photo { position: absolute; inset: 0; z-index: 0; }
.hero__photo img { width: 100%; height: 100%; object-fit: cover; }
.hero__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--bg) 0, rgba(16, 16, 18, .82) 45%, rgba(16, 16, 18, .55));
}

.h1--hero {
  font-size: clamp(34px, 7.4vw, 64px);
  line-height: 1.4;
  letter-spacing: -0.01em;
  font-weight: 700;
  text-wrap: balance;
  overflow-wrap: anywhere;
  padding-block: .1em;
  max-width: 20ch;
}
/* phrase clip wrappers: the phrase rises out of its clip; Thai is never split below the authored phrase */
.nbc { display: inline-block; vertical-align: top; overflow: hidden; padding-block: .18em; margin-block: -.18em; max-width: 100%; }
.h1--hero .nb { display: inline-block; }
@keyframes nbrise { from { transform: translateY(115%); } to { transform: none; } }
@keyframes herorise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.js .nbc .nb { animation: nbrise 600ms var(--ease) both; }
.js .nbc:nth-of-type(1) .nb { animation-delay: 120ms; }
.js .nbc:nth-of-type(2) .nb { animation-delay: 240ms; }
.js .nbc:nth-of-type(3) .nb { animation-delay: 360ms; }
.js .nbc:nth-of-type(4) .nb { animation-delay: 480ms; }
.js .nbc:nth-of-type(5) .nb { animation-delay: 600ms; }
.js .hero__sub { animation: herorise 600ms var(--ease) 600ms both; }
.js .hero:not(.hero--page) .lead { animation: herorise 600ms var(--ease) 760ms both; }
.js .hero:not(.hero--page) .btn-row { animation: herorise 600ms var(--ease) 900ms both; }
.hero__sub {
  margin-top: 8px;
  font-weight: 600;
  font-size: clamp(20px, 3vw, 28px);
  line-height: 1.5;
  color: var(--text);
}

/* ---------- console mock (platform.html) ---------- */
.console {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.console__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 15px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
  color: var(--muted);
}
.console__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--offline); flex: none; }
.console__dot--live { background: var(--red); box-shadow: 0 0 0 0 var(--red-line); animation: pulse 2.2s infinite; }
@keyframes pulse {
  70%  { box-shadow: 0 0 0 9px rgba(192, 0, 0, 0); }
  100% { box-shadow: 0 0 0 0 rgba(192, 0, 0, 0); }
}
.console__body { padding: 15px; display: grid; gap: 11px; }

.tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 9px; }
.tile {
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px 11px;
  text-align: center;
}
.tile b { display: block; font-size: 21px; font-weight: 700; line-height: 1.2; }
.tile span { font-size: 11.5px; color: var(--muted); letter-spacing: 0.02em; }
.tile--ok b   { color: var(--ok); }
.tile--warn b { color: var(--warn); }
.tile--crit b { color: var(--crit); }
.tile--off b  { color: var(--offline); }

.evt {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 13px;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--radius-sm);
  font-size: 14px;
}
.evt--crit { border-left-color: var(--crit); }
.evt--warn { border-left-color: var(--warn); }
.evt--ok   { border-left-color: var(--ok); }
.evt time { margin-left: auto; color: var(--muted); font-size: 12.5px; font-family: var(--mono); flex: none; }
.evt__src { color: var(--muted); font-size: 12.5px; }

/* ---------- cards ---------- */
.grid { display: grid; gap: 20px; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px 26px;
  transition: border-color .22s var(--ease), transform .22s var(--ease);
}
.card:hover { border-color: var(--red-line); transform: translateY(-3px); }
.card h2, .card h3 { margin-bottom: 10px; }
.card p { color: var(--text-2); font-size: 15.5px; line-height: 1.72; }

.card__icon {
  width: 42px; height: 42px;
  border-radius: 11px;
  background: var(--red-dim);
  border: 1px solid var(--red-line);
  display: grid;
  place-items: center;
  margin-bottom: 18px;
  color: var(--red-bright);
}
.card__icon svg { width: 21px; height: 21px; }

.card--flat { background: transparent; }
.card--flat:hover { transform: none; }

.card--quiet { display: block; }
.card--quiet:hover { border-color: var(--line); transform: translateY(-2px); }

/* numbered step */
.step__no {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--red-text);
  letter-spacing: 0.08em;
  margin-bottom: 12px;
  display: block;
}

/* ---------- feature list ---------- */
.checks { display: grid; gap: 13px; margin-top: 26px; }
.checks li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: 15.5px;
  color: var(--text-2);
  line-height: 1.68;
}
.checks li::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 2px;
  background: var(--red);
  flex: none;
  margin-top: 10px;
}

/* ---------- split ---------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 5vw, 64px);
  align-items: center;
}

/* ---------- vendor chips ---------- */
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  padding: 9px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-size: 15px;
  color: var(--text-2);
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.chip:hover { border-color: var(--red-line); color: #fff; }
.chip--soon { opacity: 0.55; }
.chip--dev { border-color: rgba(245, 165, 36, .4); color: var(--warn); }

/* ---------- table ---------- */
.tablewrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  -webkit-overflow-scrolling: touch;
}
table { width: 100%; border-collapse: collapse; min-width: 620px; }
th, td {
  padding: 15px 20px;
  text-align: left;
  font-size: 15px;
  border-bottom: 1px solid var(--line);
}
th {
  background: var(--surface-2);
  font-weight: 600;
  font-size: 13.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: rgba(255, 255, 255, 0.02); }
td b { font-weight: 600; }

.pill {
  display: inline-block;
  padding: 3px 11px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
}
.pill--ok   { background: rgba(18, 183, 106, 0.14); color: #35D48D; }
.pill--dev  { background: rgba(245, 165, 36, 0.14); color: var(--warn); }
.pill--plan { background: rgba(255, 255, 255, 0.07); color: #A6A6B0; }

/* ---------- status palette legend ---------- */
.legend { display: flex; flex-wrap: wrap; gap: 22px; margin-top: 24px; }
.legend div { display: flex; align-items: center; gap: 9px; font-size: 14.5px; color: var(--text-2); }
.legend i { width: 13px; height: 13px; border-radius: 4px; flex: none; }

/* ---------- CTA band ---------- */
.cta {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(34px, 5vw, 56px);
  text-align: center;
}
.cta .lead { margin-inline: auto; margin-top: 14px; }
.cta .btn-row { justify-content: center; }

/* ---------- form ---------- */
.form { display: grid; gap: 17px; }
.form[hidden] { display: none; }
.field { display: grid; gap: 7px; }
.field label { font-size: 14.5px; font-weight: 600; color: var(--text-2); }
.field input, .field textarea, .field select {
  width: 100%;
  padding: 13px 15px;
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  font-size: 16px;
  transition: border-color .18s var(--ease);
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--red);
}
.field textarea { resize: vertical; min-height: 130px; }
.field--2 { display: grid; grid-template-columns: 1fr 1fr; gap: 17px; }

.formnote {
  font-size: 13.5px;
  color: var(--muted);
  border-left: 2px solid var(--red);
  padding-left: 13px;
  line-height: 1.6;
}
.formnote a { text-decoration: underline; }

/* ---------- contact rows ---------- */
.contactlist { display: grid; gap: 20px; }
.contactrow { display: flex; gap: 14px; align-items: flex-start; }
.contactrow .card__icon { margin-bottom: 0; flex: none; width: 38px; height: 38px; }
.contactrow strong { display: block; font-size: 14px; color: var(--muted); font-weight: 600; }
.contactrow a, .contactrow p { font-size: 16px; color: var(--text); }
.contactrow a:hover { color: var(--red-bright); }
.pending { font-style: italic; color: var(--muted); }

/* ---------- footer ---------- */
.ftr {
  background: var(--bg-alt);
  border-top: 1px solid var(--line-soft);
  padding-block: 54px 30px;
}
.ftr__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 34px;
}
.ftr__top { margin-bottom: 38px; }
.ftr__about a { color: var(--text-2); }
.ftr__about a:hover { color: var(--red-bright); }
.ftr h4 {
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 15px;
  font-weight: 600;
}
.ftr ul { display: grid; gap: 10px; }
.ftr ul a { font-size: 15px; color: var(--text-2); }
.ftr ul a:hover { color: var(--red-bright); }
.ftr__about { font-size: 14.5px; color: var(--muted); max-width: 52ch; margin-top: 15px; line-height: 1.7; }
.ftr__bottom {
  margin-top: 42px;
  padding-top: 22px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 13.5px;
  color: var(--muted);
}

/* ---------- reveal on scroll ---------- */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.js .reveal.is-in { opacity: 1; transform: none; }

/* ---------- architecture diagram (platform.html) ---------- */
.archdiagram { display: grid; gap: 0; max-width: 820px; margin-inline: auto; }
.arch-layer {
  display: flex;
  gap: 22px;
  align-items: flex-start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px 26px;
}
.arch-layer--core {
  border-color: var(--red-line);
  background: linear-gradient(180deg, rgba(192, 0, 0, 0.10), var(--surface) 70%);
  box-shadow: 0 0 0 1px var(--red-line) inset, 0 14px 40px rgba(192, 0, 0, 0.10);
}
.arch-num {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--red-text);
  border: 1px solid var(--red-line);
  border-radius: 999px;
  padding: 7px 13px;
  white-space: nowrap;
  flex: none;
  margin-top: 3px;
}
.arch-body h3 { margin-bottom: 8px; }
.arch-body p { color: var(--text-2); font-size: 15px; line-height: 1.68; margin: 0; }
.arch-tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.arch-tag {
  font-size: 12.5px;
  color: var(--text-2);
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px 10px;
}
.arch-flow {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 30px;
  padding: 11px 0;
}
.arch-flow b { display: inline-flex; align-items: center; gap: 7px; font-weight: 500; font-size: 13px; color: var(--muted); }
.arch-flow .up { color: var(--red-text); }
.arch-flow svg { width: 14px; height: 14px; flex: none; }

/* ---------- incident flow demo (index.html) ----------
   data-step on .flow = how many steps are lit (0 = none, 6 = all lit: the static list and the no-JS default). */
.flow { --c: var(--ok); }
.flow[data-step="0"] { --c: var(--text-2); }
.flow[data-step="1"], .flow[data-step="2"], .flow[data-step="3"] { --c: var(--crit); }
.flow[data-step="4"] { --c: var(--warn); }
.flow[data-step="5"], .flow[data-step="6"] { --c: var(--ok); }

.flow__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 22px; }
.flow__tag {
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.08em; color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px; padding: 4px 12px;
}
.flow__btn {
  min-height: 44px; padding: 0 20px; border-radius: 999px;
  border: 1px solid var(--line); background: transparent; color: var(--text);
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.flow__btn:hover { border-color: var(--muted); background: rgba(255, 255, 255, 0.05); }
.flow__btn[hidden] { display: none; }

.flow__steps { list-style: none; margin: 0; padding: 0; max-width: 640px; margin-inline: auto; }
.flow__step {
  --c: var(--crit);
  position: relative;
  padding: 0 0 26px 56px;
  min-height: 24px;
  line-height: var(--lh-th);
  opacity: .6;
  transition: opacity 350ms var(--ease);
}
.flow__step:last-child { padding-bottom: 0; }
.flow__step--crit { --c: var(--crit); }
.flow__step--warn { --c: var(--warn); }
.flow__step--ok { --c: var(--ok); }
.flow__step b { display: block; font-weight: 600; font-size: 17px; color: var(--text); line-height: var(--lh-th); }
.flow__step > span:last-child { display: block; font-size: 15px; color: var(--text-2); margin-top: 2px; white-space: normal; }

.flow__node {
  position: absolute; left: 0; top: 0;
  width: 24px; height: 24px; border-radius: 50%;
  border: 2px solid var(--line); background: var(--bg);
  display: grid; place-items: center; color: var(--muted);
  transition: border-color 350ms var(--ease), color 350ms var(--ease), background 350ms var(--ease);
}
.flow__node svg { width: 12px; height: 12px; }

.flow__line {
  position: absolute; left: 11px; top: 24px; bottom: 0; width: 2px;
  background: var(--line); overflow: hidden;
}
.flow__line::after {
  content: ""; position: absolute; inset: 0; background: var(--c);
  transform: scaleY(0); transform-origin: top;
  transition: transform 1000ms linear;
}
.flow__step:last-child .flow__line { display: none; }
.flow[data-step="0"] .flow__line::after { transition-duration: 500ms; }

.flow[data-step="1"] .flow__step[data-n="1"],
.flow[data-step="2"] .flow__step[data-n="1"],
.flow[data-step="3"] .flow__step[data-n="1"],
.flow[data-step="4"] .flow__step[data-n="1"],
.flow[data-step="5"] .flow__step[data-n="1"] { opacity: 1; }
.flow[data-step="2"] .flow__step[data-n="2"],
.flow[data-step="3"] .flow__step[data-n="2"],
.flow[data-step="4"] .flow__step[data-n="2"],
.flow[data-step="5"] .flow__step[data-n="2"] { opacity: 1; }
.flow[data-step="3"] .flow__step[data-n="3"],
.flow[data-step="4"] .flow__step[data-n="3"],
.flow[data-step="5"] .flow__step[data-n="3"] { opacity: 1; }
.flow[data-step="4"] .flow__step[data-n="4"],
.flow[data-step="5"] .flow__step[data-n="4"] { opacity: 1; }
.flow[data-step="5"] .flow__step[data-n="5"] { opacity: 1; }
.flow[data-step="1"] .flow__step[data-n="1"] .flow__node,
.flow[data-step="2"] .flow__step[data-n="1"] .flow__node,
.flow[data-step="3"] .flow__step[data-n="1"] .flow__node,
.flow[data-step="4"] .flow__step[data-n="1"] .flow__node,
.flow[data-step="5"] .flow__step[data-n="1"] .flow__node { border-color: var(--c); color: var(--c); }
.flow[data-step="2"] .flow__step[data-n="2"] .flow__node,
.flow[data-step="3"] .flow__step[data-n="2"] .flow__node,
.flow[data-step="4"] .flow__step[data-n="2"] .flow__node,
.flow[data-step="5"] .flow__step[data-n="2"] .flow__node { border-color: var(--c); color: var(--c); }
.flow[data-step="3"] .flow__step[data-n="3"] .flow__node,
.flow[data-step="4"] .flow__step[data-n="3"] .flow__node,
.flow[data-step="5"] .flow__step[data-n="3"] .flow__node { border-color: var(--c); color: var(--c); }
.flow[data-step="4"] .flow__step[data-n="4"] .flow__node,
.flow[data-step="5"] .flow__step[data-n="4"] .flow__node { border-color: var(--c); color: var(--c); }
.flow[data-step="5"] .flow__step[data-n="5"] .flow__node { border-color: var(--c); color: var(--c); }
.flow[data-step="2"] .flow__step[data-n="1"] .flow__line::after,
.flow[data-step="3"] .flow__step[data-n="1"] .flow__line::after,
.flow[data-step="4"] .flow__step[data-n="1"] .flow__line::after,
.flow[data-step="5"] .flow__step[data-n="1"] .flow__line::after { transform: scaleY(1); }
.flow[data-step="3"] .flow__step[data-n="2"] .flow__line::after,
.flow[data-step="4"] .flow__step[data-n="2"] .flow__line::after,
.flow[data-step="5"] .flow__step[data-n="2"] .flow__line::after { transform: scaleY(1); }
.flow[data-step="4"] .flow__step[data-n="3"] .flow__line::after,
.flow[data-step="5"] .flow__step[data-n="3"] .flow__line::after { transform: scaleY(1); }
.flow[data-step="5"] .flow__step[data-n="4"] .flow__line::after { transform: scaleY(1); }

/* data-step 6 = whole list lit (static list, and the no-JS default) */
.flow[data-step="6"] .flow__step { opacity: 1; }
.flow[data-step="6"] .flow__step .flow__node { border-color: var(--c); color: var(--c); }
.flow[data-step="6"] .flow__step .flow__line::after { transform: scaleY(1); }

@keyframes flowpulse {
  0%   { box-shadow: 0 0 0 0 rgba(192, 0, 0, 0.55); }
  100% { box-shadow: 0 0 0 12px rgba(192, 0, 0, 0); }
}
.flow[data-step="1"] .flow__step[data-n="1"] .flow__node { animation: flowpulse 1.2s ease-out 1; }

.flow__evt {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  max-width: 640px; margin: 28px auto 0;
  padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--c); border-radius: var(--radius-sm);
  font-size: 15px; line-height: var(--lh-th);
  transition: border-left-color 350ms var(--ease);
}
.flow__msgs { display: grid; flex: 1 1 220px; min-width: 0; }
.flow__msg {
  grid-area: 1 / 1; opacity: 0; visibility: hidden;
  transition: opacity 250ms var(--ease), visibility 0s linear 250ms;
}
.flow[data-step="1"] .flow__msg[data-n="1"],
.flow[data-step="2"] .flow__msg[data-n="2"],
.flow[data-step="3"] .flow__msg[data-n="3"],
.flow[data-step="4"] .flow__msg[data-n="4"],
.flow[data-step="5"] .flow__msg[data-n="5"],
.flow[data-step="6"] .flow__msg[data-n="6"] { opacity: 1; visibility: visible; transition-delay: 0s; }
.flow[data-step="6"] .flow__src { display: none; }
.flow__src { color: var(--muted); font-size: 12.5px; font-family: var(--mono); flex: none; }

@media (min-width: 1000px) {
  .flow__steps { display: grid; grid-template-columns: repeat(6, 1fr); max-width: none; gap: 0; }
  .flow__step { padding: 38px 10px 0; text-align: center; }
  .flow__step:last-child { padding-bottom: 0; }
  .flow__node { left: 50%; margin-left: -12px; }
  .flow__line { left: calc(50% + 12px); right: auto; width: calc(100% - 24px); top: 11px; bottom: auto; height: 2px; }
  .flow__line::after { transform: scaleX(0); transform-origin: left; }
  .flow__evt { max-width: none; margin-top: 30px; }
  .flow[data-step="2"] .flow__step[data-n="1"] .flow__line::after,
  .flow[data-step="3"] .flow__step[data-n="1"] .flow__line::after,
  .flow[data-step="4"] .flow__step[data-n="1"] .flow__line::after,
  .flow[data-step="5"] .flow__step[data-n="1"] .flow__line::after { transform: scaleX(1); }
  .flow[data-step="3"] .flow__step[data-n="2"] .flow__line::after,
  .flow[data-step="4"] .flow__step[data-n="2"] .flow__line::after,
  .flow[data-step="5"] .flow__step[data-n="2"] .flow__line::after { transform: scaleX(1); }
  .flow[data-step="4"] .flow__step[data-n="3"] .flow__line::after,
  .flow[data-step="5"] .flow__step[data-n="3"] .flow__line::after { transform: scaleX(1); }
  .flow[data-step="5"] .flow__step[data-n="4"] .flow__line::after { transform: scaleX(1); }
  .flow[data-step="6"] .flow__step .flow__line::after { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .flow *, .flow *::before, .flow *::after { transition: none !important; animation: none !important; }
  .flow__step { opacity: 1; }
  .flow__node { border-color: var(--c); color: var(--c); }
  .flow__line::after { transform: none; }
}

/* ---------- scroll stage (class added by JS only, once the canvas is running) ---------- */
.stage-canvas {
  position: fixed; inset: 0; z-index: -1; display: block;
  width: 100%; height: 100%;
  background: var(--bg);
  opacity: 0; transition: opacity .5s var(--ease);
  pointer-events: none;
}
.stage-canvas.is-on { opacity: 1; }
/* canvas lost and not restored yet: the poster stands in for the live scene */
.stage-lost .flow-stage { background: var(--bg) url(img/city-poster-1600.webp) center / cover no-repeat fixed; }
@media (max-width: 800px) {
  .stage-lost .flow-stage { background-image: url(img/city-poster-800.webp); background-attachment: scroll; background-position: 50% 22%; }
}

.section--solid { background: var(--bg); }
.flow__tag { background: rgba(16, 16, 18, 0.72); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.flow__chips { display: none; }
.flow__intro { max-width: 70ch; margin-bottom: 40px; }
.flow__intro .lead { margin-top: 16px; }
.flow-stage { position: relative; background: transparent; padding-block: 0 28px; }
.flow-stage::before { content: ""; position: absolute; inset: 0; background: var(--scrim); pointer-events: none; }
.flow-stage > .wrap { position: relative; max-width: none; padding-inline: 0; }
.flow-stage > .wrap > .flow__note { margin-left: var(--L); margin-right: var(--pad); }

.flow-stage .flow { height: 600vh; height: 600svh; }
.flow-stage .flow__pin {
  position: sticky; top: 70px;
  height: calc(100vh - 70px); height: calc(100svh - 70px);
  display: flex; flex-direction: column;
  padding: 18px var(--pad) 28px var(--L);
  pointer-events: none;
}
.flow-stage .flow__btn { pointer-events: auto; }
.flow-stage .flow__head { margin-bottom: 0; }
.flow-stage .flow .flow__steps {
  display: block; position: relative; flex: 1 1 auto; min-height: 0;
  max-width: none; margin: 0; padding: 0;
}
.flow-stage .flow .flow__step,
.flow-stage .flow .flow__intro {
  position: absolute; left: 0; top: 50%;
  width: var(--pw); margin: 0; padding: 26px 30px 30px;
  background: rgba(16, 16, 18, 0.72);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid var(--line-soft); border-radius: var(--radius);
  text-align: left; line-height: var(--lh-th);
  pointer-events: none;
}
/* the intro card is a child of the pin (not of the list), so it takes the pin's left padding itself */
.flow-stage .flow .flow__intro { left: var(--L); top: calc(50% + 14px); max-width: none; }
.flow-stage .flow .flow__intro .h2 { font-size: clamp(26px, 3.3vw, 44px); line-height: 1.3; text-wrap: balance; }
.flow-stage .flow .flow__intro .lead { font-size: 17px; line-height: 1.7; color: var(--text-2); margin-top: 12px; }
/* hidden panels stay in the accessibility tree (opacity only) so a screen reader can reach every step */
.flow-stage .flow .flow__steps .flow__step:not(.is-active),
.flow-stage .flow:not([data-step="0"]) .flow__intro {
  opacity: 0;
  transform: translateY(-50%) translateY(14px);
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
}
.flow-stage .flow .flow__steps .flow__step.is-active,
.flow-stage .flow[data-step="0"] .flow__intro {
  opacity: 1;
  transform: translateY(-50%) translateY(0);
  transition: opacity 350ms var(--ease) 150ms, transform 350ms var(--ease) 150ms;
}
.flow-stage .flow__node, .flow-stage .flow__line, .flow-stage .flow__evt { display: none; }
.flow-stage .flow__step::before {
  content: "0" attr(data-n);
  display: block; margin-bottom: 14px;
  font-family: var(--mono); font-size: 13px; font-weight: 600; letter-spacing: 0.08em; line-height: 1;
  color: var(--red-text);
}
.flow-stage .flow__step b { font-size: clamp(28px, 5vw, 56px); font-weight: 700; line-height: 1.3; letter-spacing: -0.01em; text-wrap: balance; }
.flow-stage .flow__step[data-n="6"] b { font-size: clamp(34px, 6.4vw, 72px); }
.flow-stage .flow__step > span:last-child { font-size: 17px; line-height: 1.7; color: var(--text-2); margin-top: 12px; }

.flow-stage .flow__chips { display: flex; flex-wrap: wrap; gap: 8px 10px; margin-top: 16px; }
.flow__chip {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 6px 14px; border: 1px solid var(--line); border-radius: 999px;
  background: rgba(16, 16, 18, 0.72);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font-size: 14.5px; font-weight: 600; line-height: 1.5; color: var(--text);
}
.flow__chip::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--c); flex: none; }
.flow__chip--off::before { background: var(--offline); }
.flow__chip--ok::before { background: var(--ok); }
/* state is also told by shape, not colour alone: triangle = critical, ring = watch, dot = calm */
.flow[data-step="1"] .flow__state::before, .flow[data-step="2"] .flow__state::before, .flow[data-step="3"] .flow__state::before {
  border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
.flow[data-step="4"] .flow__state::before { background: transparent; border: 2px solid var(--c); }
.flow__chip:empty { display: none; }
.flow[data-step="6"] .flow__state { display: none; }
.flow:not([data-step="6"]) .flow__ext, .flow:not([data-step="6"]) .flow__int { display: none; }
.flow-stage .flow__btn, .hero__ctl .flow__btn { background: rgba(16, 16, 18, 0.72); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.flow-stage .flow__btn:hover, .hero__ctl .flow__btn:hover { background: linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05)), rgba(16, 16, 18, 0.72); }

@media (max-width: 700px) {
  .flow-stage .flow { height: 480vh; height: 480svh; }
  .flow-stage .flow__pin { padding: 12px var(--pad) 0; }
  .flow-stage .flow__chips { order: 2; margin-top: 10px; }
  .flow-stage .flow__chip { font-size: 13.5px; padding: 4px 11px; }
  .flow-stage .flow__chips { gap: 6px 8px; }
  .flow-stage .flow .flow__steps { order: 3; }
  .flow-stage::before { background: none; }
  .flow-stage .flow .flow__step,
  .flow-stage .flow .flow__intro {
    left: calc(-1 * var(--pad)); right: calc(-1 * var(--pad)); width: auto;
    top: auto; bottom: 0; max-height: 62vh; max-height: 62svh; overflow-y: auto;
    padding: 22px var(--pad) calc(26px + env(safe-area-inset-bottom, 0px));
    background: rgba(16, 16, 18, 0.90);
    border-radius: var(--radius) var(--radius) 0 0; border-width: 1px 0 0;
  }
  .flow-stage .flow .flow__intro { left: 0; right: 0; position: absolute; top: auto; bottom: 0; }
  /* the card can scroll (max-height + overflow-y), so the visible one must receive pointer events */
  .flow-stage .flow .flow__steps .flow__step.is-active,
  .flow-stage .flow[data-step="0"] .flow__intro { pointer-events: auto; }
  .flow-stage .flow .flow__steps .flow__step:not(.is-active),
  .flow-stage .flow:not([data-step="0"]) .flow__intro { transform: translateY(14px); }
  .flow-stage .flow .flow__steps .flow__step.is-active,
  .flow-stage .flow[data-step="0"] .flow__intro { transform: none; }
  .flow-stage .flow__step[data-n="6"] b { font-size: clamp(32px, 9vw, 40px); }
}
@media (min-width: 701px) and (max-width: 900px) {
  .flow-stage .flow .flow__step { width: min(var(--pw), 440px); }
}
/* short landscape windows (a phone on its side): the card is capped to the list area and scrolls,
   so it can never cover the status chips below it */
@media (min-width: 701px) and (max-height: 560px) {
  .flow-stage .flow .flow__step { max-height: 100%; overflow-y: auto; padding: 14px 20px 16px; }
  .flow-stage .flow .flow__intro { max-height: calc(100% - 60px); overflow-y: auto; padding: 14px 20px 16px; }
  .flow-stage .flow .flow__steps .flow__step.is-active,
  .flow-stage .flow[data-step="0"] .flow__intro { pointer-events: auto; }
  .flow-stage .flow__step::before { margin-bottom: 8px; }
  .flow-stage .flow__step b { font-size: clamp(20px, 6vh, 30px); line-height: 1.3; }
  .flow-stage .flow__step[data-n="6"] b { font-size: clamp(22px, 7vh, 34px); }
  .flow-stage .flow__step > span:last-child { font-size: 15px; line-height: 1.55; margin-top: 6px; }
  .flow-stage .flow .flow__intro .h2 { font-size: clamp(20px, 6vh, 28px); }
  .flow-stage .flow .flow__intro .lead { font-size: 15px; line-height: 1.55; margin-top: 6px; }
  .flow-stage .flow__chips { margin-top: 8px; }
  .flow-stage .flow__pin { padding-top: 10px; padding-bottom: 14px; }
}

/* story Play control (assets/site.js drives the page scroll; shown only while #flow has .flow-stage) */
.flow__play { min-height: 44px; margin-top: 16px; padding-top: 8px; padding-bottom: 8px; }
.flow__play[hidden] { display: none; }
.flow__play svg { flex: none; }
.flow__play span { min-width: 0; }
.flow__head .flow__play { margin-top: 0; margin-left: auto; }
.flow-stage .flow__play { pointer-events: auto; background: rgba(16, 16, 18, 0.72); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.flow-stage .flow__play:hover { background: linear-gradient(var(--red-dim), var(--red-dim)), rgba(16, 16, 18, 0.72); }
@media (max-width: 360px) {
  .flow__play { width: 100%; white-space: normal; }
  .flow__head .flow__play { margin-left: 0; }
}

/* ---------- shared inner-page polish (CSS part; site.js adds --i and .is-in). Inner pages only; all off under reduced motion ---------- */
:is(.hero--page ~ .section, .hero--page ~ .modgroup > .section) .card { box-shadow: inset 0 1px 0 rgba(198, 198, 204, 0.1); }
:is(.hero--page ~ .section, .hero--page ~ .modgroup > .section) .card:focus-within:not(:hover) { border-color: rgba(198, 198, 204, 0.5); box-shadow: inset 0 1px 0 rgba(198, 198, 204, 0.22); }
@media (prefers-reduced-motion: no-preference) {
  .js :is(.hero--page ~ .section, .hero--page ~ .modgroup > .section) .grid > .reveal.is-in { transition-delay: calc(var(--i, 0) * 60ms); }
  .js :is(.hero--page ~ .section + .section, .hero--page ~ .modgroup > .section + .section, .hero--page ~ .modgroup + .section) { position: relative; }
  .js :is(.hero--page ~ .section + .section, .hero--page ~ .modgroup > .section + .section, .hero--page ~ .modgroup + .section)::before,
  .js :is(.hero--page ~ .section + .section, .hero--page ~ .modgroup > .section + .section, .hero--page ~ .modgroup + .section)::after {
    content: ""; position: absolute; top: 0; pointer-events: none;
    --e: max(var(--pad), calc((100% - var(--maxw)) / 2 + var(--pad)));
  }
  .js :is(.hero--page ~ .section + .section, .hero--page ~ .modgroup > .section + .section, .hero--page ~ .modgroup + .section)::before {
    left: var(--e); right: var(--e); height: 1px; background: var(--line);
    transform: scaleX(0); transform-origin: 0 50%; transition: transform 900ms var(--ease);
  }
  .js :is(.hero--page ~ .section + .section, .hero--page ~ .modgroup > .section + .section, .hero--page ~ .modgroup + .section)::after {
    right: var(--e); width: 5px; height: 5px; margin: -2px -2.5px 0 0; border-radius: 50%; background: var(--muted);
    opacity: 0; transition: opacity 300ms ease 800ms;
  }
  .js :is(.hero--page ~ .section + .section, .hero--page ~ .modgroup > .section + .section, .hero--page ~ .modgroup + .section).is-in::before { transform: scaleX(1); }
  .js :is(.hero--page ~ .section + .section, .hero--page ~ .modgroup > .section + .section, .hero--page ~ .modgroup + .section).is-in::after { opacity: 1; }
  /* platform architecture: layers fade in bottom to top, then the arrows draw once */
  @keyframes archin { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
  @keyframes archdash { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
  .js .archdiagram > * { opacity: 0; }
  .js .archdiagram.is-in > * { animation: archin 520ms var(--ease) both; animation-delay: var(--d, 0ms); }
  .js .archdiagram > :nth-child(5) { --d: 0ms; }
  .js .archdiagram > :nth-child(4) { --d: 110ms; }
  .js .archdiagram > :nth-child(3) { --d: 220ms; }
  .js .archdiagram > :nth-child(2) { --d: 330ms; }
  .js .archdiagram > :nth-child(1) { --d: 440ms; }
  .js .archdiagram.is-in .arch-flow path { stroke-dasharray: 24; animation: archdash 600ms var(--ease) both; animation-delay: calc(var(--d, 0ms) + 600ms); }
}

/* ---------- responsive ---------- */
@media (max-width: 940px) {
  .split { grid-template-columns: 1fr; }
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
  .ftr__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 940px) {
  .hdr__in { gap: 12px; }
}

/* contact stays in the burger panel and the footer; the header shows the demo button instead */
@media (min-width: 1280px) {
  .nav a[href="contact.html"] { display: none; }
}

/* the burger-panel demo button only exists at phone width (see the max-width: 620px block) */
.nav a.nav__demo { display: none; }

/* Desktop nav (1280px and up). .wrap stops growing at 1180px, so a wider screen gives the header no more room:
   measured, seven Thai items at the default 14px padding wrap to two rows above 1440px and spill out of the
   1084px content box. The compact values therefore apply at every width from 1280px, not only 1280-1440px. */
@media (min-width: 1280px) {
  .nav { gap: 2px; }
  .nav a { padding: 8px 10px; white-space: nowrap; }
  .hdr__in { gap: 16px; }
  .hdr__cta { gap: 8px; }
  .hdr__cta .btn { padding: 10px 16px; }
}

@media (max-width: 1279px) {
  .burger { display: grid; }
  .nav {
    position: absolute;
    top: 70px;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 14px var(--pad) 20px;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    max-height: calc(100vh - 70px);
    max-height: calc(100dvh - 70px);
    overflow-y: auto;
    display: none;
  }
  .nav.is-open { display: flex; }
  .nav a { padding: 12px 14px; font-size: 16.5px; }
}

@media (max-width: 620px) {
  .hdr__cta .btn { display: none; }
  .nav a.nav__demo {
    display: flex;
    margin-top: 10px;
    padding: 13px 26px;
    font-size: 16px;
    font-weight: 600;
    color: #fff;
    background: var(--red);
    border-radius: 999px;
  }
  .nav a.nav__demo:hover { background: var(--red-bright); color: #fff; }
  body { font-size: 16px; }
  .grid--3, .grid--4, .grid--2 { grid-template-columns: 1fr; }
  .tiles { grid-template-columns: repeat(2, 1fr); }
  .field--2 { grid-template-columns: 1fr; }
  .ftr__grid { grid-template-columns: 1fr; }
  .btn { width: 100%; white-space: normal; }
  .btn-row { flex-direction: column; }
  .arch-layer { flex-direction: column; gap: 14px; padding: 20px; }
  .arch-flow { gap: 18px; }
}

/* ---------- focus visibility ---------- */
.btn:focus-visible,
.nav a:focus-visible,
.chip:focus-visible,
.logo:focus-visible,
a:focus-visible,
.flow__btn:focus-visible,
.flow__play:focus-visible,
.field input:focus-visible,
.field textarea:focus-visible,
.field select:focus-visible,
.burger:focus-visible {
  outline: 2px solid var(--red-text);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .js .reveal { opacity: 1; transform: none; }
  .js .nbc .nb, .js .hero__sub, .js .hero:not(.hero--page) .lead, .js .hero:not(.hero--page) .btn-row { animation: none; }
}

/* ---------- form validation (contact) ---------- */
.ferr { font-size: 13.5px; color: var(--red-text); line-height: 1.5; }
.field input.is-invalid, .field textarea.is-invalid { border-color: var(--red); }

/* consent checkbox (contact form) */
.field--check label{display:flex;gap:12px;align-items:flex-start;min-height:44px;padding-block:8px;font-weight:400;cursor:pointer}
.field--check input{width:24px;height:24px;flex:none;margin:0;padding:0;accent-color:var(--red)}
.field--check input:focus-visible{outline:2px solid var(--red-text);outline-offset:2px}
.field--check a{text-decoration:underline}

/* long-form text pages (privacy) */
.prose { max-width: 68ch; line-height: 1.75; }
.prose h2 { font-size: clamp(20px, 2.4vw, 24px); line-height: 1.4; margin: 36px 0 10px; }
.prose h2:first-child { margin-top: 0; }
.prose p, .prose ul { margin: 0 0 14px; }
.prose ul { padding-left: 1.3em; }
.prose a { text-decoration: underline; }
.prose .prose__note { color: var(--muted); font-size: 14.5px; margin-top: 36px; }

/* ---------- header: language switcher fit ---------- */
/* (the old 1021-1100px nav padding rule is gone: the burger now covers everything below 1280px) */
/* narrow phones: logo + switcher + burger must fit in 320px */
@media (max-width: 400px) {
  .hdr__in { gap: 6px; }
  .hdr__cta { gap: 6px; }
  .lang a { padding: 8px 9px; }
}

/* ---------- English pages ---------- */
/* Latin text needs the Latin face first and tighter leading than Thai */
html[lang="en"] { --font: "IBM Plex Sans", "IBM Plex Sans Thai", -apple-system, sans-serif; }
html[lang="en"] body { line-height: 1.55; }
html[lang="en"] .h1--hero {
  font-size: clamp(34px, 6.6vw, 60px);
  line-height: 1.12;
  letter-spacing: -0.02em;
  overflow-wrap: normal;
}
html[lang="en"] .nav a { white-space: nowrap; }

/* home: fifth card in the five-card multi-system grid fills the last row */
@media (min-width: 941px) {
  .grid--3 > .card:nth-child(5):last-child { grid-column: span 2; }
}

/* the global .btn rule at 620px would stretch this button across the story header */
@media (min-width: 361px) and (max-width: 620px) {
  .flow__head .flow__play { width: auto; }
}

/* ---------- dot wall (Scale section) ----------
   Tints are for this section only. They are NOT status colours (ok/warn/crit/offline). */
.dw {
  --dw-video: #3F8CE8;
  --dw-bas:   #B9C4FF;
  --dw-intr:  #7B5FD6;
  --dw-fire:  #E08CC0;
  --dw-acc:   #FFFFFF;
}
.dw__grid {
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "hero" "field" "stats";
  row-gap: 26px; min-width: 0;
}
.dw__grid > * { min-width: 0; }
.dw__stat { margin: 0; }
.dw__n {
  display: block; font-weight: 700; letter-spacing: -0.02em; line-height: 1.05;
  font-variant-numeric: tabular-nums; color: var(--text);
}
.dw__l { color: var(--text-2); line-height: 1.5; font-size: 15px; overflow-wrap: anywhere; }

.dw__chip { display: block; flex: none; width: 14px; height: 14px; }
.dw__stat--video .dw__chip { background: var(--dw-video); border-radius: 50%; }
.dw__stat--bas   .dw__chip { background: var(--dw-bas); }
.dw__stat--intr  .dw__chip { background: var(--dw-intr); transform: rotate(45deg) scale(0.74); }
.dw__stat--fire  .dw__chip { border: 2px solid var(--dw-fire); border-radius: 50%; }
.dw__stat--acc   .dw__chip {
  background:
    linear-gradient(var(--dw-acc), var(--dw-acc)) center / 3px 100% no-repeat,
    linear-gradient(var(--dw-acc), var(--dw-acc)) center / 100% 3px no-repeat;
}

/* hero stat */
.dw__stat--hero {
  grid-area: hero; display: grid; align-items: baseline;
  grid-template-columns: auto auto minmax(0, 1fr); column-gap: 14px;
}
.dw__stat--hero .dw__n { grid-column: 1; grid-row: 1; font-size: clamp(60px, 8.4vw, 92px); }
.dw__stat--hero .dw__chip { grid-column: 2; grid-row: 1; }
.dw__stat--hero .dw__l { grid-column: 3; grid-row: 1; font-size: 20px; }

/* field */
.dw__field { grid-area: field; }
.dw__plot { position: relative; width: 100%; max-width: 100%; aspect-ratio: 600 / 860; }
.dw__svg, .dw__cv { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: 100%; }
.dw__svg--wide { display: none; }
.dw__cv { display: none; pointer-events: none; }
.dw--live .dw__svg { display: none; }
.dw--live .dw__cv { display: block; }
.dw-fv { fill: var(--dw-video); }
.dw-fb { fill: var(--dw-bas); }
.dw-fi { fill: var(--dw-intr); }
.dw-ff { fill: var(--dw-fire); }
.dw-fa { fill: var(--dw-acc); }
.dw-sf { stroke: var(--dw-fire); }
.dw__brackets { display: none; }

/* stat list (phone) */
.dw__stats { grid-area: stats; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.dw__stats .dw__stat {
  display: grid; grid-template-columns: 16px minmax(0, 1fr); column-gap: 12px;
  padding: 14px 0; border-bottom: 1px solid var(--line-soft); align-items: start;
}
.dw__stats .dw__chip { grid-column: 1; grid-row: 1; margin-top: 11px; }
.dw__stats .dw__n { grid-column: 2; grid-row: 1; font-size: 32px; }
.dw__stats .dw__l { grid-column: 2; grid-row: 2; font-size: 14px; }

.dw__key { margin: 26px 0 0; max-width: 78ch; font-size: 13px; line-height: 1.6; color: var(--muted); }

/* phone: chips are plain tinted dots, matching the circles in the field */
@media (max-width: 719px) {
  .dw__stat--hero { grid-template-columns: auto minmax(0, 1fr); column-gap: 10px; align-items: center; }
  .dw__stat--hero .dw__n { grid-column: 1 / -1; grid-row: 1; margin-bottom: 6px; }
  .dw__stat--hero .dw__chip { grid-column: 1; grid-row: 2; }
  .dw__stat--hero .dw__l { grid-column: 2; grid-row: 2; font-size: 16px; }
  .dw__stat--bas .dw__chip, .dw__stat--intr .dw__chip, .dw__stat--fire .dw__chip, .dw__stat--acc .dw__chip {
    border-radius: 50%; border: 0; transform: none;
  }
  .dw__stat--bas  .dw__chip { background: var(--dw-bas); }
  .dw__stat--intr .dw__chip { background: var(--dw-intr); }
  .dw__stat--fire .dw__chip { background: var(--dw-fire); }
  .dw__stat--acc  .dw__chip { background: var(--dw-acc); }
}

/* wide: tablet and desktop */
@media (min-width: 720px) {
  .dw__plot { aspect-ratio: 1062 / 378; }
  .dw__svg--tall { display: none; }
  .dw__svg--wide { display: block; }
  .dw--live .dw__svg--wide { display: none; }
  .dw__brackets { display: flex; margin-top: 10px; }
  .dw__br { flex: 1 1 0; min-width: 0; height: 7px; margin: 0 1px; border: 2px solid; border-top: 0; transform-origin: 0 50%; }
  .dw__br--video { border-color: var(--dw-video); }
  .dw__br--bas   { border-color: var(--dw-bas); }
  .dw__br--intr  { border-color: var(--dw-intr); }
  .dw__br--fire  { border-color: var(--dw-fire); }
  .dw__br--acc   { border-color: var(--dw-acc); }
  .dw__stats { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 9px; }
  .dw__stats .dw__stat {
    display: block; padding: 14px 14px 16px; background: var(--bg);
    border: 1px solid var(--line); border-top: 3px solid var(--line); border-radius: var(--radius-sm);
  }
  .dw__stat--bas  { border-top-color: var(--dw-bas) !important; }
  .dw__stat--intr { border-top-color: var(--dw-intr) !important; }
  .dw__stat--fire { border-top-color: var(--dw-fire) !important; }
  .dw__stat--acc  { border-top-color: var(--dw-acc) !important; }
  .dw__stats .dw__chip { margin: 0 0 10px; }
  .dw__stats .dw__n { font-size: clamp(30px, 3.4vw, 40px); }
  .dw__stats .dw__l { display: block; margin-top: 4px; }
}

/* one-shot settle of the brackets only (class .dw--live is added by dotwall.js only when the canvas runs). The numbers are never hidden. */
.dw--live .dw__br { transform: scaleX(0); }
.dw--done .dw__br { transform: none; transition: transform 400ms var(--ease); }

/* ---------- platform: module sub-nav, document request ---------- */
.modnav { background: var(--bg); border-block: 1px solid var(--line-soft); }
.modnav__in {
  display: flex; gap: 10px; overflow-x: auto; padding-block: 10px;
  scroll-snap-type: x proximity; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent);
}
.modnav__in::-webkit-scrollbar { display: none; }
.modnav a {
  flex: none; scroll-snap-align: start; display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 18px; border: 1px solid var(--offline); border-radius: 999px;
  font-size: 15px; font-weight: 600; white-space: nowrap; color: var(--text-2);
}
.modnav a:hover { color: #fff; border-color: var(--red); }
.modnav a[aria-current="true"] { background: var(--red-dim); border-color: var(--red); color: #fff; }
@media (min-width: 900px) {
  .modnav__in { overflow-x: visible; -webkit-mask-image: none; mask-image: none; }
}
@media (min-width: 768px) {
  .modnav { position: sticky; top: 70px; z-index: 40; background: rgba(16, 16, 18, 0.92); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
  .modgroup [id] { scroll-margin-top: 150px; }
}
.docreq { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-top: 30px; text-align: center; }
.docreq__note { margin: 0; overflow-wrap: anywhere; }
.modback { margin-top: 26px; text-align: center; font-size: 14px; }
.modback a { color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.modback a:hover { color: #fff; }
@media (max-width: 480px) {
  .docreq .btn { width: 100%; }
}

/* ---------- contact: request-type blocks ---------- */
.tf { display: grid; gap: 17px; border: 0; padding: 0; margin: 0; min-width: 0; }
.tf[hidden] { display: none; }
.field label, .field legend, .ferr, .fhint { overflow-wrap: anywhere; }
.field legend { font-size: 14.5px; font-weight: 600; color: var(--text-2); padding: 0; margin-bottom: 7px; }
.fhint { font-size: 13.5px; color: var(--muted); line-height: 1.5; margin: 0; }
fieldset.field { border: 0; padding: 0; margin: 0; min-width: 0; }
.field select { text-overflow: ellipsis; }
.field select.is-invalid { border-color: var(--red); }
.tf textarea { min-height: 11.5em; }
.field--check.cbgroup[aria-invalid="true"] legend { color: var(--red-text); }
.field--check.cbgroup label { min-height: 44px; }
/* focus and scrollIntoView must not leave a field under the sticky header */
.field input, .field select, .field textarea, .field legend, .field--check { scroll-margin-top: 96px; }
@media print { .dw--live .dw__br { transform: none; } .dw--live .dw__cv { display: none; } .dw--live .dw__svg--tall { display: block; } }
@media print and (min-width: 720px) { .dw--live .dw__svg--tall { display: none; } .dw--live .dw__svg--wide { display: block; } }

/* no aspect-ratio support: keep the plot height with the padding trick (children are absolutely placed) */
@supports not (aspect-ratio: 1) {
  .dw__plot { height: 0; padding-top: 143.33%; }
}
@supports not (aspect-ratio: 1) {
  @media (min-width: 720px) { .dw__plot { padding-top: 35.59%; } }
}
@media print { .js .reveal, .js .archdiagram > * { opacity: 1; transform: none; } }
