/* ============================================================
   Pesantren UMI — "UMI Connection", pendekatan dunia pesantren
   ------------------------------------------------------------
   Tokens are inherited from the UMI Connection design system
   (baa.umi.ac.id / baa-connection) so this site reads as a sibling
   of the other UMI properties: green base, gold secondary, and the
   teal "connection" accent that carries the digital-ecosystem layer.

   On top of that sits the pesantren layer:
     · khatam sulaimani  — the eight-point star lattice
     · mihrab            — the ogee arch framing headings and media
     · jalinan           — a connecting thread, UMI Connection made visible
     · kertas kitab      — warm parchment for long-form reading
   ============================================================ */

/* ---------- Tokens ---------- */
:root {
  /* UMI institutional palette — green base, gold secondary. */
  --brand-900: #032a1c;
  --brand-800: #054730;
  --brand-700: #0a6b45;
  --brand-600: #0b7d4f;
  --brand-500: #14a86c;
  --brand-100: #dcf2e6;
  --brand-50:  #f0faf5;

  --gold-700: #6d4a03;
  --gold-600: #8f6104;
  --gold-500: #f2a81d;
  --gold-400: #ffc44d;
  --gold-100: #fff4dc;

  /* The "Connection" accent: a teal that bridges the green base. */
  --accent-600: #087a6d;
  --accent-500: #11b39d;
  --accent-100: #dcf5f1;

  --ink-900: #0c1f17;
  --ink-700: #1e3329;
  --ink-600: #3c5449;
  --ink-400: #5c766a;
  --ink-300: #96aaa0;

  --line: #dce8e2;
  --line-soft: #edf4f0;

  --bg: #ffffff;
  --bg-soft: #f4faf7;
  --bg-muted: #e8f2ed;

  /* Warm parchment for long-form reading — the "kitab" surface. */
  --paper: #fdfbf4;
  --paper-line: #ece3cf;

  --danger: #c62828;
  --warn: #e08a00;
  --ok: #1b8a4b;

  /* --------------------------------------------------------------
     Theme-aware pairs.
     Defined once per theme so a component never needs its own dark
     override — the earlier approach used `[data-theme="dark"]` rules
     that silently missed system-dark users and failed contrast.
     -------------------------------------------------------------- */
  --brand-ink: #0a6b45;      /* brand green, readable on the page ground */
  --accent-ink: #087a6d;     /* connection teal, readable on the ground  */

  --badge-bg: #dcf2e6;       --badge-fg: #054730;
  --badge-accent-bg: #fff4dc; --badge-accent-fg: #6d4a03;
  --badge-teal-bg: #dcf5f1;  --badge-teal-fg: #087a6d;

  --niche-bg: linear-gradient(160deg, #dcf2e6, #f0faf5);
  --wave-current-bg: linear-gradient(180deg, #fff4dc, #ffffff 55%);

  --ayat-fg: #054730;
  --ayat-bg: linear-gradient(160deg, #fff4dc, #fdfbf4);
  --ayat-inner: rgba(255, 255, 255, .6);

  --alert-success-bg: #f0faf5; --alert-success-fg: #054730;
  --alert-error-bg: #fdecec;   --alert-error-fg: #7d1a15;
  --alert-warning-bg: #fff4dc; --alert-warning-fg: #6d4a03;
  --alert-info-bg: #dcf5f1;    --alert-info-fg: #087a6d;

  /* Semantic aliases used throughout the sheet. */
  --surface: var(--bg);
  --surface-2: var(--bg-soft);
  --surface-3: var(--brand-50);
  --border: var(--line);
  --text: var(--ink-900);
  --text-muted: var(--ink-400);
  --brand: var(--brand-700);
  --brand-strong: var(--brand-800);
  --brand-soft: var(--brand-100);
  --accent: var(--gold-500);

  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 20px;
  --radius-full: 999px;

  --shadow-1: 0 1px 2px rgba(6, 42, 28, .06), 0 2px 8px rgba(6, 42, 28, .05);
  --shadow-2: 0 6px 22px rgba(6, 42, 28, .10);
  --shadow-3: 0 18px 48px rgba(6, 42, 28, .18);

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --font-arabic: "Noto Naskh Arabic", "Amiri", "Traditional Arabic", "Segoe UI Historic", serif;

  --step--1: clamp(.8rem, .77rem + .15vw, .875rem);
  --step-0: clamp(.95rem, .92rem + .18vw, 1.0625rem);
  --step-1: clamp(1.12rem, 1.05rem + .35vw, 1.35rem);
  --step-2: clamp(1.35rem, 1.2rem + .7vw, 1.8rem);
  --step-3: clamp(1.6rem, 1.35rem + 1.2vw, 2.4rem);
  --step-4: clamp(2rem, 1.5rem + 2.2vw, 3.4rem);

  --wrap: 1240px;
  --wrap-narrow: 760px;
  --gap: clamp(1rem, .7rem + 1.2vw, 1.75rem);
  --section-y: clamp(3rem, 2.2rem + 3.6vw, 6rem);

  --header-h: 76px;
  --ease: cubic-bezier(.4, 0, .2, 1);

  /* Khatam sulaimani: two squares, one rotated 45°, tiled into a lattice. */
  --pattern-khatam: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 80 80'%3E%3Cg fill='none' stroke='%23f2a81d' stroke-width='1'%3E%3Crect x='20' y='20' width='40' height='40'/%3E%3Crect x='20' y='20' width='40' height='40' transform='rotate(45 40 40)'/%3E%3C/g%3E%3C/svg%3E");

  color-scheme: light;
}

/* Dark theme — the pesantren at night: deeper ground, warmer gold.
   Opt-in only: light is the ground state for every first visit, even on a
   device set to system-dark. Dark arrives when the visitor asks for it via
   the header toggle, which writes `data-theme` and remembers the choice. */
:root[data-theme="dark"] {
  --bg: #071510;
  --bg-soft: #0c2018;
  --bg-muted: #122c21;
  --paper: #0e1f18;
  --paper-line: #24382c;
  --line: #1e3629;
  --line-soft: #16281f;
  --ink-900: #e8f0ec;
  --ink-700: #cfdcd6;
  --ink-600: #a8bcb2;
  --ink-400: #91a89d;
  --ink-300: #6d8378;
  --brand: var(--brand-500);
  --brand-strong: #3fd08d;
  --brand-soft: #0f3324;
  --accent: var(--gold-400);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-2: 0 6px 22px rgba(0, 0, 0, .45);
  --shadow-3: 0 18px 48px rgba(0, 0, 0, .55);
  --brand-ink: #14a86c;
  --accent-ink: #11b39d;
  --badge-bg: #0f3324;        --badge-fg: #14a86c;
  --badge-accent-bg: #33280a; --badge-accent-fg: #ffc44d;
  --badge-teal-bg: #06302b;   --badge-teal-fg: #11b39d;
  --niche-bg: #0f3324;
  --wave-current-bg: linear-gradient(180deg, #2a2109, #071510 55%);
  --ayat-fg: #ffc44d;
  --ayat-bg: linear-gradient(160deg, #1b1606, #0e1f18);
  --ayat-inner: rgba(0, 0, 0, .3);
  --alert-success-bg: #0f2d1d; --alert-success-fg: #8fe0b3;
  --alert-error-bg: #351110;   --alert-error-fg: #f3a9a3;
  --alert-warning-bg: #2a2109; --alert-warning-fg: #ffc44d;
  --alert-info-bg: #062c27;    --alert-info-fg: #11b39d;
  color-scheme: dark;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 20px);
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.7;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, picture, svg, video { max-width: 100%; height: auto; display: block; }
img { background-color: var(--bg-muted); }

h1, h2, h3, h4 {
  margin: 0 0 .5em;
  font-family: var(--font-display);
  line-height: 1.18;
  font-weight: 600;
  letter-spacing: -.012em;
  text-wrap: balance;
  color: var(--ink-900);
}

h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }
h5, h6 { margin: 0 0 .5em; font-weight: 700; }

p { margin: 0 0 1.1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: var(--brand); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--brand-strong); }

ul, ol { padding-inline-start: 1.4em; }
button, input, select, textarea { font: inherit; color: inherit; }
hr { border: 0; border-top: 1px solid var(--border); margin: 2rem 0; }

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

::selection { background: var(--gold-100); color: var(--ink-900); }
:root[data-theme="dark"] ::selection { background: var(--brand-soft); color: var(--ink-900); }

/* Arabic gets its own face and a looser line. */
:root[lang="ar"] body, body.locale-ar { font-family: var(--font-arabic); line-height: 2; }
[dir="rtl"] { text-align: right; }

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

/* ---------- Utilities ---------- */
.wrap { width: min(100% - 2.5rem, var(--wrap)); margin-inline: auto; }
.wrap-narrow { width: min(100% - 2.5rem, var(--wrap-narrow)); margin-inline: auto; }
.section { padding-block: var(--section-y); }
.stack > * + * { margin-top: var(--gap); }
.center { text-align: center; }
.muted { color: var(--text-muted); }
.small { font-size: var(--step--1); }

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

.skip-link {
  position: absolute;
  inset-inline-start: 1rem;
  top: -100px;
  z-index: 999;
  padding: .75rem 1.25rem;
  background: var(--brand-800);
  color: #fff;
  border-radius: 0 0 var(--radius) var(--radius);
  font-weight: 600;
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 0; color: #fff; }

/* ---------- Ornaments ---------- */

/* Gold rule with a centred eight-point star — the section divider. */
.ornament {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .85rem;
  margin: 0 0 1.1rem;
  color: var(--gold-500);
}
.ornament::before, .ornament::after {
  content: "";
  height: 1px;
  flex: 0 1 90px;
  background: linear-gradient(90deg, transparent, currentColor);
}
.ornament::after { background: linear-gradient(270deg, transparent, currentColor); }
.ornament .khatam { width: 13px; height: 13px; flex: 0 0 auto; }

/* The eight-point star itself, reusable at any size. */
.khatam {
  display: inline-block;
  background: currentColor;
  clip-path: polygon(50% 0, 61% 24%, 85% 15%, 76% 39%, 100% 50%, 76% 61%, 85% 85%, 61% 76%, 50% 100%, 39% 76%, 15% 85%, 24% 61%, 0 50%, 24% 39%, 15% 15%, 39% 24%);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .78rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  font-weight: 600;
  font-size: var(--step--1);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .18s var(--ease), border-color .18s var(--ease),
              transform .18s var(--ease), box-shadow .18s var(--ease), color .18s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn-primary {
  background: linear-gradient(135deg, var(--brand-700), var(--brand-600));
  color: #fff;
  box-shadow: var(--shadow-1);
}
.btn-primary:hover {
  background: linear-gradient(135deg, var(--brand-800), var(--brand-700));
  color: #fff;
  box-shadow: var(--shadow-2);
}

.btn-ghost { background: transparent; color: var(--text); border-color: var(--border); }
.btn-ghost:hover { background: var(--bg-soft); color: var(--brand); border-color: var(--brand); }

/* Gold call to action, for the one action that matters most on a screen. */
.btn-accent {
  background: linear-gradient(135deg, var(--gold-500), var(--gold-400));
  color: #4a3202;
  box-shadow: 0 2px 10px rgba(242, 168, 29, .3);
}
.btn-accent:hover { background: linear-gradient(135deg, var(--gold-600), var(--gold-500)); color: #fff; }

.btn-sm { padding: .45rem .95rem; font-size: .8rem; }
.btn-lg { padding: .95rem 2rem; font-size: var(--step-0); }
.btn-block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .55; pointer-events: none; }

/* On dark grounds (hero, footer) the ghost button needs its own colours. */
.on-dark .btn-ghost { color: #eaf5ef; border-color: rgba(255, 255, 255, .34); }
.on-dark .btn-ghost:hover { background: rgba(255, 255, 255, .12); color: #fff; border-color: rgba(255, 255, 255, .6); }

/* ---------- Badges ---------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .26rem .8rem;
  border-radius: var(--radius-full);
  background: var(--badge-bg);
  color: var(--badge-fg);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .02em;
}
.badge-accent { background: var(--badge-accent-bg); color: var(--badge-accent-fg); }
.badge-teal { background: var(--badge-teal-bg); color: var(--badge-teal-fg); }
.badge-outline { background: transparent; border: 1px solid var(--border); color: var(--text-muted); font-weight: 600; }


/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: saturate(1.7) blur(14px);
  border-bottom: 1px solid var(--border);
}
/* A hairline of gold under the header — small, but unmistakably UMI. */
.site-header::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: -2px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold-500) 22%, var(--accent-500) 50%, var(--gold-500) 78%, transparent);
  opacity: .75;
}

.header-inner { display: flex; align-items: center; gap: 1rem; min-height: var(--header-h); }

.brand { display: flex; align-items: center; gap: .75rem; text-decoration: none; color: var(--text); flex: 0 0 auto; }
.brand img, .brand svg { width: 46px; height: 46px; flex: 0 0 auto; object-fit: contain; background: none; }
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-name { font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; letter-spacing: -.015em; }
.brand-sub { font-size: .64rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .11em; font-weight: 600; }

.primary-nav { margin-inline-start: auto; }
.primary-nav .menu { display: flex; align-items: center; gap: .1rem; list-style: none; margin: 0; padding: 0; }
.primary-nav .menu-item { position: relative; }
.primary-nav .menu-item > a {
  display: block;
  padding: .55rem .8rem;
  border-radius: var(--radius-sm);
  font-size: .9rem;
  font-weight: 550;
  color: var(--ink-700);
  text-decoration: none;
  white-space: nowrap;
  transition: color .16s var(--ease), background-color .16s var(--ease);
}
.primary-nav .menu-item > a:hover { background: var(--bg-soft); color: var(--brand); }

/* Active item marked with a gold underline rather than a colour swap. */
.primary-nav .current-menu-item > a { color: var(--brand); font-weight: 700; }
.primary-nav .current-menu-item > a::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 4px;
  border-radius: 2px;
  background: var(--gold-500);
}

.primary-nav .sub-menu {
  position: absolute;
  top: calc(100% + 10px);
  inset-inline-start: 0;
  min-width: 236px;
  list-style: none;
  margin: 0;
  padding: .45rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-top: 2px solid var(--gold-500);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility .18s;
}
.primary-nav .menu-item:hover > .sub-menu,
.primary-nav .menu-item:focus-within > .sub-menu { opacity: 1; visibility: visible; transform: translateY(0); }
.primary-nav .sub-menu a {
  display: block;
  padding: .55rem .8rem;
  border-radius: var(--radius-sm);
  font-size: .875rem;
  text-decoration: none;
  color: var(--ink-700);
}
.primary-nav .sub-menu a:hover { background: var(--badge-bg); color: var(--badge-fg); }
.submenu-toggle { display: none; }

.header-actions { display: flex; align-items: center; gap: .4rem; }

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 40px; height: 40px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  background: var(--bg);
  cursor: pointer;
  color: var(--ink-700);
  transition: background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.icon-btn:hover { background: var(--bg-soft); border-color: var(--brand); color: var(--brand); }

/* Language switcher */
.lang-switch { position: relative; }
.lang-switch-menu {
  position: absolute;
  top: calc(100% + 10px);
  inset-inline-end: 0;
  min-width: 200px;
  padding: .4rem;
  margin: 0;
  list-style: none;
  background: var(--bg);
  border: 1px solid var(--border);
  border-top: 2px solid var(--gold-500);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  z-index: 10;
}
.lang-switch-menu[hidden] { display: none; }
.lang-switch-menu a {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .75rem;
  border-radius: var(--radius-sm);
  font-size: .875rem;
  text-decoration: none;
  color: var(--ink-700);
}
.lang-switch-menu a:hover { background: var(--brand-100); color: var(--brand-800); }
.lang-switch-menu a[aria-current="true"] { font-weight: 700; color: var(--brand); }
.lang-flag { font-size: 1.05rem; line-height: 1; }

.nav-toggle { display: none; }

/* The drawer and the button that opens it must share one breakpoint. They did
   not: the button appeared at 1040px but the off-canvas rules lived in the
   560px block below, so from 561px to 1040px — every tablet, and a large
   phone held sideways — the button was visible while `.is-open` had nothing
   to act on and the panel stayed parked off-screen. */
@media (max-width: 1040px) {
  .nav-toggle { display: inline-grid; }

  /* The brand was flex:0 0 auto, so it kept its full 252px on every screen
     and pushed the header actions past the edge. On a 390px phone the menu
     button ended up entirely outside the viewport — the site menu could not
     be opened at all — and at 360px the theme toggle went with it. The brand
     now yields space and truncates instead. */
  .brand { flex: 1 1 auto; min-width: 0; }
  .brand-text { min-width: 0; }
  .brand-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .header-actions { flex: 0 0 auto; }

  .primary-nav {
    position: fixed;
    top: var(--header-h);
    inset-inline: 0;
    /* `inset: var(--header-h) 0 0 0` alone left the panel 40px tall: the auto
       height never resolved against `bottom`, so the drawer slid in as a
       sliver with all sixteen links scrolled out of reach. Sizing it outright
       is what actually fills the screen. dvh follows the mobile URL bar. */
    height: calc(100vh - var(--header-h));
    height: calc(100dvh - var(--header-h));
    background: var(--bg);
    padding: 1.25rem;
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(100%);
    /* Parked off-screen but still `visible`, the closed drawer kept all
       sixteen of its links in the tab order and in the accessibility tree —
       a keyboard or screen-reader user walked an invisible menu before
       reaching the page. visibility:hidden removes it from both. The delay
       holds it visible until the slide-out has finished playing. */
    visibility: hidden;
    transition: transform .26s var(--ease), visibility 0s linear .26s;
    margin-inline-start: 0;
    z-index: 99;
  }
  [dir="rtl"] .primary-nav { transform: translateX(-100%); }
  .primary-nav.is-open {
    transform: translateX(0);
    visibility: visible;
    transition: transform .26s var(--ease), visibility 0s;
  }
  .primary-nav .menu { flex-direction: column; align-items: stretch; gap: .1rem; }
  .primary-nav .menu-item > a { padding: .85rem .6rem; font-size: 1rem; border-bottom: 1px solid var(--line-soft); border-radius: 0; }
  .primary-nav .current-menu-item > a::after { display: none; }
  /* `visibility: visible` here re-asserted itself over the closed drawer's
     hidden state, putting eight sub-menu links back into the tab order.
     `inherit` follows the drawer, and a collapsed accordion stays hidden
     until it is actually expanded. */
  .primary-nav .sub-menu {
    position: static; opacity: 1; visibility: hidden; transform: none;
    box-shadow: none; border: 0; border-inline-start: 2px solid var(--gold-500);
    border-radius: 0; margin-inline-start: .6rem; padding-block: 0;
    max-height: 0; overflow: hidden; transition: max-height .24s var(--ease);
  }
  .primary-nav .menu-item.is-expanded > .sub-menu { max-height: 760px; visibility: inherit; }
  .submenu-toggle {
    display: grid; place-items: center;
    position: absolute; inset-inline-end: 0; top: .5rem;
    width: 42px; height: 42px;
    background: none; border: 0; cursor: pointer; color: var(--text-muted);
  }
  .primary-nav .menu-item.is-expanded > .submenu-toggle { transform: rotate(180deg); }
}

/* On a phone four 40px buttons plus the strapline left only ~97px for the
   site name, which truncated to "Pesantren U…". Dropping the strapline and
   trimming the buttons buys back enough for the name to sit whole. */
@media (max-width: 560px) {
  .site-header .brand-sub { display: none; }
  .brand { gap: .55rem; }
  .header-actions { gap: .25rem; }
  .header-actions .icon-btn { width: 36px; height: 36px; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  isolation: isolate;
  padding-block: clamp(3.25rem, 2rem + 7vw, 7.5rem);
  background:
    radial-gradient(1100px 520px at 78% -10%, rgba(17, 179, 157, .22), transparent 62%),
    linear-gradient(155deg, var(--brand-900) 0%, var(--brand-800) 48%, var(--brand-700) 100%);
  color: #eaf5ef;
  overflow: hidden;
}

/* The khatam lattice, laid over the green ground and faded out downward. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--pattern-khatam);
  background-size: 92px 92px;
  opacity: .13;
  mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, .35) 62%, transparent 100%);
}

/* A gold arch rising behind the content — the mihrab. */
.hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset-block-start: 8%;
  inset-inline-end: -6%;
  width: min(560px, 46%);
  aspect-ratio: 3 / 4;
  border: 1px solid rgba(242, 168, 29, .32);
  border-radius: 50% 50% 12px 12px / 62% 62% 8px 8px;
  pointer-events: none;
}

.hero h1 { color: #fff; margin-bottom: .4em; }
.hero-grid { position: relative; display: grid; gap: clamp(2rem, 1rem + 4vw, 3.5rem); align-items: center; }
@media (min-width: 940px) { .hero-grid { grid-template-columns: 1.05fr .95fr; } }

/* Also used on light page headers, so the dark treatment is scoped. */
.hero-lede { font-size: var(--step-1); color: var(--text-muted); max-width: 56ch; }
.on-dark .hero-lede { color: rgba(234, 245, 239, .82); }
.hero-actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2rem; }

/* Anything on the green ground needs light-on-dark values: the muted grey
   used elsewhere all but disappears against the hero. */
.on-dark, .on-dark p, .on-dark li { color: rgba(234, 245, 239, .88); }
.on-dark .muted, .on-dark .small.muted { color: rgba(234, 245, 239, .68); }
.on-dark strong { color: #fff; }
.on-dark h1, .on-dark h2, .on-dark h3, .on-dark h4 { color: #fff; }

/* Breadcrumbs and body copy sitting on the green hero. */
.on-dark .breadcrumbs ol { color: rgba(234, 245, 239, .7); }
.on-dark .breadcrumbs a { color: rgba(234, 245, 239, .78); }
.on-dark .breadcrumbs a:hover { color: var(--gold-400); }
.on-dark .breadcrumbs li + li::before { color: var(--gold-500); }
.on-dark .breadcrumbs [aria-current="page"] { color: #fff; }

.hero-eyebrow {
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .4rem 1rem .4rem .8rem;
  margin-bottom: 1.2rem;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(242, 168, 29, .42);
  backdrop-filter: blur(6px);
  font-size: .74rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--gold-400);
}
.pulse-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent-500);
  box-shadow: 0 0 0 0 rgba(17, 179, 157, .7);
  animation: pulse 2.4s infinite;
}
@keyframes pulse {
  70% { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Countdown panel — framed like a mihrab niche. */
.hero-panel {
  position: relative;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .16);
  border-top: 2px solid var(--gold-500);
  border-radius: 26px 26px var(--radius-lg) var(--radius-lg);
  box-shadow: var(--shadow-3);
  backdrop-filter: blur(12px);
  padding: clamp(1.4rem, 1rem + 1.6vw, 2.1rem);
  color: #eaf5ef;
}
.hero-panel h2 { color: #fff; font-size: var(--step-2); margin: .8rem 0 .3rem; }
.hero-panel .badge { background: rgba(242, 168, 29, .18); color: var(--gold-400); }

.countdown { display: grid; grid-template-columns: repeat(4, 1fr); gap: .55rem; margin: 1.2rem 0 1.35rem; }
.countdown-cell {
  text-align: center;
  padding: .75rem .3rem .6rem;
  background: rgba(3, 42, 28, .42);
  border: 1px solid rgba(242, 168, 29, .26);
  border-radius: var(--radius);
}
.countdown-num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--step-2); font-weight: 700; line-height: 1;
  color: var(--gold-400);
  font-variant-numeric: tabular-nums;
}
.countdown-label { font-size: .62rem; text-transform: uppercase; letter-spacing: .1em; color: rgba(234, 245, 239, .62); }

/* ---------- Stats ---------- */
.stats {
  display: grid;
  /* 170px puts four figures into a balanced 2x2 on a phone. */
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  background: var(--bg);
  border: 1px solid var(--border);
  border-top: 3px solid var(--gold-500);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}
/* A quantity query: auto-fit cannot see how many children it has, and at
   170px a strip of exactly three figures breaks to two columns on a phone
   and strands the third on a row of its own. Three short figures fit across
   a 390px screen comfortably. Four keep the 2x2 above. */
.stats:has(> .stat:nth-child(3)):not(:has(> .stat:nth-child(4))) {
  grid-template-columns: repeat(auto-fit, minmax(105px, 1fr));
}

/* Centred as a column so every label sits on the same line even when one
   figure is wider than the others. */
.stat {
  padding: 1.6rem 1.25rem;
  text-align: center;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: .2rem;
}
.stat + .stat::before {
  content: "";
  position: absolute;
  inset-block: 22%;
  inset-inline-start: 0;
  width: 1px;
  background: var(--border);
}
.stat-num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--step-3); font-weight: 700; line-height: 1.1;
  color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
}
/* The participant figure opens the roll. A dotted rule says so without
   turning a headline number into something that looks like a button. */
a.stat-num {
  text-decoration: underline dotted;
  text-underline-offset: .22em;
  text-decoration-thickness: 2px;
  text-decoration-color: color-mix(in srgb, var(--brand) 40%, transparent);
}
a.stat-num:hover,
a.stat-num:focus-visible { text-decoration-style: solid; color: var(--brand-strong); }

.stat-label { font-size: var(--step--1); color: var(--text-muted); font-weight: 550; }

/* Squeezed into three columns on a phone, a two-word label wraps and drags
   its figure out of line with the others. Top-aligning the columns keeps the
   numbers on one line whatever the labels below them do. */
@media (max-width: 560px) {
  .stat { padding: 1.25rem .5rem; justify-content: flex-start; }
  .stat-label { font-size: .74rem; line-height: 1.35; }
}

/* ---------- Section headings ---------- */
.section-head { margin-bottom: clamp(1.75rem, 1rem + 2.2vw, 3rem); }
.section-head.center { margin-inline: auto; max-width: 64ch; text-align: center; }
.section-eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .74rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-ink); margin-bottom: .6rem;
}
.section-eyebrow::before {
  content: "";
  width: 9px; height: 9px;
  flex: 0 0 auto;
  background: var(--gold-500);
  clip-path: polygon(50% 0, 61% 24%, 85% 15%, 76% 39%, 100% 50%, 76% 61%, 85% 85%, 61% 76%, 50% 100%, 39% 76%, 15% 85%, 24% 61%, 0 50%, 24% 39%, 15% 15%, 39% 24%);
}
.section-head p { color: var(--text-muted); font-size: var(--step-1); }
.section-head.center .section-eyebrow { justify-content: center; }

