@import url("tokens.css");

/* ==========================================================================
   NCAC / MPPN — base
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  overscroll-behavior-x: none;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, .u-display {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: var(--lh-tight);
  letter-spacing: -0.015em;
  margin: 0 0 var(--s-4);
  color: var(--navy);
}

h1 { font-size: clamp(2rem, 5.2vw, var(--fs-4xl)); }
h2 { font-size: clamp(1.65rem, 3.6vw, var(--fs-3xl)); }
h3 { font-size: clamp(1.25rem, 2.2vw, var(--fs-xl)); }

p { margin: 0 0 var(--s-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }

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

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

/* Visually hidden until focused. clip-path, not left:-9999px — the old
   trick creates a 10,000px-wide layout box that every overflow probe then
   reports as a failure, drowning the real offenders. */
.skip {
  position: absolute; top: 0; left: 0; z-index: 999;
  width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
  background: var(--navy); color: #fff; padding: var(--s-3) var(--s-4);
  font-family: var(--font-ui); font-size: var(--fs-sm);
}
.skip:focus {
  width: auto; height: auto; overflow: visible;
  clip-path: none; top: var(--s-4); left: var(--s-4);
}

/* --- i18n -----------------------------------------------------------------
   Scope the HIDE under the active-language class. Never force a display
   VALUE on the shown language — component rules out-specify a bare rule. */
html.lang-bm .t-en { display: none !important; }
html.lang-en .t-bm { display: none !important; }

/* --- layout --------------------------------------------------------------- */
.wrap { width: min(100% - 2.5rem, var(--container)); margin-inline: auto; }
.wrap-text { width: min(100% - 2.5rem, var(--container-text)); margin-inline: auto; }
@media (min-width: 48rem) { .wrap { width: min(100% - 4rem, var(--container)); } }

