/* ============================================================================
   Mancube — capability register
   ----------------------------------------------------------------------------
   One stylesheet, no framework, no build step, no runtime network request. The
   fonts are vendored next to this file, so the page renders identically on a
   conference wifi that resolves nothing.

   The world is a printed capability register: hairline rules edge to edge, a
   mono index in the left gutter, and every claim sitting in a row next to the
   thing that proves it. Deep petrol is the only saturated colour on the page —
   it marks evidence and nothing else, so "this is checkable" is legible before
   a word is read.
   ============================================================================ */

/* ── Fonts ─────────────────────────────────────────────────────────────────
   Anton and Archivo are one superfamily lineage, which is why the condensed
   display sits on the body face without a seam. JetBrains Mono carries every
   coordinate, version and command — anything a reader might retype. */

@font-face {
  font-family: "Anton";
  src: url("fonts/anton-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ── Tokens ────────────────────────────────────────────────────────────────
   The complete light palette is defined on bare :root, because the default
   viewer setting stamps nothing on the document — only prefers-color-scheme
   separates light from dark there. Both blocks below redefine tokens only;
   no component ever declares a colour inside a media or [data-theme] block,
   which is what makes an artifact render one theme's text on the other
   theme's ground. */

:root {
  /* Ground: a neutral pulled a few degrees toward the petrol, so paper and
     accent read as one set rather than two borrowed palettes. */
  --paper: #f6f5f1;
  --paper-2: #eeece5;
  --paper-3: #e5e3da;
  --ink: #15191a;
  --ink-2: #4d5857;
  /* Measured, not guessed: the previous #77807e came out at 3.72:1 on --paper,
     under the 4.5 floor, and it is the colour every coordinate, row index and
     group label is set in. This lands at 4.66:1 on the darker of the two
     grounds it sits on (--paper-2, under the filled bands and the footer) and
     5.05:1 on plain --paper. */
  --ink-3: #616a68;
  --rule: #d3d0c6;
  --rule-strong: #b4b1a5;

  /* The one saturated colour. Evidence, links, and live status — nothing
     decorative ever takes it. */
  --petrol: #0b4f4a;
  --petrol-ink: #073b37;
  --petrol-wash: #e2ebe8;

  /* The event bar is the one component with an inverted ground, so it needs its
     own pair rather than borrowing --petrol. Hardcoding these is what broke it:
     in dark theme --petrol lifts to a pale teal, and near-white text on pale
     teal measured 1.67:1. */
  --notice-bg: #0b4f4a;
  --notice-fg: #f4faf8;
  --notice-fg-2: #b9d8d2;

  --shadow: 0 1px 0 rgb(21 25 26 / 6%);

  --font-display: "Anton", "Archivo Narrow", "Arial Narrow", sans-serif;
  --font-body: "Archivo", ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;

  /* Type scale — 1.26 ratio, held to across the page. */
  --t-mono: 0.75rem;
  --t-small: 0.875rem;
  --t-body: 1.0625rem;
  --t-lead: 1.3125rem;
  --t-h3: 1.5rem;
  --t-h2: clamp(2rem, 1.2rem + 3.4vw, 3.25rem);
  --t-hero: clamp(2.75rem, 1rem + 8vw, 6.5rem);

  --gutter: clamp(1.15rem, 4vw, 3rem);
  --max: 1180px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0e1211;
    --paper-2: #151a19;
    --paper-3: #1d2422;
    --ink: #e9e7e0;
    --ink-2: #a3aeab;
    --ink-3: #7b8583;
    --rule: #2a3230;
    --rule-strong: #3e4846;

    /* The deep petrol has nowhere near enough contrast on a dark ground, so
       the token lifts rather than the components changing. */
    --petrol: #46b3a6;
    --petrol-ink: #6fcabe;
    --petrol-wash: #14312e;

    /* Stays a deep ground in dark theme; only the text lifts. */
    --notice-bg: #0d3d38;
    --notice-fg: #d8efeb;
    --notice-fg-2: #a9cdc7;

    --shadow: 0 1px 0 rgb(0 0 0 / 40%);
  }
}

:root[data-theme="dark"] {
  --paper: #0e1211;
  --paper-2: #151a19;
  --paper-3: #1d2422;
  --ink: #e9e7e0;
  --ink-2: #a3aeab;
  --ink-3: #7b8583;
  --rule: #2a3230;
  --rule-strong: #3e4846;
  --petrol: #46b3a6;
  --petrol-ink: #6fcabe;
  --petrol-wash: #14312e;
  --notice-bg: #0d3d38;
  --notice-fg: #d8efeb;
  --notice-fg-2: #a9cdc7;
  --shadow: 0 1px 0 rgb(0 0 0 / 40%);
}

/* ── Base ──────────────────────────────────────────────────────────────── */

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

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

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

body {
  margin: 0;
  /* Explicit, from a token: the viewer paints its own ground behind the page,
     so a transparent body silently borrows the host's theme. */
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
p,
ul,
ol,
figure {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

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

a:hover {
  color: var(--petrol-ink);
}

:focus-visible {
  outline: 2px solid var(--petrol);
  outline-offset: 3px;
  border-radius: 1px;
}

code,
kbd,
samp {
  font-family: var(--font-mono);
  font-size: 0.92em;
}

img,
svg {
  max-width: 100%;
  height: auto;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 0.7rem 1.1rem;
  z-index: 100;
  font-family: var(--font-mono);
  font-size: var(--t-mono);
}

.skip:focus {
  left: 0;
}

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

/* ── Layout primitives ─────────────────────────────────────────────────── */

.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* A section is a register entry: full-bleed hairline above, mono index in the
   left gutter, content in the measure. */
.band {
  border-top: 1px solid var(--rule);
}

.band--fill {
  background: var(--paper-2);
}

.band__inner {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: 0 clamp(1rem, 3vw, 2.5rem);
  padding-block: clamp(3rem, 7vw, 5.5rem);
}

@media (max-width: 46rem) {
  .band__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
}

.index {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--petrol);
  padding-top: 0.55rem;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 46rem) {
  .index {
    padding-top: 0;
    padding-bottom: 0.9rem;
  }
}

.band__body > * + * {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}

h2 {
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: 400;
  line-height: 0.98;
  letter-spacing: -0.005em;
  text-wrap: balance;
  text-transform: uppercase;
  max-width: 18ch;
}

h3 {
  font-family: var(--font-body);
  font-size: var(--t-h3);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 58ch;
}

.prose {
  max-width: 64ch;
}

.prose p + p {
  margin-top: 1em;
}

/* ── Masthead ──────────────────────────────────────────────────────────── */

.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}

@supports not (backdrop-filter: blur(1px)) {
  .masthead {
    background: var(--paper);
  }
}

.masthead__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3.5rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-display);
  font-size: 1.3rem;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
}