/* ---------- Grid ---------- */
.grid { display: grid; gap: var(--gap); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 330px), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }

/* ---------- Cards ---------- */
.card {
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); border-color: color-mix(in srgb, var(--brand) 40%, var(--border)); }

.card-media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--bg-muted); }
.card-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s var(--ease); }
.card:hover .card-media img { transform: scale(1.05); }
.card-media .badge { position: absolute; inset-block-start: .8rem; inset-inline-start: .8rem; background: var(--bg); box-shadow: var(--shadow-1); }

.card-body { padding: 1.25rem 1.35rem 1.45rem; display: flex; flex-direction: column; flex: 1; gap: .55rem; }
.card-title { font-size: var(--step-1); margin: 0; line-height: 1.3; }
.card-title a { color: inherit; text-decoration: none; }
.card-title a:hover { color: var(--brand); }
.card-excerpt { color: var(--text-muted); font-size: var(--step--1); margin: 0; }
.card-meta { margin-top: auto; padding-top: .75rem; border-top: 1px solid var(--line-soft); display: flex; flex-wrap: wrap; gap: .8rem; font-size: .78rem; color: var(--text-muted); }
.card-meta > * { display: inline-flex; align-items: center; gap: .3rem; }

/* Feature card — topped with a mihrab arch holding the icon. */
.feature {
  position: relative;
  padding: 2.4rem 1.6rem 1.7rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.feature:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); border-color: color-mix(in srgb, var(--gold-500) 42%, var(--border)); }