.section { padding-block: clamp(3.5rem, 8vw, var(--s-9)); }
.section--tint { background: var(--bg-alt); }
.section--invert { background: var(--navy); color: rgba(255,255,255,.86); }
.section--invert h2, .section--invert h3 { color: #fff; }
/* :not(.btn) matters — .section--invert a (0,1,1) out-specifies .btn (0,1,0),
   so without it a white .btn--onDark gets white text on a white face. */
.section--invert a:not(.btn) { color: #fff; }
.section--invert .btn { color: var(--btn-fg); }

.eyebrow {
  font-family: var(--font-ui);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--grey-500);
  margin: 0 0 var(--s-3);
}
.section--invert .eyebrow { color: var(--tint-300); }

.lede { font-size: var(--fs-lg); line-height: 1.55; color: var(--text-muted); }
.section--invert .lede { color: rgba(255,255,255,.8); }

.section-head { max-width: 46rem; margin-bottom: var(--s-6); }
.section-head--split {
  max-width: none; display: flex; flex-wrap: wrap; gap: var(--s-4);
  align-items: end; justify-content: space-between;
}
.section-head--split > div { max-width: 40rem; }

/* --- buttons --------------------------------------------------------------- */
.btn {
  --btn-bg: var(--navy); --btn-fg: #fff; --btn-bd: var(--navy);
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 700;
  line-height: 1; letter-spacing: .01em;
  padding: 0.95rem 1.4rem;
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1.5px solid var(--btn-bd); border-radius: var(--radius);
  text-decoration: none; cursor: pointer;
  transition: transform .18s var(--ease), background-color .18s var(--ease), color .18s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn--ghost { --btn-bg: transparent; --btn-fg: var(--navy); }
.btn--ghost:hover { --btn-bg: var(--navy); --btn-fg: #fff; }
.btn--gold { --btn-bg: var(--badge-gold); --btn-fg: var(--navy-deep); --btn-bd: var(--badge-gold); }
.btn--gold:hover { --btn-bg: #c6a34f; --btn-bd: #c6a34f; }
.btn--onDark { --btn-bg: #fff; --btn-fg: var(--navy); --btn-bd: #fff; }
.btn--onDarkGhost { --btn-bg: transparent; --btn-fg: #fff; --btn-bd: rgba(255,255,255,.5); }
.btn--onDarkGhost:hover { --btn-bg: #fff; --btn-fg: var(--navy); --btn-bd: #fff; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-3); }

.link-more {
  font-family: var(--font-ui); font-weight: 700; font-size: var(--fs-sm);
  text-decoration: none; display: inline-flex; align-items: center; gap: .45rem;
}
.link-more::after { content: "→"; transition: transform .18s var(--ease); }
.link-more:hover::after { transform: translateX(4px); }

/* --- photo slot -----------------------------------------------------------
   Deliberate, labelled placeholder. The CI manual supplied ZERO photography;
   these are photo-shaped so the layout is right when real images land. */
.ph {
  position: relative; overflow: hidden;
  background:
    linear-gradient(155deg, var(--tint-300) 0%, var(--navy) 78%);
  border-radius: var(--radius);
  display: grid; place-items: center;
  min-height: 14rem;
}
.ph::after {
  content: attr(data-label);
  position: absolute; inset: auto var(--s-4) var(--s-3) auto;
  font-family: var(--font-ui); font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
  color: rgba(255,255,255,.62);
}
.ph img.ph-mark { width: 38%; max-width: 150px; opacity: .28; }
.ph--tall { min-height: 26rem; }
.ph--wide { aspect-ratio: 16 / 9; min-height: 0; }

/* ==========================================================================
   Header
   ========================================================================== */

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255,255,255,.96);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--rule);
  transition: box-shadow .2s var(--ease);
}
.site-header.is-stuck { box-shadow: var(--shadow-sm); }

/* .header-top removed 2026-08-17: the navy strip carrying the full
   "Badan penasihat kepada Menteri..." line read as too loud above the
   lockup. The relationship to KPDN is stated in the hero eyebrow and the
   footer, where it belongs. */
.header-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); padding-block: var(--s-3);
}
.header-tools { display: flex; align-items: center; gap: var(--s-3); }

/* Row two. Measured on the live desktop header: eight items had a 0px gap
   between them and 12px to the language toggle, because squeezing them in
   beside a 169px lockup left the nav ~980px of a 1216px container. Giving the
   nav its own full-width row restores real spacing without dropping items the
   storyboard's own navigation list asks for. */
.nav-row { border-top: 1px solid var(--rule); }
@media (max-width: 67.99rem) { .nav-row { display: none; } }

.brand { display: flex; align-items: center; text-decoration: none; flex: 0 0 auto; }
/* The lockup is ~3:1, so its height drives a lot of horizontal width.
   At 1280 the header was 76px over; the logo, the nav gap and the language
   buttons each give some of that back. Measured, not guessed. */
.brand img { height: 46px; width: auto; }
@media (min-width: 68rem) { .brand img { height: 58px; } }

.lang-toggle { display: flex; gap: 1px; background: var(--rule); border-radius: var(--radius); overflow: hidden; }
.lang-toggle button {
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: 700;
  padding: .45rem .55rem; border: 0; background: #fff; color: var(--grey-500); cursor: pointer;
}
.lang-toggle button[aria-pressed="true"] { background: var(--navy); color: #fff; }

/* --- nav ------------------------------------------------------------------- */
.nav { display: none; }
@media (min-width: 68rem) { .nav { display: block; } }

.nav > ul {
  display: flex; list-style: none; margin: 0; padding: 0;
  /* was gap: 0, which is what made eight items read as one cramped block */
  gap: clamp(.25rem, 1.4vw, 1.25rem);
}
.nav > ul > li { position: relative; }
.nav > ul > li > a {
  display: block; padding: .85rem .25rem;
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  color: var(--navy); text-decoration: none; white-space: nowrap;
  border-bottom: 2px solid transparent;
}
@media (min-width: 84rem) {
  .nav > ul > li > a { padding-inline: .4rem; }
}
.nav > ul > li > a:hover,
.nav > ul > li[aria-expanded="true"] > a { border-bottom-color: var(--navy); }

.mega {
  /* Anchored to the item's LEFT edge, not centred on it. Measured on the live
     two-row nav: a centred panel on the first item hung 73px off the left of
     the viewport at 1152 and 69px at 1280. */
  position: absolute; top: calc(100% + 1px); left: 0; transform: none;
  min-width: 20rem; max-width: min(28rem, 92vw); background: #fff;
  border: 1px solid var(--rule); border-radius: var(--radius);
  box-shadow: var(--shadow-md); padding: var(--s-4);
  list-style: none; margin: 0;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .16s var(--ease);
}
.nav li:hover > .mega, .nav li:focus-within > .mega {
  opacity: 1; visibility: visible; pointer-events: auto;
}
.mega a {
  display: block; padding: .5rem .6rem; border-radius: var(--radius);
  font-family: var(--font-ui); font-size: var(--fs-sm); text-decoration: none;
  color: var(--navy);
}
.mega a:hover { background: var(--grey-100); }

.burger {
  display: inline-flex; flex-direction: column; gap: 5px; justify-content: center;
  width: 44px; height: 44px; padding: 0 10px;
  background: none; border: 1px solid var(--rule); border-radius: var(--radius); cursor: pointer;
}
.burger span { display: block; height: 2px; background: var(--navy); transition: transform .2s var(--ease), opacity .2s var(--ease); }
@media (min-width: 68rem) { .burger { display: none; } }

.drawer {
  position: fixed; inset: 0 0 0 auto; width: min(88vw, 24rem);
  background: #fff; z-index: 200; padding: var(--s-5);
  transform: translateX(100%); transition: transform .28s var(--ease);
  overflow-y: auto; box-shadow: var(--shadow-md);
}
.drawer.is-open { transform: none; }
.drawer ul { list-style: none; margin: 0; padding: 0; }
.drawer > ul > li { border-bottom: 1px solid var(--rule); }
.drawer a {
  display: block; padding: .85rem .2rem;
  font-family: var(--font-ui); font-weight: 600; font-size: var(--fs-base);
  color: var(--navy); text-decoration: none;
}
.drawer ul ul a { padding-left: var(--s-4); font-weight: 500; font-size: var(--fs-sm); color: var(--grey-600); }
.drawer-close { position: absolute; top: var(--s-4); right: var(--s-4); background: none; border: 0; font-size: 1.6rem; cursor: pointer; color: var(--navy); line-height: 1; }
.scrim {
  position: fixed; inset: 0; background: rgba(24,47,87,.42); z-index: 150;
  opacity: 0; visibility: hidden; transition: opacity .22s var(--ease);
}
.scrim.is-open { opacity: 1; visibility: visible; }

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative; overflow: hidden; isolation: isolate; background: var(--bg);
  min-height: clamp(39rem, 52vw, 49rem);
}
.hero-media { position: absolute; inset: 0; z-index: -2; display: block; }
.hero-media img {
  display: block; width: 100%; height: 100%; object-fit: cover; object-position: center center;
}
.hero::before {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(255,255,255,.96) 0%, rgba(255,255,255,.82) 34%,
      rgba(255,255,255,.45) 48%, rgba(255,255,255,.08) 67%, rgba(255,255,255,.01) 100%),
    linear-gradient(180deg, rgba(238,244,252,.22), rgba(24,47,87,.08));
  pointer-events: none; z-index: -1;
}
.hero .wrap { position: relative; min-height: inherit; }
.hero-grid {
  display: flex; align-items: center;
  padding-block: clamp(2.5rem, 7vw, var(--s-9));
}
.hero-copy { width: min(55%, 46rem); }
.hero h1 { margin-bottom: var(--s-5); text-wrap: balance; }
.hero .lede { max-width: 34rem; margin-bottom: var(--s-6); }

@media (max-width: 61.99rem) {
  .hero {
    display: grid; grid-template-columns: 1fr; grid-template-rows: auto auto; min-height: 0;
  }
  .hero-media {
    position: relative; inset: auto; grid-column: 1; grid-row: 1; z-index: -2;
    width: 100%; height: 100%; aspect-ratio: auto;
  }
  .hero-media img { object-position: center bottom; }
  .hero::before {
    z-index: -1;
    background:
      linear-gradient(180deg, rgba(255,255,255,.97) 0%, rgba(255,255,255,.82) 27%,
        rgba(255,255,255,.20) 44%, rgba(255,255,255,.02) 62%, rgba(24,47,87,.03) 100%),
      linear-gradient(90deg, rgba(255,255,255,.72), rgba(255,255,255,.08));
  }
  .hero-grid {
    grid-column: 1; grid-row: 1 / 3; display: grid; align-items: stretch;
    grid-template-rows: min(calc(100vw * 3838 / 2160), 59rem) auto;
    min-height: 0; padding-block: 0;
  }
  .hero-copy { display: contents; }
  .hero-intro {
    grid-row: 1; z-index: 1; align-self: start; width: 100%;
    padding-top: clamp(2rem, 8vw, 3.5rem);
  }
  .hero h1 { font-size: clamp(1.85rem, 8.6vw, 2.75rem); }
  .hero-actions {
    grid-row: 2; width: 100%;
    padding-block: var(--s-6) var(--s-7); background: var(--bg);
  }
  .hero-actions .btn-row {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3);
  }
  .hero-actions .btn { justify-content: center; width: 100%; text-align: center; }
}