.wordmark:hover {
  color: var(--ink);
}

.wordmark__mark {
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
}

.nav {
  display: flex;
  gap: clamp(0.9rem, 2.4vw, 1.9rem);
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  letter-spacing: 0.04em;
}

.nav a {
  color: var(--ink-2);
  text-decoration: none;
  padding-block: 0.4rem;
  border-bottom: 1px solid transparent;
  /* At 390px the CTA was wrapping mid-phrase and taking the masthead to two
     ragged lines. Nav items never wrap; if they stop fitting, one is hidden
     below instead. */
  white-space: nowrap;
}

.nav a:hover {
  color: var(--ink);
  border-bottom-color: var(--petrol);
}

@media (max-width: 40rem) {
  .nav__optional {
    display: none;
  }
  .nav {
    gap: 0.85rem;
  }
  .wordmark {
    font-size: 1.15rem;
  }
}

.nav__cta {
  color: var(--petrol) !important;
  font-weight: 700;
}

/* ── Event notice ──────────────────────────────────────────────────────── */

.notice {
  background: var(--notice-bg);
  color: var(--notice-fg);
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  letter-spacing: 0.03em;
}

.notice__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.9rem;
  padding-block: 0.6rem;
}

.notice b {
  font-weight: 700;
}

.notice span {
  color: var(--notice-fg-2);
}

/* Without this the address takes the global petrol link colour, which in light
   theme is the same value as --notice-bg — measured at 1.00:1, i.e. invisible. */
.notice a {
  color: var(--notice-fg);
  text-decoration-color: var(--notice-fg-2);
}

.notice a:hover {
  color: var(--notice-fg);
  text-decoration-color: var(--notice-fg);
}

/* ── Hero ──────────────────────────────────────────────────────────────── */

.hero {
  padding-block: clamp(3rem, 8vw, 6rem) clamp(2rem, 4vw, 3rem);
}

.hero__kicker {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--petrol);
}

h1 {
  margin-top: 1.4rem;
  font-family: var(--font-display);
  font-size: var(--t-hero);
  font-weight: 400;
  line-height: 0.9;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  max-width: 14ch;
  text-wrap: balance;
}

h1 em {
  font-style: normal;
  color: var(--petrol);
}

.hero__lead {
  margin-top: 1.6rem;
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 54ch;
}