.feature-icon {
  display: grid; place-items: center;
  width: 54px; height: 62px;
  margin-bottom: 1.1rem;
  /* Ogee arch: rounded at the top, squared at the base. */
  border-radius: 50% 50% 10px 10px / 62% 62% 8px 8px;
  background: var(--niche-bg);
  border: 1px solid color-mix(in srgb, var(--gold-500) 40%, transparent);
  color: var(--brand-ink);
}
.feature h3 { font-size: var(--step-1); margin-bottom: .4em; }
.feature p { color: var(--text-muted); font-size: var(--step--1); margin: 0; }

/* ---------- Wave (gelombang) cards ---------- */
.wave-card {
  position: relative;
  display: flex; flex-direction: column; gap: .85rem;
  padding: 1.5rem 1.6rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.wave-card::before {
  content: "";
  position: absolute;
  inset-block: 0; inset-inline-start: 0;
  width: 4px;
  background: linear-gradient(180deg, var(--brand-600), var(--accent-500));
}
.wave-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: color-mix(in srgb, var(--brand) 34%, var(--border)); }
.wave-card.is-current { border-color: color-mix(in srgb, var(--gold-500) 55%, transparent); background: var(--wave-current-bg); }
.wave-card.is-current::before { background: linear-gradient(180deg, var(--gold-500), var(--gold-400)); }