/* The first choice after the hero is structural, not a four-button toolbar. Two routes mirror
   MPPN's actual public work: listening to issues and turning them into policy positions. */
.homepage-paths { background: var(--bg); border-bottom: 1px solid var(--rule); }
.home-path-grid { display: grid; gap: var(--s-4); }
@media (min-width: 46rem) { .home-path-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.home-path-card {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center;
  gap: var(--s-4); min-height: 8.25rem; padding: var(--s-5);
  color: var(--navy); background: var(--paper); border: 1px solid var(--rule);
  border-left: 4px solid var(--navy); border-radius: var(--radius); text-decoration: none;
  transition: transform .18s var(--ease), border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.home-path-card:hover { transform: translateY(-2px); border-color: var(--tint-400); box-shadow: var(--shadow-sm); }
.home-path-card .ico { width: 2.25rem; height: 2.25rem; color: var(--navy); }
.home-path-card strong { display: block; font: 700 var(--fs-lg)/1.25 var(--font-ui); }
.home-path-card small {
  display: block; margin-top: .45rem; color: var(--grey-600);
  font: 400 var(--fs-sm)/1.5 var(--font-body);
}
.home-path-arrow { color: var(--navy); font: 700 1.5rem/1 var(--font-ui); }

.hero-stat-row {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-4); margin-top: var(--s-7);
  border-top: 1px solid var(--rule); padding-top: var(--s-5);
}
.hero-stat { min-width: 0; }
.hero-stat .n {
  font-family: var(--font-ui); font-weight: 800;
  font-size: clamp(1.6rem, 3.4vw, 2.25rem); color: var(--navy);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.hero-stat .l {
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: 600;
  color: var(--grey-500); margin-top: .4rem; line-height: 1.3; overflow-wrap: anywhere;
}

/* ==========================================================================
   The position ledger — the distinctive device.
   MPPN's product is Pandangan and Syor. They get a numbered rail, not a card.
   ========================================================================== */

.ledger { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.section--invert .ledger { border-top-color: rgba(255,255,255,.22); }

.ledger > li { border-bottom: 1px solid var(--rule); }
.section--invert .ledger > li { border-bottom-color: rgba(255,255,255,.22); }

.ledger-item {
  display: grid; gap: var(--s-3);
  grid-template-columns: 3.25rem 1fr;
  padding-block: var(--s-5);
  text-decoration: none; color: inherit;
  transition: background-color .18s var(--ease);
}
@media (min-width: 56rem) {
  .ledger-item { grid-template-columns: 4.5rem 1fr 11rem; gap: var(--s-5); align-items: start; }
}
.ledger-item:hover { background: rgba(24,47,87,.035); }
.section--invert .ledger-item:hover { background: rgba(255,255,255,.06); }

.ledger-n {
  font-family: var(--font-ui); font-weight: 800; font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums; color: var(--grey-600);   /* tint-400 was 2.59:1 on white */
  padding-top: .25rem;
}
.ledger-kind {
  display: block;
  font-family: var(--font-ui); font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--grey-500);
  margin-bottom: .5rem;
}
.section--invert .ledger-kind { color: var(--tint-300); }
.ledger-title {
  display: block;
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--fs-lg); line-height: 1.3; color: var(--navy);
  margin: 0 0 .5rem;
}
.section--invert .ledger-title { color: #fff; }
.ledger-sum { display: block; font-size: var(--fs-sm); color: var(--text-muted); margin: 0; }
.section--invert .ledger-sum { color: rgba(255,255,255,.72); }
.ledger-meta {
  font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--grey-500);
  font-variant-numeric: tabular-nums;
}
.section--invert .ledger-meta { color: var(--tint-300); }

/* ==========================================================================
   Issue cards — 4 categories, navy ramp, drawn SVG icons (never emoji)
   ========================================================================== */

.issue-grid { display: grid; gap: var(--s-4); }
@media (min-width: 40rem) { .issue-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 72rem) { .issue-grid { grid-template-columns: repeat(4, 1fr); } }

.issue-card {
  display: flex; flex-direction: column; gap: var(--s-3);
  padding: var(--s-5); background: #fff;
  border: 1px solid var(--rule); border-top: 3px solid var(--cat, var(--navy));
  border-radius: var(--radius); text-decoration: none; color: inherit;
  transition: transform .2s var(--ease), box-shadow .2s var(--ease);
}
.issue-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.issue-card .ico { width: 34px; height: 34px; color: var(--cat, var(--navy)); }
.issue-card h3 { font-size: var(--fs-lg); margin: 0; }
.issue-card p { font-size: var(--fs-sm); color: var(--text-muted); margin: 0; }
.issue-card .count {
  margin-top: auto; padding-top: var(--s-3);
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: 700;
  color: var(--grey-500); font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Consumer Pulse — data, not decoration
   ========================================================================== */

.pulse { display: grid; gap: var(--s-6); }
@media (min-width: 58rem) { .pulse { grid-template-columns: 1fr 1.15fr; gap: var(--s-8); align-items: center; } }

.pulse-bars { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-4); }
.pulse-row { display: grid; gap: .4rem; }
.pulse-label {
  display: flex; justify-content: space-between; gap: var(--s-3);
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
}
.pulse-label .pct { font-variant-numeric: tabular-nums; color: #fff; }
.pulse-track { height: 10px; background: rgba(255,255,255,.16); border-radius: 99px; overflow: hidden; }
.pulse-fill {
  height: 100%; width: 0; border-radius: 99px;
  background: linear-gradient(90deg, var(--tint-300), #fff);
  transition: width 1.1s var(--ease);
}
.pulse-note {
  font-family: var(--font-ui); font-size: var(--fs-xs);
  color: var(--tint-300); font-variant-numeric: tabular-nums;
  margin-top: var(--s-4);
}

/* ==========================================================================
   Generic cards / lists
   ========================================================================== */

.card-grid { display: grid; gap: var(--s-4); }
@media (min-width: 46rem) { .card-grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 46rem) { .card-grid--2 { grid-template-columns: repeat(2, 1fr); } }

.news-card {
  display: flex; flex-direction: column; gap: var(--s-3);
  text-decoration: none; color: inherit;
}
.news-card .ph { border-radius: var(--radius); }
.news-card .kind {
  font-family: var(--font-ui); font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--grey-600);  /* was 2.59:1 */
}
.news-card h3 { font-size: var(--fs-lg); margin: 0; }
.news-card:hover h3 { text-decoration: underline; text-underline-offset: 3px; }
.news-card time {
  font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--grey-500);
  font-variant-numeric: tabular-nums;
}

.pub-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
.pub-item {
  display: grid; grid-template-columns: 2.5rem 1fr auto; gap: var(--s-4);
  align-items: center; padding: var(--s-4);
  background: #fff; border: 1px solid var(--rule); border-radius: var(--radius);
  text-decoration: none; color: inherit;
}
.pub-item:hover { border-color: var(--navy); }
.pub-item .ico { width: 26px; height: 26px; color: var(--tint-400); }
.pub-item .t { font-family: var(--font-display); font-weight: 700; font-size: var(--fs-base); color: var(--navy); }
.pub-item .m { font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--grey-500); font-variant-numeric: tabular-nums; }
.pub-item .dl { font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: 700; color: var(--navy); white-space: nowrap; }
@media (max-width: 40rem) {
  .pub-item { grid-template-columns: 2.5rem 1fr; }
  .pub-item .dl { grid-column: 2; }
}