.hero__actions {
  margin-top: 2.2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  align-items: center;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-decoration: none;
  padding: 0.75rem 1.25rem;
  border: 1px solid var(--petrol);
  transition: background-color 0.15s ease, color 0.15s ease;
}

.btn--solid {
  background: var(--petrol);
  color: var(--paper);
}

.btn--solid:hover {
  background: var(--petrol-ink);
  border-color: var(--petrol-ink);
  color: var(--paper);
}

.btn--ghost {
  color: var(--petrol);
  background: transparent;
}

.btn--ghost:hover {
  background: var(--petrol-wash);
  color: var(--petrol-ink);
}

/* ── The manifest strip: the hero's evidence, above the fold ───────────── */

.manifest {
  border-top: 1px solid var(--rule-strong);
  border-bottom: 1px solid var(--rule);
}

.manifest__label {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-block: 0.9rem 0.2rem;
}

.manifest__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  border-left: 1px solid var(--rule);
}

.artifact {
  border-right: 1px solid var(--rule);
  border-top: 1px solid var(--rule);
  padding: 1.1rem clamp(0.9rem, 2vw, 1.4rem) 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
}

.artifact__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}

.artifact__name {
  font-family: var(--font-display);
  font-size: 1.35rem;
  text-transform: uppercase;
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
}

.artifact__name:hover {
  color: var(--petrol);
}

.artifact__ver {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 700;
  color: var(--petrol);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.artifact__what {
  font-size: var(--t-small);
  color: var(--ink-2);
  line-height: 1.4;
}

.artifact__coord {
  margin-top: auto;
  padding-top: 0.55rem;
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

/* ── Register rows: the services ───────────────────────────────────────── */

.register {
  border-top: 1px solid var(--rule-strong);
}

.row {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1.15fr) minmax(0, 1.5fr);
  gap: 0.35rem clamp(0.8rem, 2.5vw, 2rem);
  align-items: baseline;
  padding-block: 1.15rem;
  border-bottom: 1px solid var(--rule);
}

@media (max-width: 46rem) {
  .row {
    grid-template-columns: 2.5rem minmax(0, 1fr);
  }
  .row__note {
    grid-column: 2;
  }
}

.row__n {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.row__name {
  font-weight: 600;
  line-height: 1.3;
}

.row__note {
  color: var(--ink-2);
  font-size: var(--t-small);
  line-height: 1.5;
}

/* The evidence tag. Petrol only appears here and on links, so a reader
   scanning the column sees exactly which claims are backed by something
   they can install. */
.ev {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--petrol);
  background: var(--petrol-wash);
  padding: 0.1rem 0.4rem;
  white-space: nowrap;
  text-decoration: none;
}

a.ev:hover {
  background: var(--petrol);
  color: var(--paper);
}

/* ── Cards ─────────────────────────────────────────────────────────────── */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
}

.card {
  background: var(--paper);
  padding: clamp(1.2rem, 2.5vw, 1.75rem);
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  min-width: 0;
}

.band--fill .card {
  background: var(--paper-2);
}

.card__tag {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--petrol);
}

.card h3 {
  font-size: 1.2rem;
}

.card p {
  font-size: var(--t-small);
  color: var(--ink-2);
  line-height: 1.55;
}

.card ul {
  font-size: var(--t-small);
  color: var(--ink-2);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.card li {
  padding-left: 1rem;
  position: relative;
  line-height: 1.45;
}

.card li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.4rem;
  height: 1px;
  background: var(--petrol);
}

/* ── Terminal block ────────────────────────────────────────────────────── */

.term {
  border: 1px solid var(--rule-strong);
  background: var(--paper-2);
  font-family: var(--font-mono);
  font-size: var(--t-small);
  line-height: 1.7;
  overflow-x: auto;
  padding: 1.1rem 1.25rem;
  color: var(--ink);
  tab-size: 2;
  /* The block is authored with real newlines and no <br>. Without this the
     three commands collapse onto one line and the comments read as prose. */
  white-space: pre;
}

.band--fill .term {
  background: var(--paper);
}

.term .c {
  color: var(--ink-3);
}

.term .p {
  color: var(--petrol);
  font-weight: 700;
  user-select: none;
}

/* ── Facts: the air-gap section's counted claims ───────────────────────── */

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1px;
  background: var(--rule);
  border-block: 1px solid var(--rule);
}

.fact {
  background: var(--paper);
  padding: 1.1rem 1.15rem 1.25rem;
}

.band--fill .fact {
  background: var(--paper-2);
}