/* Roman numeral in a gold-ringed medallion. */
.wave-code {
  display: inline-grid; place-items: center;
  min-width: 46px; height: 46px; padding-inline: .5rem;
  border-radius: 50%;
  background: linear-gradient(145deg, var(--brand-700), var(--brand-600));
  border: 2px solid var(--gold-500);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 700; font-size: 1.05rem; letter-spacing: .02em;
}
.wave-head { display: flex; align-items: center; gap: .85rem; flex-wrap: wrap; }
.wave-dates { font-size: var(--step--1); color: var(--text-muted); font-weight: 600; }
.wave-faculties { font-size: var(--step--1); color: var(--ink-700); margin: 0; }
.wave-foot { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding-top: .75rem; border-top: 1px dashed var(--border); }
.wave-count { font-weight: 700; color: var(--brand); font-family: var(--font-display); }

/* ---------- Timeline ---------- */
/* The "jalinan" — a connecting thread running through the day. */
.timeline { position: relative; padding-inline-start: 2.1rem; }
.timeline::before {
  content: "";
  position: absolute;
  inset-block: .7rem;
  inset-inline-start: 7px;
  width: 2px;
  background: linear-gradient(180deg, var(--gold-500), var(--accent-500) 45%, var(--brand-600));
  border-radius: 2px;
}
.timeline-day { position: relative; margin-bottom: 2.5rem; }
.timeline-day::before {
  content: "";
  position: absolute;
  inset-inline-start: -2.1rem;
  top: .5rem;
  width: 16px; height: 16px;
  background: var(--gold-500);
  clip-path: polygon(50% 0, 61% 24%, 85% 15%, 76% 39%, 100% 50%, 76% 61%, 85% 85%, 61% 76%, 50% 100%, 39% 76%, 15% 85%, 24% 61%, 0 50%, 24% 39%, 15% 15%, 39% 24%);
}
.timeline-day.is-today::before { background: var(--accent-500); }
.timeline-date { display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap; margin-bottom: 1rem; }
.timeline-date h3 { margin: 0; font-size: var(--step-1); }
.timeline-date time { font-size: var(--step--1); color: var(--text-muted); }

.session {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 1.1rem;
  padding: .95rem 1.15rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease), transform .18s var(--ease);
}
.session + .session { margin-top: .65rem; }
.session:hover { border-color: color-mix(in srgb, var(--brand) 42%, var(--border)); box-shadow: var(--shadow-1); transform: translateX(2px); }
[dir="rtl"] .session:hover { transform: translateX(-2px); }
.session-time {
  font-family: var(--font-display);
  font-weight: 700; font-size: .9rem;
  color: var(--brand-ink);
  font-variant-numeric: tabular-nums;
  padding-top: .1rem;
}
.session-title { font-weight: 650; margin: 0 0 .25rem; font-size: var(--step-0); }
.session-meta { font-size: .8rem; color: var(--text-muted); display: flex; flex-wrap: wrap; gap: .5rem .85rem; align-items: center; }
@media (max-width: 560px) { .session { grid-template-columns: 1fr; gap: .4rem; } }