/* --- knowledge hub strip --------------------------------------------------- */
.hub-grid { display: grid; gap: var(--s-3); }
@media (min-width: 40rem) { .hub-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 64rem) { .hub-grid { grid-template-columns: repeat(6, 1fr); } }
.hub-tile {
  display: grid; gap: var(--s-2); place-items: center; text-align: center;
  padding: var(--s-5) var(--s-3); background: #fff;
  border: 1px solid var(--rule); border-radius: var(--radius);
  text-decoration: none; color: var(--navy);
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: 600;
  transition: border-color .18s var(--ease), transform .18s var(--ease);
}
.hub-tile:hover { border-color: var(--navy); transform: translateY(-2px); }
.hub-tile .ico { width: 28px; height: 28px; color: var(--tint-400); }

/* --- voice / newsletter ---------------------------------------------------- */
.split { display: grid; gap: var(--s-6); }
@media (min-width: 58rem) { .split { grid-template-columns: 1fr 1fr; gap: var(--s-8); align-items: center; } }

.quote-strip { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
.quote-strip li {
  padding: var(--s-4); background: rgba(255,255,255,.07);
  border-left: 3px solid var(--tint-300); border-radius: 0 var(--radius) var(--radius) 0;
  font-size: var(--fs-sm); line-height: 1.55;
}
.quote-strip .who {
  display: block; margin-top: var(--s-2);
  font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--tint-300);
}