.fact__n {
  font-family: var(--font-display);
  font-size: 2.35rem;
  line-height: 1;
  color: var(--petrol);
  font-variant-numeric: tabular-nums;
}

.fact__t {
  margin-top: 0.45rem;
  font-size: var(--t-small);
  color: var(--ink-2);
  line-height: 1.45;
}

/* ── Contact ───────────────────────────────────────────────────────────── */

.contact__addr {
  font-family: var(--font-mono);
  font-size: clamp(1.05rem, 3.5vw, 1.6rem);
  font-weight: 700;
  color: var(--petrol);
  text-decoration: none;
  overflow-wrap: anywhere;
  border-bottom: 2px solid var(--petrol);
  padding-bottom: 0.1rem;
}

.contact__addr:hover {
  color: var(--petrol-ink);
  border-bottom-color: var(--petrol-ink);
}

.contact__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
}

.contact__cols h3 {
  font-size: 1.05rem;
  margin-bottom: 0.5rem;
}

.contact__cols p,
.contact__cols li {
  font-size: var(--t-small);
  color: var(--ink-2);
  line-height: 1.55;
}

.contact__cols ul {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

/* ── Footer ────────────────────────────────────────────────────────────── */

.foot {
  border-top: 1px solid var(--rule-strong);
  background: var(--paper-2);
}

.foot__inner {
  padding-block: 2.25rem 2.75rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  align-items: flex-start;
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  color: var(--ink-3);
  line-height: 1.7;
}

.foot a {
  color: var(--ink-2);
  text-decoration: none;
}

.foot a:hover {
  color: var(--petrol);
}

.foot__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.2rem;
}

/* ── Portfolio ─────────────────────────────────────────────────────────────
   Same register grammar as the services above, grouped by the problem each
   product sits in front of. The whole row is the link target: at a conference
   this is read on a phone, and a 12px product name is not a tap target. */

.pf__group + .pf__group {
  margin-top: clamp(1.75rem, 3.5vw, 2.75rem);
}

.pf__label {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: 0.55rem;
  border-bottom: 1px solid var(--rule-strong);
}

.pf__list {
  display: flex;
  flex-direction: column;
}

.pf__item {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr) auto;
  gap: 0.2rem clamp(0.8rem, 2.5vw, 1.75rem);
  align-items: baseline;
  padding-block: 1rem;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
  transition: background-color 0.12s ease;
}

a.pf__item:hover {
  background: var(--petrol-wash);
}

@media (max-width: 46rem) {
  .pf__item {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .pf__desc {
    grid-column: 1 / -1;
  }
}

.pf__name {
  font-family: var(--font-display);
  font-size: 1.2rem;
  text-transform: uppercase;
  line-height: 1.05;
  letter-spacing: 0.005em;
  color: var(--ink);
  min-width: 0;
  overflow-wrap: anywhere;
}

a.pf__item:hover .pf__name {
  color: var(--petrol);
}

.pf__desc {
  font-size: var(--t-small);
  color: var(--ink-2);
  line-height: 1.5;
  min-width: 0;
}

.pf__ver {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 700;
  color: var(--petrol);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  justify-self: end;
}

.pf__ver--muted {
  color: var(--ink-3);
}

/* A count line that carries the whole argument of the section in one row. */
.tally {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.75rem;
  font-family: var(--font-mono);
  font-size: var(--t-small);
  color: var(--ink-2);
  border-block: 1px solid var(--rule-strong);
  padding-block: 0.9rem;
}

.tally b {
  color: var(--petrol);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ── The scan card ─────────────────────────────────────────────────────────
   A page that people are told about out loud needs a way to be handed over
   without spelling a URL across a hall. On desktop it sits beside the hero
   copy; on mobile it drops below the buttons, where it is still the thing a
   second person points a camera at. */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: end;
}

@media (max-width: 54rem) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
  }
}

.qr {
  /* Light ground in BOTH themes. Inverted QR codes scan on most modern phones
     but not all, and this one has one job at a moment when a retry is
     awkward. */
  background: #f6f5f1;
  border: 1px solid #b4b1a5;
  padding: 0.9rem 0.9rem 0.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  width: max-content;
  box-shadow: 0 1px 0 rgb(21 25 26 / 8%);
}

.qr__label,
.qr__url {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #616a68;
}

.qr__url {
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: none;
  color: #0b4f4a;
}

.qr__code {
  width: clamp(8rem, 30vw, 9.5rem);
  height: auto;
  display: block;
}

/* ── The contact block ─────────────────────────────────────────────────────
   The address is the primary route and keeps its weight; the handle sits under
   it as a second line rather than competing for the same rank. It is not a
   link — wa.me resolves phone numbers, not @handles, and a dead tap in front of
   someone is worse than plain text they can retype in three seconds. */