/* Attached teaching material, shown as compact chips under the session. */
.session-materials { display: flex; flex-wrap: wrap; gap: .4rem; margin: .5rem 0 .55rem; }
.session-material {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .3rem .7rem;
  border: 1px solid color-mix(in srgb, var(--gold-500) 45%, var(--border));
  border-radius: var(--radius-full);
  background: var(--badge-accent-bg);
  color: var(--badge-accent-fg);
  font-size: .76rem;
  font-weight: 600;
  text-decoration: none;
  transition: background-color .16s var(--ease), border-color .16s var(--ease), transform .16s var(--ease);
}
.session-material:hover {
  background: var(--gold-500);
  border-color: var(--gold-500);
  color: #3a2703;
  transform: translateY(-1px);
}
.session-material small { font-weight: 500; opacity: .75; }
:root[data-theme="dark"] .session-material:hover { color: #1b1606; }

.session.is-tentative { border-style: dashed; background: var(--bg-soft); }
.session.is-tentative .session-title { color: var(--text-muted); }

/* ---------- Tables ---------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-1); }
table.data { width: 100%; border-collapse: collapse; font-size: var(--step--1); min-width: 640px; }
table.data th, table.data td { padding: .9rem 1.1rem; text-align: start; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
table.data thead th {
  background: linear-gradient(135deg, var(--brand-800), var(--brand-700));
  color: #fff; font-weight: 650; font-size: .76rem; letter-spacing: .07em; text-transform: uppercase;
  position: sticky; top: 0;
}
table.data tbody tr:nth-child(even) { background: var(--bg-soft); }
table.data tbody tr:hover { background: var(--badge-bg); }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td.num, table.data th.num { text-align: end; font-variant-numeric: tabular-nums; }
table.data tfoot td { background: var(--badge-accent-bg); font-weight: 700; border-top: 2px solid var(--gold-500); }

/* ---------- Document library ---------- */
.doc-card {
  display: grid;
  grid-template-columns: 82px 1fr;
  gap: 1.2rem;
  padding: 1.25rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.doc-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: color-mix(in srgb, var(--gold-500) 45%, var(--border)); }

/* Styled like a bound kitab: gold spine on the binding edge. */
.doc-thumb {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: 4px var(--radius-sm) var(--radius-sm) 4px;
  overflow: hidden;
  background: linear-gradient(150deg, var(--brand-700), var(--brand-800));
  display: grid; place-items: center;
  box-shadow: var(--shadow-1);
}
.doc-thumb::before {
  content: "";
  position: absolute;
  inset-block: 0; inset-inline-start: 0;
  width: 6px;
  background: linear-gradient(180deg, var(--gold-500), var(--gold-600));
  z-index: 2;
}
.doc-thumb img { width: 100%; height: 100%; object-fit: cover; }
.doc-thumb svg { color: var(--gold-400); }
.doc-thumb .doc-ext {
  position: absolute; inset-block-end: 0; inset-inline: 0;
  padding: .2rem;
  background: rgba(3, 42, 28, .82); color: var(--gold-400);
  font-size: .58rem; font-weight: 800; letter-spacing: .08em; text-align: center;
  z-index: 2;
}
.doc-body { display: flex; flex-direction: column; gap: .45rem; min-width: 0; }
.doc-title { font-family: var(--font-display); font-size: var(--step-1); font-weight: 650; margin: 0; line-height: 1.3; }
.doc-title a { color: inherit; text-decoration: none; }
.doc-title a:hover { color: var(--brand); }
.doc-desc { font-size: var(--step--1); color: var(--text-muted); margin: 0; }
.doc-meta { display: flex; flex-wrap: wrap; gap: .45rem .9rem; font-size: .76rem; color: var(--text-muted); margin-top: auto; padding-top: .5rem; }
.doc-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .7rem; }

/* ---------- Prose (kertas kitab) ---------- */
.prose {
  font-size: 1.075rem;
  line-height: 1.85;
  color: var(--ink-700);
}
.prose > * + * { margin-top: 1.2em; }
.prose h2 {
  margin-top: 2.1em;
  font-size: var(--step-2);
  padding-bottom: .3em;
  border-bottom: 1px solid var(--border);
}
.prose h3 { margin-top: 1.7em; font-size: var(--step-1); color: var(--brand-ink); }
.prose img, .prose figure { border-radius: var(--radius); margin-block: 1.9em; }
.prose figure figcaption { margin-top: .6em; font-size: var(--step--1); color: var(--text-muted); text-align: center; }

.prose blockquote {
  margin-inline: 0;
  padding: 1.1em 1.4em;
  background: var(--paper);
  border: 1px solid var(--paper-line);
  border-inline-start: 3px solid var(--gold-500);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--ink-700);
  font-family: var(--font-display);
  font-size: 1.06em;
}
[dir="rtl"] .prose blockquote { border-radius: var(--radius) 0 0 var(--radius); }

.prose code {
  padding: .15em .4em;
  background: var(--bg-muted);
  border-radius: 4px;
  font-size: .9em;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}
.prose pre { padding: 1.1em 1.3em; background: var(--bg-soft); border: 1px solid var(--border); border-radius: var(--radius); overflow-x: auto; }
.prose pre code { background: none; padding: 0; }
.prose ul, .prose ol { padding-inline-start: 1.5em; }
.prose li + li { margin-top: .45em; }
.prose li::marker { color: var(--gold-600); }
.prose a { font-weight: 550; }
/* Video embeds. wp_kses() rebuilds every one of these with no width or
   height, so the ratio has to come from here or the frame collapses to the
   300x150 an iframe defaults to. */
.prose figure.embed { margin-block: 1.9em; }
.prose figure.embed iframe {
  display: block; width: 100%; aspect-ratio: 16 / 9; height: auto;
  border: 0; border-radius: var(--radius); background: var(--bg-muted);
}

.prose table { width: 100%; border-collapse: collapse; font-size: .94em; }
.prose th, .prose td { padding: .65em .85em; border: 1px solid var(--border); text-align: start; }
.prose thead th { background: var(--bg-soft); }

/* Ayat — Quranic verse, framed as an illuminated panel. */
.ayat {
  position: relative;
  font-family: var(--font-arabic);
  font-size: 1.7rem;
  line-height: 2.3;
  text-align: center;
  direction: rtl;
  color: var(--ayat-fg);
  padding: 2rem 2.4rem;
  background:
    var(--pattern-khatam) center / 80px 80px,
    var(--ayat-bg);
  background-blend-mode: soft-light;
  border: 1px solid var(--gold-500);
  border-radius: var(--radius-lg);
  box-shadow: inset 0 0 0 4px var(--ayat-inner);
}

/* ---------- Article header ---------- */
.article-head { padding-block: clamp(2.2rem, 1.5rem + 2vw, 3.5rem) 1.5rem; }
.article-title { font-size: var(--step-3); margin-bottom: .55rem; }
.article-meta { display: flex; flex-wrap: wrap; gap: 1rem; font-size: var(--step--1); color: var(--text-muted); }
.article-hero { margin-block: 1.9rem; border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--border); box-shadow: var(--shadow-2); }

/* ---------- Breadcrumbs ---------- */
/* Each crumb is centred on a shared line. Without this the separator and
   the current-page span sat on the text baseline while the links, padded
   out to a 24px tap target, stood taller — so the row came out ragged. */
.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 .1rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--step--1);
  color: var(--text-muted);
}
.breadcrumbs li { display: flex; align-items: center; }
.breadcrumbs li + li::before {
  content: "";
  width: 4px;
  height: 4px;
  margin-inline: .55rem;
  border-radius: 50%;
  background: var(--gold-600);
  flex: 0 0 auto;
}
/* Link and current page share one box, so they cannot drift apart. */
.breadcrumbs li > a,
.breadcrumbs li > [aria-current] {
  display: inline-block;
  padding-block: .3rem;
  line-height: 1.2;
}
.breadcrumbs a { color: var(--text-muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--brand); text-decoration: underline; }
.breadcrumbs [aria-current="page"] { color: var(--text); font-weight: 600; }

/* ---------- Wave detail ---------- */
.wave-hero { padding-block: clamp(2.25rem, 1.75rem + 4vw, 4rem) clamp(3.5rem, 3rem + 4vw, 5.5rem); }
.wave-status { margin-top: 1.35rem; }

.wave-headline {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: .9rem;
}
.wave-headline h1 { margin: 0; }
.wave-headline .wave-code {
  min-width: 62px;
  height: 46px;
  font-size: 1.15rem;
  flex: 0 0 auto;
}

.wave-dateline {
  display: flex;
  /* Start-aligned: on a phone the range wraps to two lines and a centred
     icon would float in the middle of them. */
  align-items: flex-start;
  gap: .6rem;
  margin: 1.1rem 0 0;
  font-size: var(--step-0);
  color: rgba(234, 245, 239, .88);
}
.wave-dateline svg { flex: 0 0 auto; margin-top: .28em; color: var(--gold-400); }

/* Pulls the strip up over the hero's lower edge. */
.wave-stats-wrap { margin-top: -2.75rem; position: relative; z-index: 2; }


/* Faculty names as pills rather than one run-on line. */
.chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* ---------- Forms ---------- */
.field { margin-bottom: 1.15rem; }
.field label { display: block; margin-bottom: .4rem; font-weight: 650; font-size: var(--step--1); }
.field .hint { font-size: .78rem; color: var(--text-muted); margin-top: .32rem; }
.required { color: var(--danger); }

.input, .select, .textarea {
  width: 100%;
  padding: .8rem 1rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: var(--step-0);
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 18%, transparent);
}
.textarea { min-height: 160px; resize: vertical; }
.input[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: var(--danger); }
.field-error { display: block; margin-top: .35rem; font-size: .8rem; color: var(--danger); font-weight: 550; }

.checkbox { display: flex; align-items: flex-start; gap: .6rem; font-size: var(--step--1); }
/* 17px is below the 24px WCAG 2.2 asks of a control, and a form control has
   no "inline in a sentence" exemption to fall back on. */
.checkbox input { margin-top: .1rem; width: 24px; height: 24px; accent-color: var(--brand); flex: 0 0 auto; }