.nl-form { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-4); }
.nl-form input[type="email"] {
  flex: 1 1 16rem; min-width: 0;
  font-family: var(--font-ui); font-size: var(--fs-sm);
  padding: .95rem 1rem; border: 1.5px solid var(--rule);
  border-radius: var(--radius); background: #fff; color: var(--ink);
}
.nl-form input[type="email"]:focus { border-color: var(--navy); }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer { background: var(--navy); color: rgba(255,255,255,.78); font-size: var(--fs-sm); }
.footer-main { padding-block: var(--s-8) var(--s-6); }
.footer-grid { display: grid; gap: var(--s-6); }
@media (min-width: 46rem) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (min-width: 72rem) { .footer-grid { grid-template-columns: 1.6fr 1fr 1fr 1.2fr; } }

.site-footer img.f-logo { height: 60px; width: auto; margin-bottom: var(--s-4); }
.site-footer h4 {
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: #fff;
  margin: 0 0 var(--s-3);
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.site-footer a { color: rgba(255,255,255,.78); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.site-footer address { font-style: normal; line-height: 1.6; }

.footer-bottom {
  border-top: 1px solid rgba(255,255,255,.18);
  padding-block: var(--s-4);
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5);
  align-items: center; justify-content: space-between;
  font-family: var(--font-ui); font-size: var(--fs-xs);
  color: rgba(255,255,255,.6);
}
.footer-bottom nav { display: flex; flex-wrap: wrap; gap: var(--s-4); }

/* ==========================================================================
   Motion — fadeInUp reveals with stagger
   ========================================================================== */

/* Scoped under .js — set by the inline script in head.php. Without JS, or if
   IntersectionObserver never fires, every .reveal stays VISIBLE. An animation
   that fails must not be able to erase the page. */
.js .reveal { opacity: 0; transform: translateY(18px); }
.js .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay: var(--d, 0ms);
}
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; }
}

/* ==========================================================================
   Inner pages
   ========================================================================== */