.contact__block {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.85rem;
}

.contact__wa {
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0.01em;
}

.contact__wa-k {
  color: var(--ink-3);
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-right: 0.5rem;
}

/* ── The poster gallery ────────────────────────────────────────────────────
   Grouped by product, in the same order as the portfolio above it, so the two
   sections read as one list seen twice rather than two lists. Thumbnails are
   420px WebP derivatives (~20 KB); the click target is a 1200px one (~104 KB).
   Both are generated by scripts/build-poster-gallery.py from the 2800x4200
   originals, which stay with their products. */

.pg__set + .pg__set {
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
}

.pg__k {
  font-family: var(--font-mono);
  font-size: var(--t-mono);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--rule-strong);
}

.pg__k a {
  color: var(--petrol);
  text-decoration: none;
}

.pg__k a:hover {
  color: var(--ink);
}

.pg__grid {
  margin-top: 0.85rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.7rem;
}

.pg__i {
  display: block;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  line-height: 0;
  transition: border-color 0.14s ease;
}

.pg__i:hover {
  border-color: var(--petrol);
}

.pg__i img {
  width: 100%;
  height: auto;
  display: block;
}

/* ── The decision table ────────────────────────────────────────────────────
   Four columns: what we're hired to do, the situation, what you get, and the
   measure. The last one is the point — it is what both sides look at afterwards
   to decide whether the money was well spent, so it is the only column that
   takes the accent.

   On a phone this stacks into a labelled block per row rather than a scrolling
   table, because a director reading on a train will not scroll a table
   sideways to find the column that matters. */

.dec {
  margin-top: 1.75rem;
  border-top: 1px solid var(--rule-strong);
}

.dec__h {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.25fr) minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 0.4rem clamp(0.8rem, 2vw, 1.5rem);
  padding-block: 0.7rem;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-mono);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.dec__r {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.25fr) minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 0.4rem clamp(0.8rem, 2vw, 1.5rem);
  padding-block: 1.15rem;
  border-bottom: 1px solid var(--rule);
  align-items: start;
}

.dec__n {
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
}

.dec__s,
.dec__g {
  font-size: var(--t-small);
  color: var(--ink-2);
  line-height: 1.5;
}

.dec__k {
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--petrol);
  font-weight: 600;
}

@media (max-width: 60rem) {
  .dec__h {
    display: none;
  }

  .dec__r {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.55rem;
    padding-block: 1.35rem;
  }

  /* The header row is gone, so each cell has to say what it is. */
  .dec__s::before,
  .dec__g::before,
  .dec__k::before {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--t-xs);
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-3);
    padding-bottom: 0.2rem;
  }

  .dec__s::before {
    content: "The situation";
  }

  .dec__g::before {
    content: "What you get";
  }

  .dec__k::before {
    content: "How you'll know it worked";
    color: var(--petrol);
  }
}

/* The three "when not to hire us" cards read as a caution, not a feature list. */
#notfor .card li::before,
#notfor .card__k {
  color: var(--ink-3);
}

/* The masthead is sticky, so an in-page jump lands with the heading hidden
   underneath it. Every anchor target needs to stop short of it. */
.band,
#main > section[id] {
  scroll-margin-top: 4.25rem;
}

/* ── Language switch ───────────────────────────────────────────────────────
   A real link to a real URL, not a JS toggle. The page has no framework and a
   second language is worth a shareable, indexable address rather than a state
   that vanishes when someone sends the link on. */

.lang {
  font-weight: 700;
  letter-spacing: 0.08em;
  border: 1px solid var(--rule-strong);
  padding: 0.2rem 0.45rem;
  color: var(--ink-2) !important;
}

.lang:hover {
  border-color: var(--petrol);
  color: var(--petrol) !important;
}

/* The translation notice. Stated once, at the top of the first section, rather
   than as a banner — it is a fact about the page, not a warning. */
.note--tr {
  margin-top: 0;
  margin-bottom: 1.1rem;
  padding-left: 0.7rem;
  border-left: 2px solid var(--rule-strong);
}

/* The Malay labels are longer than the English ones, so the same masthead that
   fits in one language ran 4px past a 390px viewport in the other. The switch
   gives the width back rather than a nav item disappearing in one language
   only — the two pages must stay structurally identical. */
@media (max-width: 40rem) {
  .nav {
    gap: 0.7rem;
  }

  .lang {
    padding: 0.15rem 0.32rem;
    letter-spacing: 0.03em;
  }
}