/* ---------- Contact form ----------
   Two fixed columns, not auto-fit. auto-fit resolves to three columns once
   the form passes ~700px, which strands the fourth field on a row of its own
   beside two thirds of empty space.

   The breakpoint is a container query because this form's width does not
   track the viewport: it measures 706px inside a 746px window but only 634px
   inside a 1002px one, since the page grid around it changes column count.
   A viewport media query would be reading the wrong number. */
.contact-form {
  container-type: inline-size;
  padding: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 1rem;
}

@container (min-width: 30rem) {
  .form-grid { grid-template-columns: 1fr 1fr; }
}

/* For a field that should keep the full width whatever the column count. */
.form-grid > .field-wide { grid-column: 1 / -1; }

/* The closing row: security code on the left, submit on the right, so the
   bottom of the form reaches both edges the way every row above it does.
   Bottom-aligned, because the two have very different heights. */
.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
}
.form-actions > .field { margin-bottom: 0; }
.form-actions > .btn { margin-bottom: .35rem; }

/* ---------- Captcha ----------
   Presented as one bounded step rather than three loose controls sitting in
   a row. The gold edge marks it as the security gate, and the answer field
   sits directly beneath the image it refers to, so the eye never has to work
   out which box belongs to which. */
/* One full-width row of two columns whose tops and bottoms line up: the
   image on the left at its natural size, and a column on the right holding
   the answer field above the reload button. Both columns are exactly as tall
   as the image, so the block reads as a single balanced control rather than
   a stack of parts with ragged edges.

   Capped, because a five-character answer field stretched across a wide form
   column looks wrong however neatly it aligns. */
.captcha-field {
  display: flex;
  gap: .7rem;
  flex-wrap: wrap;
  /* Only bites once the row has wrapped: the answer column grows to fill the
     line, so side by side this changes nothing, but when the image drops onto
     a line of its own it sits centred instead of stranded against the left
     edge with a full-width field beneath it. */
  justify-content: center;
  max-width: 30rem;
  padding: .8rem;
  border: 1px solid var(--border);
  border-inline-start: 3px solid var(--gold-500);
  border-radius: var(--radius);
  background: var(--surface-2);
}

/* Fixed at its natural 224x76 so the glyphs stay pixel-crisp — it is never
   scaled up. The image carries its own paper ground, so this frame is what
   stops it looking like a hole punched in the panel under a dark theme. */
.captcha-img {
  display: block;
  flex: 0 0 auto;
  width: 224px;
  height: 76px;
  max-width: 100%;
  border: 1px solid var(--border);
  border-radius: calc(var(--radius) - 4px);
  background: #fdfbf4;
}