.page-hero { background: var(--navy); color: rgba(255,255,255,.85); }
.page-hero .wrap { padding-block: clamp(2.5rem, 6vw, var(--s-8)); }
.page-hero h1 { color: #fff; margin-bottom: var(--s-3); }
.page-hero .lede { color: rgba(255,255,255,.8); max-width: 46rem; }
.page-hero .eyebrow { color: var(--tint-300); }

.crumbs {
  font-family: var(--font-ui); font-size: var(--fs-xs);
  color: rgba(255,255,255,.62); margin-bottom: var(--s-4);
}
.crumbs a { color: rgba(255,255,255,.62); text-decoration: none; }
.crumbs a:hover { color: #fff; text-decoration: underline; }
.crumbs span { padding-inline: .4rem; }

/* --- two-column article layout with a sticky in-page nav ------------------ */
.doc { display: grid; gap: var(--s-6); }
@media (min-width: 62rem) { .doc { grid-template-columns: 15rem 1fr; gap: var(--s-8); } }

.doc-nav { align-self: start; }
@media (min-width: 62rem) { .doc-nav { position: sticky; top: 7.5rem; } }
.doc-nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.doc-nav a {
  display: block; padding: .5rem .75rem; border-left: 2px solid var(--rule);
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: 600;
  color: var(--grey-600); text-decoration: none;
}
.doc-nav a:hover { border-left-color: var(--navy); color: var(--navy); background: var(--grey-100); }

.doc-body > section { padding-bottom: var(--s-6); margin-bottom: var(--s-6); border-bottom: 1px solid var(--rule); }
.doc-body > section:last-child { border-bottom: 0; margin-bottom: 0; }
.doc-body h2 { font-size: var(--fs-2xl); }
.doc-body ul, .doc-body ol { padding-left: 1.25rem; }
.doc-body li { margin-bottom: .5rem; }
.doc-body blockquote {
  margin: var(--s-5) 0; padding: var(--s-4) var(--s-5);
  border-left: 3px solid var(--navy); background: var(--grey-100);
  font-size: var(--fs-sm);
}
.doc-body blockquote cite {
  display: block; margin-top: var(--s-2); font-style: normal;
  font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--grey-600);
}

/* --- filters -------------------------------------------------------------- */
.filters {
  display: flex; flex-wrap: wrap; gap: var(--s-2);
  padding-bottom: var(--s-5); margin-bottom: var(--s-5);
  border-bottom: 1px solid var(--rule);
}
.chip {
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: 600;
  padding: .55rem .9rem; border: 1px solid var(--rule); border-radius: 99px;
  background: #fff; color: var(--grey-600); text-decoration: none; cursor: pointer;
}
.chip:hover { border-color: var(--navy); color: var(--navy); }
.chip[aria-current="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }

.searchbar { display: flex; gap: var(--s-2); margin-left: auto; }
.searchbar input {
  font-family: var(--font-ui); font-size: var(--fs-xs);
  padding: .55rem .8rem; border: 1px solid var(--rule); border-radius: var(--radius);
  min-width: 12rem;
}
.searchbar input:focus { border-color: var(--navy); }

/* --- member grid ---------------------------------------------------------- */
.member-grid { display: grid; gap: var(--s-5); }
@media (min-width: 40rem) { .member-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .member-grid { grid-template-columns: repeat(4, 1fr); } }

.member { display: grid; gap: var(--s-3); }
.member .ph { aspect-ratio: 3 / 4; min-height: 0; }
.member .nm { font-family: var(--font-display); font-weight: 600; color: var(--navy); font-size: var(--fs-base); }
.member .rl { font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--grey-600); }
.member .fx { font-size: var(--fs-xs); color: var(--grey-600); }

.chair {
  display: grid; gap: var(--s-5); align-items: center;
  padding: var(--s-6); background: var(--grey-100); border-radius: var(--radius);
  margin-bottom: var(--s-7);
}
@media (min-width: 52rem) { .chair { grid-template-columns: 16rem 1fr; gap: var(--s-7); } }
.chair .ph { aspect-ratio: 3 / 4; min-height: 0; }

/* --- forms ---------------------------------------------------------------- */
.form { display: grid; gap: var(--s-4); max-width: 40rem; }
.field { display: grid; gap: .4rem; }
.field label {
  font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: 700; color: var(--navy);
}
.field .hint { font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--grey-600); }
.field input, .field select, .field textarea {
  font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--ink);
  padding: .8rem .9rem; border: 1.5px solid var(--rule); border-radius: var(--radius);
  background: #fff; width: 100%;
}
.field textarea { min-height: 9rem; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--navy); outline: none; }
.consent { display: flex; gap: var(--s-3); align-items: flex-start; font-size: var(--fs-sm); }
.consent input { width: 1.15rem; height: 1.15rem; margin-top: .2rem; flex: 0 0 auto; }
.form-note { font-size: var(--fs-xs); color: var(--grey-600); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.alert {
  padding: var(--s-4) var(--s-5); border-radius: var(--radius);
  border-left: 3px solid var(--navy); background: var(--grey-100);
  font-size: var(--fs-sm); margin-bottom: var(--s-5);
}
.alert--ok { border-left-color: #1d7a4d; }
.alert--err { border-left-color: #b3261e; }

/* --- accordion (FAQ) ------------------------------------------------------ */
.acc { border-top: 1px solid var(--rule); }
.acc details { border-bottom: 1px solid var(--rule); }
.acc summary {
  cursor: pointer; list-style: none; padding: var(--s-4) 0;
  font-family: var(--font-display); font-weight: 600; font-size: var(--fs-lg);
  color: var(--navy); display: flex; justify-content: space-between; gap: var(--s-4);
}
.acc summary::-webkit-details-marker { display: none; }
.acc summary::after { content: "+"; font-weight: 400; color: var(--grey-500); }
.acc details[open] summary::after { content: "\2212"; }
.acc .acc-body { padding-bottom: var(--s-4); font-size: var(--fs-sm); color: var(--text-muted); }

/* --- empty state ---------------------------------------------------------- */
.empty {
  padding: var(--s-7) var(--s-5); text-align: center;
  border: 1px dashed var(--rule); border-radius: var(--radius);
  color: var(--grey-600); font-size: var(--fs-sm);
}

/* --- contact / map -------------------------------------------------------- */
.contact-grid { display: grid; gap: var(--s-6); }
@media (min-width: 58rem) { .contact-grid { grid-template-columns: 1fr 1.1fr; gap: var(--s-8); } }
.office { padding: var(--s-5); border: 1px solid var(--rule); border-radius: var(--radius); }
.office + .office { margin-top: var(--s-4); }
.office h3 { font-size: var(--fs-lg); margin-bottom: var(--s-3); }
.office address { font-style: normal; font-size: var(--fs-sm); line-height: 1.7; }
.map-frame { border: 0; width: 100%; aspect-ratio: 4 / 3; border-radius: var(--radius); }

/* --- sitemap page --------------------------------------------------------- */
.sitemap-cols { display: grid; gap: var(--s-6); }
@media (min-width: 46rem) { .sitemap-cols { grid-template-columns: repeat(3, 1fr); } }
.sitemap-cols h2 { font-size: var(--fs-lg); }
.sitemap-cols ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.sitemap-cols a { font-family: var(--font-ui); font-size: var(--fs-sm); text-decoration: none; }
.sitemap-cols a:hover { text-decoration: underline; }

/* --- real photography ------------------------------------------------------
   Distinct from .ph, which is the labelled placeholder. A .shot is an actual
   photograph and carries the site's single tonal treatment so the set reads
   as one system rather than four unrelated frames. */
.shot { display: block; margin: 0; overflow: hidden; border-radius: var(--radius); background: var(--grey-100); }
.shot img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%;
            filter: saturate(.88) contrast(1.04); }
/* the council frame's subjects sit below centre */
.shot--tall img { object-position: 50% 62%; }
/* Was 4/5 then 3/4. Cropping a 16:9 frame to 3:4 discards ~44% of its width,
   and on the council photo the people sit low-centre, so the visible band was
   ceiling. 5/4 keeps the subject and still gives the hero vertical presence. */
.shot--tall { aspect-ratio: 4 / 3; }
@media (min-width: 62rem) { .shot--tall { aspect-ratio: 5 / 4; } }
.shot--wide { aspect-ratio: 16 / 9; }
.shot--band { aspect-ratio: 21 / 8; margin-top: var(--s-6); }
@media (max-width: 46rem) { .shot--band { aspect-ratio: 16 / 9; } }

/* ==========================================================================
   Mobile tap targets
   The overflow probe said 0 at 390 while the audit found 18-47 links per page
   under 32px tall. Nothing was overflowing; the links were simply too small to
   hit. A gutter that measures correctly and a target you cannot press are
   different failures, and only one of them was being checked.
   ========================================================================== */
@media (max-width: 62rem) {
  .site-footer ul { gap: 0; }
  .site-footer ul a,
  .sitemap-cols a,
  .footer-bottom nav a {
    display: block;
    min-height: 44px;
    display: flex; align-items: center;
  }
  .site-footer ul a { border-bottom: 1px solid rgba(255,255,255,.10); }
  .site-footer ul li:last-child a { border-bottom: 0; }
  .sitemap-cols ul { gap: 0; }
  .sitemap-cols a { border-bottom: 1px solid var(--rule); }
  .crumbs a { display: inline-flex; align-items: center; min-height: 32px; }
  .link-more { min-height: 44px; align-items: center; }
  .chip { min-height: 40px; display: inline-flex; align-items: center; }
  .drawer a { min-height: 48px; display: flex; align-items: center; }
  .drawer ul ul a { min-height: 42px; }
  .pub-item .dl { display: inline-flex; align-items: center; min-height: 40px; }
  .header-top a, .cms-who a { display: inline-flex; align-items: center; min-height: 40px; }
}

/* The honeypot used the same left:-9999px trick the skip link did, which the
   audit reports as a 177px box clipped into 1px. Same clip-path fix. */
.hp {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; left: auto;
}

/* ==========================================================================
   Image treatment derived from the CI
   The identity manual defines the lengkungan as "perisai perlindungan" — a
   protective shield — and the app icon as a soft-cornered square. Both are the
   client's own geometry, so the imagery can carry them instead of sitting in
   plain rectangles. Nothing here is invented decoration.
   ========================================================================== */

.shot--arc {
  position: relative;
  /* the crescent's sweep: one deep corner, one tight, on the diagonal */
  border-radius: 42% 8px 42% 8px / 30% 8px 30% 8px;
  overflow: hidden;
}
@media (min-width: 62rem) { .shot--arc { border-radius: 46% 10px 46% 10px / 32% 10px 32% 10px; } }

/* the orbit, redrawn as a ring behind the frame */
.shot-orbit { position: relative; }
/* No negative margin: it pulled the box 2% past the grid cell and left a 7px
   horizontal overflow on the homepage at every mobile width. The ring is inset
   instead, which costs nothing visually. */
.shot-orbit { padding: 4% 2% 2%; }
.shot-orbit::before {
  /* was inset -5%/-8%, which pushed the ring past the container and produced a
     real 18px horizontal overflow on the homepage at every mobile width. The
     ring now sits inside padding the container gives it. */
  content: ""; position: absolute; z-index: 0;
  inset: 0;
  border: 1.5px solid var(--tint-400);
  border-radius: 46% 10px 46% 10px / 32% 10px 32% 10px;
  opacity: .55; pointer-events: none;
}
.shot-orbit > .shot { position: relative; z-index: 1; }

/* a navy veil so a photograph sits in the palette rather than beside it */
.shot--veil::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(200deg, rgba(24,47,87,0) 45%, rgba(24,47,87,.34) 100%);
}
.shot--band { border-radius: var(--radius-lg) var(--radius-lg) 42px var(--radius-lg); }

@media (max-width: 62rem) {
  /* tel: and mailto: inside <address> are inline, so min-height never applied
     to them. They are the two links a person on a phone is most likely to
     actually press. */
  .site-footer address a,
  .office address a {
    display: inline-flex; align-items: center;
    min-height: 44px; padding-block: .25rem;
  }
}

/* The hero sub-line. Was .lede at 20px carrying a 26-word sentence that tried
   to be four things at once — storyboard §3 lists those four as their own
   block, so the head section only needs one quiet line. */
.hero-sub {
  font-family: var(--font-ui);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--grey-600);
  max-width: 30rem;
  margin: 0 0 var(--s-6);
}

/* Storyboard §3 "Penerangan MPPN Secara Ringkas" — siapa, peranan, fungsi,
   kepentingan as four labelled lines. Structure instead of prose, which is
   also what §21 means by data-driven and clean. */
.section--tight { padding-block: clamp(2rem, 5vw, var(--s-7)); }
.brief {
  display: grid; gap: 0; margin: 0;
  border-top: 1px solid var(--rule);
}
@media (min-width: 52rem) { .brief { grid-template-columns: repeat(2, 1fr); column-gap: var(--s-7); } }
@media (min-width: 76rem) { .brief { grid-template-columns: repeat(4, 1fr); } }

.brief-item { padding-block: var(--s-4); border-bottom: 1px solid var(--rule); }
@media (min-width: 76rem) { .brief-item { border-bottom: 0; border-top: 2px solid var(--navy); margin-top: -1px; } }
.brief-item dt {
  font-family: var(--font-ui); font-size: var(--fs-micro); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--grey-500);
  margin-bottom: .35rem;
}
.brief-item dd { margin: 0; font-size: var(--fs-sm); line-height: 1.55; color: var(--text); }

/* The last two items sit at the right edge of the row, so their panels open
   leftwards instead of running past the container. */
.nav > ul > li:nth-last-child(1) > .mega,
.nav > ul > li:nth-last-child(2) > .mega { left: auto; right: 0; }

/* At 320 the header row measured 287px inside a 280px container: a 46px lockup
   is ~138px wide at 3:1, plus a 76px language toggle, a 44px burger and two
   gaps. Seven pixels over. Shrink the lockup and tighten the gaps on the
   narrowest phones only. */
@media (max-width: 22.5rem) {
  .brand img { height: 38px; }
  .header-bar { gap: var(--s-2); }
  .header-tools { gap: var(--s-2); }
  .lang-toggle button { padding: .45rem .45rem; }
}