/* 42 + 6 + 28 = 76, matching the image exactly. */
.captcha-answer {
  flex: 1 1 9.5rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.captcha-reload {
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .35rem;
  padding: 0 .6rem;
  font-family: inherit;
  font-size: .74rem;
  font-weight: 600;
  color: var(--brand-ink);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: border-color .18s var(--ease), background-color .18s var(--ease);
}
.captcha-reload:hover { border-color: var(--brand-ink); background: var(--bg-muted); }
.captcha-reload svg { transition: transform .45s var(--ease); }
.captcha-reload:hover svg { transform: rotate(-180deg); }

/* Wide tracking to echo the spacing of the glyphs in the image. The
   text-indent compensates for the trailing letter-space, which would
   otherwise push the centred text visibly off-centre. */
.captcha-field .input {
  height: 42px;
  padding: 0 .5rem;
  text-align: center;
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: .34em;
  text-indent: .34em;
  text-transform: uppercase;
}

.hp-field { position: absolute !important; left: -9999px; opacity: 0; height: 0; overflow: hidden; }

/* ---------- Alerts ---------- */
.alert {
  display: flex; gap: .8rem; align-items: flex-start;
  padding: 1rem 1.2rem;
  border-radius: var(--radius);
  border: 1px solid;
  border-inline-start-width: 4px;
  font-size: var(--step--1);
  margin-bottom: 1.25rem;
}
.alert-success { background: var(--alert-success-bg); border-color: var(--brand-500); color: var(--alert-success-fg); }
.alert-error { background: var(--alert-error-bg); border-color: var(--danger); color: var(--alert-error-fg); }
.alert-warning { background: var(--alert-warning-bg); border-color: var(--gold-500); color: var(--alert-warning-fg); }
.alert-info { background: var(--alert-info-bg); border-color: var(--accent-500); color: var(--alert-info-fg); }


/* ---------- Pagination ---------- */
.pagination { display: flex; flex-wrap: wrap; justify-content: center; gap: .35rem; margin-top: 2.75rem; padding: 0; list-style: none; }
.pagination a, .pagination span {
  display: inline-grid; place-items: center;
  min-width: 42px; height: 42px; padding-inline: .7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-decoration: none; color: var(--ink-700);
  font-size: var(--step--1); font-weight: 550;
}
.pagination a:hover { background: var(--bg-soft); border-color: var(--brand); color: var(--brand); }
.pagination .active span, .pagination [aria-current="page"] {
  background: var(--brand-700); border-color: var(--brand-700); color: #fff; font-weight: 700;
}
.pagination .disabled span { opacity: .4; }

/* ---------- Footer ---------- */
.site-footer {
  position: relative;
  margin-top: var(--section-y);
  background: linear-gradient(165deg, var(--brand-900), var(--brand-800));
  color: #b9d3c6;
  padding-block: clamp(2.75rem, 2rem + 3vw, 4.25rem) 0;
  overflow: hidden;
}
.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--pattern-khatam);
  background-size: 84px 84px;
  opacity: .08;
  mask-image: linear-gradient(0deg, #000, transparent 72%);
  pointer-events: none;
}
.site-footer > * { position: relative; }
.footer-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }
.site-footer .footer-heading { color: #fff; font-size: .82rem; letter-spacing: .13em; text-transform: uppercase; margin-bottom: 1.1rem; font-family: var(--font-sans); font-weight: 700; }
.site-footer a { color: #b9d3c6; text-decoration: none; }
.site-footer a:hover { color: var(--gold-400); }

/* Two more targets the sweep caught, both nav rather than running prose, so
   both owe the 24px minimum:

   - Breadcrumb links were 17px tall.
   - The wave column in the schedule table links a Roman numeral, so "I" gave
     a 4x17px target. Nobody hits that with a thumb. */
/* Breadcrumb links get their box in the breadcrumb block above, where the
   separator and current-page span are lined up with them. */
table.data th[scope="row"] a {
  display: inline-block;
  min-width: 24px;
  padding-block: .28rem;
}
table.data th[scope="row"] a { text-align: center; padding-inline: .3rem; }

/* Footer navigation links were 17px tall — the text box and nothing else.
   WCAG 2.2 asks for 24px, and on a phone a 17px target between two others
   is genuinely hard to hit. The padding is vertical only, so the columns
   keep their rhythm. Links inside running prose are exempt and untouched. */
.site-footer li > a {
  display: inline-block;
  padding-block: .32rem;
}
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .6rem; font-size: var(--step--1); }
.footer-brand p { font-size: var(--step--1); color: #8fae9f; max-width: 42ch; }
.footer-bottom {
  margin-top: 2.75rem;
  padding-block: 1.35rem;
  border-top: 1px solid rgba(242, 168, 29, .2);
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
  font-size: .8rem; color: #8fae9f;
}

/* ---------- Floating controls ---------- */
.to-top {
  position: fixed;
  inset-block-end: 1.5rem;
  inset-inline-end: 1.5rem;
  z-index: 90;
  display: grid; place-items: center;
  width: 50px; height: 50px;
  border: 1px solid var(--gold-500);
  border-radius: 50%;
  background: linear-gradient(145deg, var(--brand-700), var(--brand-800));
  color: var(--gold-400);
  cursor: pointer;
  box-shadow: var(--shadow-2);
  opacity: 0; visibility: hidden;
  transform: translateY(12px);
  transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s, background-color .18s var(--ease);
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.to-top:hover { background: var(--brand-900); color: #fff; }

.a11y-toggle {
  position: fixed;
  inset-block-end: 1.5rem;
  inset-inline-start: 1.5rem;
  z-index: 95;
  display: grid; place-items: center;
  width: 50px; height: 50px;
  border: 1px solid var(--accent-500);
  border-radius: 50%;
  background: linear-gradient(145deg, var(--accent-600), #065f55);
  color: #fff;
  cursor: pointer;
  box-shadow: var(--shadow-2);
  transition: transform .2s var(--ease), background-color .18s var(--ease);
}
.a11y-toggle:hover { transform: scale(1.06); }

.a11y-panel {
  position: fixed;
  inset-block-end: 5.75rem;
  inset-inline-start: 1.5rem;
  z-index: 96;
  width: min(330px, calc(100vw - 3rem));
  max-height: min(70vh, 580px);
  overflow-y: auto;
  padding: 1.35rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent-500);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
}
.a11y-panel[hidden] { display: none; }
.a11y-panel h2 { font-size: 1.02rem; margin-bottom: .25rem; }
.a11y-panel > p { font-size: .79rem; color: var(--text-muted); margin-bottom: 1.1rem; }
.a11y-group { margin-bottom: 1.15rem; }
.a11y-group > span { display: block; font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); margin-bottom: .5rem; }
.a11y-options { display: flex; flex-wrap: wrap; gap: .4rem; }
.a11y-btn {
  flex: 1 1 auto;
  padding: .55rem .75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  font-size: .8rem; font-weight: 550;
  cursor: pointer;
  transition: background-color .16s var(--ease), border-color .16s var(--ease);
}
.a11y-btn:hover { background: var(--bg-soft); border-color: var(--accent-500); }
.a11y-btn[aria-pressed="true"] { background: var(--accent-600); border-color: var(--accent-600); color: #fff; font-weight: 700; }
.a11y-reset { width: 100%; margin-top: .25rem; }

/* Accessibility preference classes, applied to <html>. */
.a11y-font-lg { font-size: 112.5%; }
.a11y-font-xl { font-size: 125%; }
.a11y-font-xxl { font-size: 140%; }

.a11y-spacing body { letter-spacing: .06em; word-spacing: .16em; line-height: 2; }
.a11y-dyslexia body, .a11y-dyslexia .prose { font-family: "Comic Sans MS", "Trebuchet MS", Verdana, sans-serif; letter-spacing: .045em; }

.a11y-contrast {
  --bg: #fff; --bg-soft: #fff; --bg-muted: #fff; --paper: #fff;
  --ink-900: #000; --ink-700: #000; --ink-400: #1a1a1a;
  --border: #000; --line: #000; --line-soft: #000;
  --brand: #00381f; --brand-700: #00381f; --brand-800: #002415; --brand-100: #d9f0e2;
}
.a11y-contrast body { background: #fff; color: #000; }
.a11y-contrast a { color: #00308f; text-decoration: underline; }
.a11y-contrast .hero, .a11y-contrast .site-footer { background: #00381f; }
.a11y-contrast .hero::before, .a11y-contrast .site-footer::before { display: none; }
.a11y-contrast img:not(.keep-color) { filter: grayscale(.25) contrast(1.15); }

.a11y-links a { text-decoration: underline !important; text-decoration-thickness: 2px !important; }
.a11y-links a:focus, .a11y-links a:hover { background: var(--gold-100); }

.a11y-no-images img, .a11y-no-images picture, .a11y-no-images video { visibility: hidden; }
.a11y-no-images .card-media, .a11y-no-images .doc-thumb { background: repeating-linear-gradient(45deg, var(--bg-muted) 0 8px, var(--bg) 8px 16px); }

.a11y-cursor, .a11y-cursor * { cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cpath d='M6 2l24 15-10 2 6 12-5 3-6-12-7 7z' fill='%23000' stroke='%23fff' stroke-width='2'/%3E%3C/svg%3E") 4 2, auto !important; }

.a11y-guide-bar {
  position: fixed;
  inset-inline: 0;
  height: 44px;
  z-index: 94;
  background: rgba(17, 179, 157, .14);
  border-block: 2px solid rgba(17, 179, 157, .55);
  pointer-events: none;
}
.a11y-guide-bar[hidden] { display: none; }

/* ---------- PDF reader ---------- */
.reader { display: grid; grid-template-rows: auto 1fr; height: calc(100vh - var(--header-h)); background: var(--bg-muted); }
.reader-toolbar {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .6rem 1rem;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  z-index: 5;
}
.reader-toolbar .spacer { flex: 1; }
.reader-title { font-family: var(--font-display); font-weight: 650; font-size: var(--step-0); max-width: 34ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reader-page-input { width: 62px; text-align: center; padding: .4rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); font-variant-numeric: tabular-nums; }
.reader-zoom { font-variant-numeric: tabular-nums; font-size: .8rem; color: var(--text-muted); min-width: 48px; text-align: center; }

/* The stage has to fill this, not merely sit inside it. Left at content
   height, the stage never became a scroll container, so a page zoomed past
   the viewport was simply clipped by this wrapper's overflow:hidden with no
   way to reach the rest of it. */
.reader-body { position: relative; overflow: hidden; display: grid; min-height: 0; }

.reader-stage {
  position: relative;
  overflow: auto;
  padding: 1.5rem;
  min-height: 0;
  display: flex;
}

/* Centring via auto margins rather than justify/align-content. When the page
   is larger than the stage, auto margins resolve to zero and it lands at the
   start edge, fully scrollable; centring keywords push the top of an
   oversized page above the scroll origin, where it cannot be reached.
   `align-content: safe center` is meant to cover that and did not. */
.reader-stage > * { margin: auto; }
.reader-canvas-wrap { position: relative; background: #fff; box-shadow: var(--shadow-3); border-radius: 3px; }
.reader-canvas-wrap canvas { display: block; border-radius: 3px; }

.reader.is-flipbook .reader-stage { align-content: center; }
.reader.is-flipbook .reader-spread { display: flex; gap: 0; perspective: 2400px; }
.reader.is-flipbook .reader-spread .reader-canvas-wrap { border-radius: 0; }
.reader.is-flipbook .reader-spread .reader-canvas-wrap:first-child { border-radius: 4px 0 0 4px; box-shadow: inset -22px 0 26px -22px rgba(0, 0, 0, .38), var(--shadow-3); }
.reader.is-flipbook .reader-spread .reader-canvas-wrap:last-child { border-radius: 0 4px 4px 0; box-shadow: inset 22px 0 26px -22px rgba(0, 0, 0, .38), var(--shadow-3); }
.reader.is-flipbook .reader-spread.is-turning { animation: page-turn .45s var(--ease); }
@keyframes page-turn {
  0% { transform: rotateY(0deg); }
  50% { transform: rotateY(-7deg); }
  100% { transform: rotateY(0deg); }
}

.reader-nav {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  display: grid; place-items: center;
  width: 48px; height: 48px;
  border: 1px solid var(--border); border-radius: 50%;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(6px);
  color: var(--ink-700); cursor: pointer;
  box-shadow: var(--shadow-2);
  z-index: 4;
}
.reader-nav:hover { background: var(--brand-700); color: #fff; border-color: var(--brand-700); }
.reader-nav[disabled] { opacity: .3; cursor: default; }
.reader-prev { inset-inline-start: 1rem; }
.reader-next { inset-inline-end: 1rem; }

.reader-loading { display: grid; place-items: center; gap: .85rem; padding: 4rem 1rem; color: var(--text-muted); }
.spinner {
  width: 36px; height: 36px;
  border: 3px solid var(--border);
  border-top-color: var(--gold-500);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.reader-thumbs {
  position: absolute;
  inset-block: 0; inset-inline-start: 0;
  width: 172px;
  padding: .8rem;
  overflow-y: auto;
  background: var(--bg);
  border-inline-end: 1px solid var(--border);
  z-index: 3;
}
.reader-thumbs[hidden] { display: none; }
.reader-thumb { display: block; width: 100%; margin-bottom: .65rem; padding: 0; border: 2px solid transparent; border-radius: var(--radius-sm); background: none; cursor: pointer; }
.reader-thumb canvas { width: 100%; height: auto; border: 1px solid var(--border); border-radius: 3px; display: block; }
.reader-thumb.is-active { border-color: var(--gold-500); }
.reader-thumb span { display: block; font-size: .68rem; color: var(--text-muted); text-align: center; padding-top: .2rem; }

.reader-text-layer { position: absolute; inset: 0; overflow: hidden; opacity: .22; line-height: 1; pointer-events: auto; }
.reader-text-layer span { position: absolute; white-space: pre; transform-origin: 0 0; color: transparent; }
.reader-text-layer ::selection { background: rgba(17, 179, 157, .4); }

.reader-noscript { padding: 2rem; text-align: center; }

/* The toolbar's two parts. Above the touch breakpoint they sit on one line
   and read exactly as they always did. */
.reader-bar { display: contents; }
.reader-tools { display: contents; }
.reader-more { display: none; }

/* The bottom dock only exists for touch screens. */
.reader-dock { display: none; }

/* ---------- Reader on phones and tablets ----------
   Measured before rewriting: on a 390x844 phone the site header plus a
   toolbar that wrapped to three ragged rows consumed 465px — 55% of the
   screen — before a single line of the document was visible. So the header
   goes (the reader has its own back button), the toolbar keeps only what is
   needed to orient, and paging moves to a dock the thumb can actually
   reach. */
@media (max-width: 1040px) {
  .document-reader .site-header,
  .document-reader .site-footer { display: none; }

  .reader {
    height: 100dvh;
    grid-template-rows: auto 1fr auto;
  }

  .reader-toolbar {
    display: grid;
    gap: 0;
    padding: 0;
    flex-wrap: nowrap;
  }

  .reader-bar {
    display: flex;
    align-items: center;
    gap: .4rem;
    min-height: 52px;
    padding: .35rem .6rem;
  }

  .reader-title { max-width: none; flex: 1; font-size: .95rem; }

  .reader-more {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 40px;
    padding: 0 .75rem;
    font-family: inherit;
    font-size: .8rem;
    font-weight: 600;
    color: var(--text);
    background: var(--bg-soft);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    cursor: pointer;
  }

  /* Collapsed until "Alat" is pressed. */
  .reader-tools {
    display: none;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    padding: .6rem;
    background: var(--bg-soft);
    border-top: 1px solid var(--border);
  }
  .reader.tools-open .reader-tools { display: flex; }
  .reader-tools .input { flex: 1 1 8rem; min-width: 0; }

  .reader-stage { padding: .5rem; }

  /* The floating arrows sat ~330px away from the page on a tablet and in
     the middle of empty space on a phone. The dock replaces them. */
  .reader-nav { display: none; }

  .reader-dock {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .5rem max(.75rem, env(safe-area-inset-left)) max(.5rem, env(safe-area-inset-bottom));
    background: var(--bg);
    border-top: 1px solid var(--border);
  }

  .reader-dock button {
    display: grid;
    place-items: center;
    width: 56px;
    height: 44px;
    color: var(--text);
    background: var(--bg-soft);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    cursor: pointer;
  }
  .reader-dock button[disabled] { opacity: .35; }
  .reader-dock-page {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: .95rem;
  }

  .reader-thumbs { width: 108px; }

  /* The two floating buttons sat exactly on top of the dock's arrows. The
     reader fills the viewport and never scrolls the page, so back-to-top has
     nothing to do here; the accessibility toggle is lifted clear instead. */
  .document-reader .to-top { display: none; }
  .document-reader .a11y-toggle { bottom: calc(61px + .75rem); }
  .document-reader .a11y-panel { bottom: calc(61px + 4.25rem); }
}

@media (max-width: 720px) {
  .reader-thumbs { width: 132px; }
  .reader.is-flipbook .reader-spread { flex-direction: column; }
  .reader-title { max-width: 16ch; }
}

/* ---------- Empty state ---------- */
.empty {
  padding: 3.75rem 1.5rem;
  text-align: center;
  border: 2px dashed var(--border);
  border-radius: var(--radius-lg);
  color: var(--text-muted);
  background: var(--bg-soft);
}
.empty svg { margin: 0 auto 1rem; color: var(--ink-300); }

/* ---------- Print ---------- */
@media print {
  .site-header, .site-footer, .to-top, .a11y-toggle, .a11y-panel,
  .breadcrumbs, .pagination, .reader-toolbar, .reader-thumbs, .reader-nav { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .hero { background: none !important; color: #000; }
  .hero h1, .hero-lede { color: #000; }
  .prose a::after { content: " (" attr(href) ")"; font-size: .85em; color: #555; }
  .card, .doc-card, .wave-card { break-inside: avoid; border: 1px solid #ccc; }
}

/* ================================================================
   Participant roll
   ================================================================ */

/* The headcount becomes a link once a roll has been imported. The dotted
   underline says "there is more here" without turning the figure into a
   button competing with "Lihat Jadwal" beside it. */
/* A wave that has finished steps back without disappearing — it still
   answers "which one was mine" for anyone checking afterwards. */
.wave-card.is-past { opacity: .72; }
.wave-card.is-past:hover, .wave-card.is-past:focus-within { opacity: 1; }

.wave-count.is-link {
  text-decoration: underline dotted;
  text-underline-offset: .28em;
  text-decoration-thickness: 1.5px;
  text-decoration-color: color-mix(in srgb, var(--brand) 45%, transparent);
}
.wave-count.is-link:hover,
.wave-count.is-link:focus-visible { text-decoration-style: solid; color: var(--brand-strong); }

/* ---- Search and sort -------------------------------------------
   The toolbar is capped at the same width as the table below, so the
   two edges line up instead of the controls floating narrower than
   the data they act on. Input and button live inside one bordered
   shell: two rounded shapes side by side read as two unrelated
   controls, one shell reads as a single search field. */
.roll-tools {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  max-width: 62rem; margin: 1.5rem 0 1.1rem;
}

.roll-search-shell {
  display: flex; align-items: center; gap: .5rem;
  flex: 1 1 22rem; min-width: 0;
  padding: .3rem .3rem .3rem .85rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-1);
  transition: border-color .15s, box-shadow .15s;
}
.roll-search-shell:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 16%, transparent);
}

.roll-search-icon { width: 17px; height: 17px; flex: 0 0 auto; color: var(--text-muted); }

.roll-search-shell input {
  flex: 1 1 auto; min-width: 0;
  padding: .5rem 0;
  font: inherit; font-size: var(--step-0);
  color: var(--text); background: none; border: 0;
}
.roll-search-shell input:focus { outline: none; }
/* The browser's own clear cross sits badly inside a pill. */
.roll-search-shell input::-webkit-search-cancel-button { display: none; }

.roll-search-shell button {
  flex: 0 0 auto;
  padding: .55rem 1.35rem;
  font: inherit; font-size: .92rem; font-weight: 600;
  color: #fff; background: var(--brand);
  border: 0; border-radius: var(--radius-full);
  cursor: pointer;
  transition: background-color .15s;
}
.roll-search-shell button:hover { background: var(--brand-strong); }
.roll-search-shell button:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }

/* Sort sits to the right of the search on a wide row and drops beneath
   it on a narrow one, where it takes the full width rather than being
   squeezed into a corner. */
.roll-sort { display: flex; align-items: center; gap: .45rem; flex: 0 0 auto; }
.roll-sort label { font-size: var(--step--1); color: var(--text-muted); white-space: nowrap; }
.roll-sort select {
  padding: .58rem 2rem .58rem .8rem;
  font: inherit; font-size: var(--step--1);
  color: var(--text); background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-full);
  cursor: pointer; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c766a' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .65rem center; background-size: 14px;
}
[dir="rtl"] .roll-sort select { background-position: left .65rem center; padding: .58rem .8rem .58rem 2rem; }
.roll-sort select:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }

.roll-sort-go {
  padding: .58rem 1rem; font: inherit; font-size: var(--step--1); font-weight: 600;
  color: var(--text); background: var(--bg-soft);
  border: 1px solid var(--border); border-radius: var(--radius-full); cursor: pointer;
}

.roll-meta { max-width: 62rem; margin: -.4rem 0 1rem; font-size: var(--step--1); color: var(--text-muted); }

/* ---- Table -----------------------------------------------------
   Fixed layout so the columns keep their width down the whole page
   instead of each row negotiating its own; that is what made the
   rows jump about in height before. */
/* Capped so a 1240px wrap does not stretch the name column to twice the
   width it needs, leaving a canyon before the programme column. */
.roll-wrap { max-width: 62rem; }
table.data.roll { min-width: 40rem; table-layout: fixed; }
table.data.roll th, table.data.roll td { padding: .6em .85em; vertical-align: middle; }

table.data.roll .roll-no { width: 3.5rem; text-align: end; }
table.data.roll td.roll-no { color: var(--text-muted); font-variant-numeric: tabular-nums; font-size: var(--step--1); }

table.data.roll .roll-nim { width: 9.5rem; }
table.data.roll td.roll-nim { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--text-muted); }

table.data.roll td.roll-name { font-weight: 600; }
table.data.roll .roll-prodi { width: 14rem; }
table.data.roll td.roll-prodi { color: var(--text-muted); font-size: var(--step--1); }

/* Zebra striping earns its keep on a list this long — the eye needs a
   rail to follow from a name across to its programme. */
table.data.roll tbody tr:nth-child(even) { background: var(--bg-soft); }
table.data.roll tbody tr:hover { background: var(--badge-bg); }

@media (max-width: 560px) {
  .roll-search-shell { padding-inline-start: .7rem; }
  .roll-search-shell button { padding-inline: 1rem; }
  table.data.roll { min-width: 32rem; }
  table.data.roll .roll-prodi { width: 10rem; }
}
