/*
 * Manifest compiled by Propshaft into /assets/application-*.css.
 * No build step (Tailwind/Sass) -- plain CSS with cascade layers, so file
 * load order never matters and !important is never needed.
 */

@layer reset, base, layout, components, utilities;

@layer reset {
  *, *::before, *::after {
    box-sizing: border-box;
  }

  html, body {
    margin: 0;
  }

  img, svg {
    max-width: 100%;
    display: block;
  }

  a {
    color: inherit;
    text-decoration: none;
  }
}

@layer base {
  :root {
    /* Brand: navy + gold ("Biru-Emas Klasik") */
    --color-navy: #1E3A5F;
    --color-navy-dark: #142943;
    --color-gold: #C9A227;

    --color-navy-light: color-mix(in oklch, var(--color-navy) 55%, white);
    --color-gold-light: color-mix(in oklch, var(--color-gold) 45%, white);
    --color-gold-dark: color-mix(in oklch, var(--color-gold) 80%, black);

    /* Site header background only -- rest of the brand's navy stays as-is
       (footer, buttons, text) so this doesn't ripple through the palette. */
    --color-header: #0284C7;

    --color-canvas: #ffffff;
    --color-canvas-subtle: #F6F7FA;
    --color-ink: #1F2933;
    --color-ink-light: #5B6573;
    --color-border: #E2E5EA;

    --color-link: var(--color-navy);

    --color-negative-bg: #FDECEC;
    --color-negative-ink: #9B1C1C;
    --color-positive-bg: #EAF7EE;
    --color-positive-ink: #1B6B3A;

    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    --text-xs: 0.8rem;
    --text-sm: 0.925rem;
    --text-base: 1.05rem;
    --text-lg: 1.25rem;
    --text-xl: 1.6rem;
    --text-2xl: clamp(2rem, 4vw, 2.75rem);
    --text-3xl: clamp(2.25rem, 5vw, 3.5rem);

    --space-1: 0.5rem;
    --space-2: 1rem;
    --space-3: 1.5rem;
    --space-4: 2rem;
    --space-6: 3rem;
    --space-8: 4rem;

    --radius: 0.5rem;
    --radius-lg: 1rem;
    --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.06);
    --shadow-md: 0 6px 16px rgb(0 0 0 / 0.10);
    --shadow-lg: 0 16px 40px rgb(0 0 0 / 0.16);

    --max-width: 72rem;

    color-scheme: light;
  }

  body {
    font-family: var(--font-sans);
    background: var(--color-canvas);
    color: var(--color-ink);
    font-size: var(--text-base);
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
  }

  h1, h2, h3, h4 {
    line-height: 1.2;
    font-weight: 700;
    color: var(--color-navy-dark);
    margin: 0 0 var(--space-2);
  }

  h1 { font-size: var(--text-2xl); }
  h2 { font-size: var(--text-xl); margin-top: var(--space-4); }
  h3 { font-size: var(--text-lg); }

  p {
    margin: 0 0 var(--space-2);
    color: var(--color-ink-light);
    max-width: 70ch;
  }

  .indented-paragraph {
    text-indent: 2em;
    text-align: justify;
  }

  /* Tentang Kami page: larger body text on desktop only, headings untouched. */
  @media (min-width: 641px) {
    .about-content p {
      font-size: var(--text-lg);
    }
  }

  .about-content {
    font-family: "Quicksand", var(--font-sans);
    padding-inline: 1.5rem;
  }

  .about-content h1,
  .about-content h2 {
    font-family: "Playfair Display", "Quicksand", var(--font-sans);
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }

  @media (min-width: 641px) {
    .about-content {
      padding-inline: 10rem;
    }
  }

  .contact-content {
    padding-inline: 1.5rem;
  }

  @media (min-width: 641px) {
    .contact-content {
      padding-inline: 4rem;
    }
  }

  /* Mobile only: the longest line ("Ibadah Wanita: Sabtu Pertama pukul
     16.00 WIB") wraps at narrow widths with just "WIB" dropping to its own
     line, reading as cut off. Shrinking the font (clamp so it scales with
     viewport instead of a single fixed size) keeps every line on one row
     on typical phone widths. Desktop is untouched -- this only applies
     under the same 640px breakpoint the rest of this page's mobile
     adjustments use. */
  @media (max-width: 640px) {
    .service-hours {
      font-size: clamp(0.8rem, 3.8vw, 0.95rem);
    }
  }

  .commission-show-content {
    padding-inline: 1.5rem;
  }

  @media (min-width: 641px) {
    .commission-show-content {
      padding-inline: 4rem;
    }

    .commission-show-content p {
      max-width: none;
    }
  }

  /* Override the global p { max-width: 70ch } cap so paragraphs stretch to
     the full content width instead of stopping partway across the page. */
  .about-content p {
    max-width: none;
  }

  a {
    color: var(--color-link);
  }

  a:hover {
    color: var(--color-gold-dark);
  }

  /* Animated hover underline for plain text/nav links (navbar, prose, footer).
     Scoped to unclassed <a> tags so card/button links (which style themselves
     via a class and already set text-decoration: none) are left untouched. */
  a:not([class]) {
    position: relative;
  }

  a:not([class])::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -0.15em;
    width: 100%;
    height: 1px;
    background: currentColor;
    transform: scaleX(0);
    transform-origin: right;
    transition: transform 0.2s ease;
  }

  a:not([class]):hover::after,
  a:not([class]):focus-visible::after {
    transform: scaleX(1);
    transform-origin: left;
  }

  ul {
    padding-left: 1.25rem;
  }

  li {
    margin-bottom: var(--space-1);
  }

  *:focus-visible {
    outline: 2px solid var(--color-gold);
    outline-offset: 2px;
  }
}

@layer layout {
  .site-header {
    background: var(--color-header);
    position: sticky;
    top: 0;
    z-index: 30;
    box-shadow: var(--shadow-sm);
    overflow: visible;
  }

  .site-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    height: 4.75rem;
    padding-block: 0;
    flex-wrap: wrap;
  }

  .site-nav .brand {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    text-decoration: none;
  }

  .brand__logo {
    height: 5.5rem;
    width: auto;
    flex-shrink: 0;
  }

  .brand__name {
    font-weight: 700;
    font-size: var(--text-base);
    color: #fff;
    letter-spacing: 0.01em;
    line-height: 1.25;
  }

  .brand__sub {
    font-weight: 400;
    font-size: 1.6rem;
    color: var(--color-gold-light);
    letter-spacing: 0.02em;
  }

  .nav-links {
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
  }

  .nav-links a {
    color: #fff;
    font-size: var(--text-sm);
    font-weight: 700;
    transition: color 0.15s;
  }

  .nav-links a:hover {
    color: var(--color-gold);
  }

  .nav-overlay {
    display: none;
  }

  .nav-drawer-logo {
    display: none;
  }

  .nav-verse {
    display: none;
  }

  @media (max-width: 800px) {
    .site-nav {
      position: relative;
      height: auto;
      padding-block: var(--space-1);
      flex-wrap: nowrap;
    }

    .brand__logo {
      height: 3rem;
    }

    .brand__name {
      font-size: var(--text-sm);
    }

    .brand__sub {
      font-size: var(--text-xs);
    }

    .nav-overlay {
      display: block;
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, 0.45);
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.2s;
      z-index: 35;
    }

    .nav-overlay.is-open {
      opacity: 1;
      pointer-events: auto;
    }

    /* Same sky blue as .site-header (var(--color-header)) so the open
       drawer reads as an extension of the header, not a separate white
       sheet. Slide (transform) is paired with a fade + slight scale for a
       softer, less mechanical open/close than a plain translateX -- and
       each link fades/slides in with its own stagger delay (below) so
       opening the drawer reveals the menu one row after another. */
    .nav-links {
      position: fixed;
      inset-block: 0;
      left: 0;
      width: min(80vw, 300px);
      display: flex;
      flex-direction: column;
      /* Reset the desktop rule's flex-wrap: wrap (base .nav-links above) --
         left as-is here, a column-direction flex container that overflows
         its fixed height wraps into a second side-by-side column instead
         of just growing past the container, which is exactly wrong for an
         off-canvas drawer: it should never grow sideways, only scroll. */
      flex-wrap: nowrap;
      align-items: stretch;
      gap: 0;
      background: var(--color-header);
      box-shadow: 2px 0 16px rgba(0, 0, 0, 0.2);
      transform: translateX(-100%) scale(0.96);
      opacity: 0;
      transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.3s ease;
      z-index: 40;
      overflow-x: hidden;
      overflow-y: auto;
      padding: 3.5rem var(--space-2) var(--space-2);
    }

    .nav-drawer-logo {
      display: block;
      position: absolute;
      top: 0.5rem;
      left: 1rem;
      height: 2.5rem;
      width: auto;
    }

    .nav-links.is-open {
      transform: translateX(0) scale(1);
      opacity: 1;
    }

    /* The logout button is a <button class="nav-logout-btn"> wrapped in an
       auto-generated <form> (button_to) -- the form, not the button, is
       the actual flex item inside .nav-links, so alignment/spacing goes
       here rather than on .nav-logout-btn itself. text-align: center
       centers the button (inline-flex, sized to its own text -- see the
       base .nav-logout-btn rule, and the display: block override for this
       same selector in the @layer components section below) inside the
       form. The auto top margin (matching .nav-verse below) pushes it
       down away from "PENGURUS" into the drawer's lower half instead of
       sitting right under it.

       display/width/max-width for this form are NOT set here: this block
       is inside @layer layout, and the global `form { display: flex;
       ... }` reset ("Forms" section below) lives in @layer components --
       later in the @layer reset,base,layout,components,utilities
       declaration at the top of this file, so it wins outright regardless
       of specificity. That override lives with the rest of the
       .nav-logout-btn rules in @layer components instead (search
       "blockifies"). */
    .nav-links form {
      margin-top: auto;
      text-align: center;
    }

    .nav-links a {
      width: 100%;
      color: #fff;
      padding: var(--space-2) var(--space-3);
      border-bottom: 1px solid rgba(255, 255, 255, 0.2);
      transition: background-color 0.15s ease, opacity 0.3s ease, transform 0.3s ease;
      opacity: 0;
      transform: translateX(-14px);
    }

    .nav-links a:hover {
      background: rgba(255, 255, 255, 0.12);
    }

    .nav-links a:active,
    .nav-links a.is-pressed {
      background: rgba(255, 255, 255, 0.22);
      transition-duration: 0.05s;
    }

    .nav-links.is-open a {
      opacity: 1;
      transform: translateX(0);
    }

    .nav-links.is-open a:nth-child(1) { transition-delay: 0.08s; }
    .nav-links.is-open a:nth-child(2) { transition-delay: 0.13s; }
    .nav-links.is-open a:nth-child(3) { transition-delay: 0.18s; }
    .nav-links.is-open a:nth-child(4) { transition-delay: 0.23s; }
    .nav-links.is-open a:nth-child(5) { transition-delay: 0.28s; }
    .nav-links.is-open a:nth-child(6) { transition-delay: 0.33s; }
    .nav-links.is-open a:nth-child(7) { transition-delay: 0.38s; }
    .nav-links.is-open a:nth-child(8) { transition-delay: 0.43s; }
    .nav-links.is-open a:nth-child(9) { transition-delay: 0.48s; }

    /* Verse footer under the last drawer link (LOGIN, or Logout when
       signed in). margin-top: auto pins it to the bottom of the drawer's
       flex column on short menus (guest with few links) instead of
       trailing right under the last link; on long menus (many open
       meetings) it just falls in normal flow after everything else and
       scrolls with the rest. Both lines are forced onto a single line
       (white-space: nowrap) with a vw-based clamp() font-size instead of a
       fixed size, so they shrink to fit the ~80vw-wide drawer on narrow
       phones rather than wrapping or clipping. */
    .nav-verse {
      display: block;
      margin-top: auto;
      padding: var(--space-3) var(--space-2) var(--space-1);
      text-align: center;
    }

    .nav-verse__zh {
      font-family: "Playfair Display", var(--font-sans);
      font-weight: 600;
      color: #fff;
      white-space: nowrap;
      font-size: clamp(0.8rem, 4.5vw, 1.1rem);
      letter-spacing: 0.04em;
      margin: 0 0 0.35rem;
    }

    .nav-verse__en {
      font-family: "Quicksand", var(--font-sans);
      font-style: italic;
      color: rgba(255, 255, 255, 0.85);
      white-space: nowrap;
      font-size: clamp(0.5rem, 3vw, 0.75rem);
      margin: 0;
    }
  }

  .container {
    max-width: var(--max-width);
    margin-inline: auto;
    padding: var(--space-4) var(--space-3);
  }

  .pengurus-main {
    max-width: var(--max-width);
    margin-inline: auto;
    padding-inline: var(--space-3);
  }

  .site-footer {
    background: var(--color-navy-dark);
    color: rgba(255, 255, 255, 0.7);
    margin-top: var(--space-8);
  }

  .footer-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding-block: var(--space-3);
    flex-wrap: wrap;
  }

  .footer-social {
    display: flex;
    gap: var(--space-2);
    align-items: center;
  }

  .footer-social__link {
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.15s, transform 0.15s;
  }

  .footer-social__link:hover {
    opacity: 0.8;
    transform: translateY(-2px);
  }

  .footer-social__icon {
    width: 2rem;
    height: 2rem;
  }

  .footer-brand {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
  }

  .footer-brand__logo {
    height: 2rem;
    width: auto;
    opacity: 0.85;
    flex-shrink: 0;
  }

  .footer-brand__copy {
    color: rgba(255, 255, 255, 0.7);
    font-size: var(--text-sm);
    font-weight: 600;
    margin: 0;
    white-space: nowrap;
  }

  .footer-brand__detail {
    color: rgba(255, 255, 255, 0.5);
    font-size: var(--text-xs);
    margin: 0;
  }

  .footer-brand__detail a {
    color: rgba(255, 255, 255, 0.5);
  }

  .footer-brand__detail a:hover {
    color: var(--color-gold-light);
  }

  .site-footer p {
    color: rgba(255, 255, 255, 0.6);
    margin: 0;
  }

  .site-footer a {
    color: rgba(255, 255, 255, 0.5);
    font-size: var(--text-xs);
  }

  .site-footer a:hover {
    color: var(--color-gold-light);
  }
}

@layer components {
  /* Hero slideshow: each .hero__slide is a full-bleed <img> + dark overlay,
     crossfaded by toggling .is-active (see hero_slideshow_controller.js).
     Rendered via <img>, not a CSS background-image -- Propshaft 1.3.2 has
     no ERB/asset_path support inside .css files, and an inline
     style="background-image: url("...")" attribute would be silently
     dropped by the strict style-src CSP (no `unsafe-inline`). The first
     slide ships server-rendered with .is-active, so the hero still shows
     one photo correctly before/without JS. */
  .hero {
    position: relative;
    min-height: 100dvh;
    color: #fff;
    overflow: hidden;
    background: var(--color-navy-dark);
  }

  @media (max-width: 800px) {
    .hero {
      /* Plain 50dvh clips text on short viewports (landscape phones, a
         squeezed browser window, devtools' responsive mode) since it
         shrinks with the viewport with no floor -- 400px guarantees room
         for a 3-line title + subtitle + button regardless of how short the
         viewport gets, while still landing at roughly half height on a
         normal phone. */
      min-height: max(50dvh, 400px);
    }
  }

  .hero__slide {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 1s ease;
  }

  .hero__slide.is-active {
    opacity: 1;
    pointer-events: auto;
    z-index: 1;
  }

  .hero__slide::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(10, 20, 35, 0.45), rgba(10, 20, 35, 0.8));
  }

  /* No text overlay on this slide (e.g. a designed announcement graphic
     that already contains its own text) -- skip the dark gradient so it
     doesn't muddy the image's own design. */
  .hero__slide--plain::after {
    display: none;
  }

  .hero__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 35%;
  }

  /* Plain slides are designed announcement graphics with their own baked-in
     text (see the comment on .hero__slide--plain::after above). Fills the
     hero edge-to-edge on every device instead of letterboxing -- this
     crops whatever falls outside the hero's aspect ratio at a given
     viewport, so the poster's own design must keep important text (times,
     dates) in a centered "safe zone" rather than near the edges. */
  .hero__slide--plain .hero__image {
    object-fit: cover;
    object-position: center;
  }

  .hero__content {
    position: relative;
    z-index: 1;
  }

  .hero h1 {
    color: #fff;
    font-size: var(--text-3xl);
    max-width: 24ch;
  }

  .hero p {
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--text-lg);
    max-width: 48ch;
  }

  .cta-group {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-3);
    flex-wrap: wrap;
  }

  /* Must come after the unconditional .hero h1/.hero p/.cta-group rules
     above -- same specificity, so an earlier position would lose the
     cascade on every viewport width, not just desktop. Shrinks the text
     overlay to fit the shorter mobile hero (see the min-height override
     above) and tightens the gaps so long titles/subtitles stop getting
     clipped by .hero's overflow: hidden. */
  @media (max-width: 800px) {
    .hero h1 {
      font-size: 1.5rem;
      margin-bottom: var(--space-1);
    }

    .hero p {
      font-size: var(--text-sm);
      margin-bottom: var(--space-1);
      /* Lets a literal newline in slide.subtitle force a line break here
         (e.g. avoiding an awkward mid-word wrap) without affecting desktop,
         where the same newline just collapses to a space as normal. */
      white-space: pre-line;
    }

    .hero .cta-group {
      margin-top: var(--space-1);
    }

    /* Slide-specific: this CTA sits right under a two-line subtitle and
       reads as cramped at this margin, unlike the other slides -- pushed
       down further on mobile only, per request. Scoped to the slide's own
       dom_id (not .hero__slide:nth-of-type) so it stays correct if slides
       get reordered or others are added/removed via the admin panel. */
    #hero_slide_3 .cta-group {
      margin-top: var(--space-6);
    }
  }

  /* Prev/next + dots, scoped under .hero so they out-specificity the
     generic `button:not(.btn)` rule below without relying on source order. */
  .hero .hero__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 2.75rem;
    height: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.35);
    color: #fff;
    border: none;
    border-radius: 50%;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.15s;
  }

  .hero .hero__nav:hover {
    background: rgba(0, 0, 0, 0.55);
  }

  .hero .hero__nav--prev { left: var(--space-3); }
  .hero .hero__nav--next { right: var(--space-3); }

  .hero__dots {
    position: absolute;
    bottom: var(--space-4);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    display: flex;
    gap: 0.6rem;
  }

  .hero .hero__dot {
    width: 0.65rem;
    height: 0.65rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.45);
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
  }

  .hero .hero__dot.is-active {
    background: var(--color-gold);
    transform: scale(1.3);
  }

  /* POS PI photo slideshow, below the page banner -- same crossfade
     behavior and hero-slideshow Stimulus controller as .hero, but a
     moderate in-page size instead of full-bleed, and plain photos with no
     text overlay. */
  .pos-pi-slideshow {
    position: relative;
    height: clamp(280px, 50vw, 600px);
    overflow: hidden;
    background: var(--color-navy-dark);
    border-radius: 0;
    margin: 0 0 var(--space-4);
  }

  .pos-pi-slideshow__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    pointer-events: none;
    transition: opacity 1s ease;
  }

  .pos-pi-slideshow__slide.is-active {
    opacity: 1;
    pointer-events: auto;
    z-index: 1;
  }

  .pos-pi-slideshow__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* Ancestor-scoped (two classes) so this out-specificities the generic
     `button:not(.btn)` reset below, same trick as `.hero .hero__nav`. */
  .pos-pi-slideshow .pos-pi-slideshow__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 2.75rem;
    height: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.35);
    color: #fff;
    border: none;
    border-radius: 50%;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.15s;
  }

  .pos-pi-slideshow .pos-pi-slideshow__nav:hover {
    background: rgba(0, 0, 0, 0.55);
  }

  .pos-pi-slideshow__nav--prev { left: var(--space-3); }
  .pos-pi-slideshow__nav--next { right: var(--space-3); }

  .pos-pi-slideshow__dots {
    position: absolute;
    bottom: var(--space-3);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    display: flex;
    gap: 0.6rem;
  }

  .pos-pi-slideshow .pos-pi-slideshow__dot {
    width: 0.65rem;
    height: 0.65rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.45);
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
  }

  .pos-pi-slideshow .pos-pi-slideshow__dot.is-active {
    background: var(--color-gold);
    transform: scale(1.3);
  }

  /* SKM Show: photo slideshow below the social row on the Sekolah
     Maranatha page. Same crossfade behavior as .pos-pi-slideshow, but the
     frame keeps a fixed 16:9 aspect ratio instead of a clamped height. */
  .school-show-slideshow {
    margin-top: var(--space-2);
    margin-bottom: var(--space-2);
  }

  @media (min-width: 641px) {
    .school-show-slideshow {
      margin-top: var(--space-4);
      margin-bottom: var(--space-4);
    }
  }

  .school-show-slideshow__frame {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--color-navy-dark);
    border-radius: var(--radius-lg);
  }

  .school-show-slideshow__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    pointer-events: none;
    transition: opacity 1s ease;
  }

  .school-show-slideshow__slide.is-active {
    opacity: 1;
    pointer-events: auto;
    z-index: 1;
  }

  .school-show-slideshow__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .school-show-slideshow .school-show-slideshow__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 2.75rem;
    height: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.35);
    color: #fff;
    border: none;
    border-radius: 50%;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.15s;
  }

  .school-show-slideshow .school-show-slideshow__nav:hover {
    background: rgba(0, 0, 0, 0.55);
  }

  .school-show-slideshow__nav--prev { left: var(--space-3); }
  .school-show-slideshow__nav--next { right: var(--space-3); }

  .school-show-slideshow__dots {
    position: absolute;
    bottom: var(--space-3);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    display: flex;
    gap: 0.6rem;
  }

  .school-show-slideshow .school-show-slideshow__dot {
    width: 0.65rem;
    height: 0.65rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.45);
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
  }

  .school-show-slideshow .school-show-slideshow__dot.is-active {
    background: var(--color-gold);
    transform: scale(1.3);
  }

  /* YouTube embed shown above the poster sections on the POS PI page. */
  .pos-pi-video {
    position: relative;
    aspect-ratio: 16 / 9;
    max-width: 60rem;
    margin: var(--space-4) auto;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--color-navy-dark);
  }

  .pos-pi-video iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
  }

  /* Two manually-uploaded photos (poster_left/poster_right) shown side by
     side below the POS PI slideshow. Either one can be attached alone --
     the grid still lays out correctly with a single column filled. */
  .pos-pi-photo-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
    margin: var(--space-4) 0;
  }

  /* Portrait aspect-ratio (not a viewport-width-driven height) so each
     column stays tall/elongated relative to its own width at any screen
     size -- a wide desktop column doesn't flatten out the way a fixed
     vw-based height would. */
  .pos-pi-photo-grid__image {
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: var(--radius-lg);
  }

  .pos-pi-address {
    margin: var(--space-4) 0;
  }

  @media (min-width: 641px) {
    .pos-pi-address {
      font-size: var(--text-lg);
    }
  }

  /* Sekolah Maranatha page: autoplaying/looping hero video below the header,
     with a title + tagline overlaid on top (dark gradient for legibility
     over the moving footage, mirroring .page-hero's overlay treatment). */
  .school-hero-video {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--color-navy-dark);
  }

  .school-hero-video__video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .school-hero-video__overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(10, 20, 35, 0.35), rgba(10, 20, 35, 0.75));
  }

  .school-hero-video__logo {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    z-index: 1;
    width: 3.5rem;
    height: auto;
    filter: drop-shadow(0 1px 6px rgba(0,0,0,0.6));
  }

  @media (min-width: 641px) {
    .school-hero-video__logo {
      width: 6rem;
    }
  }

  .school-hero-video__content {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    gap: var(--space-1);
    text-align: left;
    padding: var(--space-3);
  }

  .school-hero-video__content h1 {
    color: #fff;
    font-size: clamp(1.5rem, 6vw, 4.5rem);
    margin: 0;
    text-shadow: 0 1px 6px rgba(0,0,0,0.6);
  }

  .school-hero-video__content h2 {
    color: #fff;
    font-size: clamp(1rem, 3.5vw, var(--text-xl));
    font-weight: 400;
    margin: 0;
    text-shadow: 0 1px 6px rgba(0,0,0,0.6);
  }

  @media (min-width: 641px) {
    .school-hero-video__content {
      padding-bottom: 8rem;
    }

    .school-hero-video__content h2 {
      font-size: var(--text-3xl);
    }
  }

  /* Scripture verse centered below the Sekolah Maranatha hero video. */
  .school-verse {
    text-align: center;
    max-width: 42rem;
    padding-bottom: var(--space-2);
  }

  @media (min-width: 641px) {
    .school-verse {
      padding-bottom: var(--space-4);
    }
  }

  .school-verse__zh {
    font-size: clamp(0.7rem, 4vw, var(--text-base));
    font-weight: 600;
    color: var(--color-navy-dark);
    margin: 0 0 var(--space-1);
    white-space: nowrap;
  }

  .school-verse__en {
    font-family: "Quicksand", var(--font-sans);
    font-size: var(--text-sm);
    font-style: italic;
    color: var(--color-ink-light);
    margin: 0;
  }

  .school-verse__en cite {
    font-style: normal;
  }

  .school-verse__social {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    margin-top: var(--space-2);
  }

  .school-verse__social-label {
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--color-navy-dark);
    font-size: var(--text-sm);
  }

  .school-verse__social-link {
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.15s, transform 0.15s;
  }

  .school-verse__social-link:hover {
    opacity: 0.8;
    transform: translateY(-2px);
  }

  .school-verse__social-icon {
    width: 1.75rem;
    height: 1.75rem;
  }

  @media (min-width: 641px) {
    .school-verse__zh {
      font-size: var(--text-xl);
    }

    .school-verse__en {
      font-size: var(--text-lg);
    }
  }

  /* Jenjang Pendidikan timeline: photo left, description right, a dot +
     animated connecting line runs down the middle between levels. */
  .school-levels {
    --school-levels-gap: var(--space-6);
    padding-top: var(--space-2);
  }

  @media (min-width: 641px) {
    .school-levels {
      padding-top: var(--space-4);
    }
  }

  .school-levels__list {
    display: flex;
    flex-direction: column;
    gap: var(--school-levels-gap);
    margin-top: var(--space-3);
  }

  .school-level {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
  }

  .school-level__image-wrap {
    flex: 0 0 6rem;
    width: 6rem;
    aspect-ratio: 4 / 3;
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow-md);
  }

  .school-level__image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .school-level__track {
    position: relative;
    flex: 0 0 auto;
    width: 1rem;
    align-self: stretch;
    display: flex;
    justify-content: center;
  }

  .school-level__dot {
    width: 12px;
    height: 12px;
    margin-top: 0.35rem;
    border-radius: 50%;
    background: var(--color-gold);
    box-shadow: 0 0 0 3px var(--color-gold-light);
    position: relative;
    z-index: 1;
    opacity: 1;
    transform: scale(1);
    transition: opacity 0.4s ease, transform 0.4s ease;
  }

  .school-level__line {
    position: absolute;
    top: 0.85rem;
    bottom: calc(-1 * var(--school-levels-gap));
    left: 50%;
    width: 2px;
    background-color: var(--color-border);
    background-image: repeating-linear-gradient(
      to bottom,
      var(--color-gold) 0,
      var(--color-gold) 8px,
      transparent 8px,
      transparent 16px
    );
    background-size: 100% 16px;
    animation: school-level-line-march 0.8s linear infinite;
    transform: translateX(-50%) scaleY(1);
    transform-origin: top;
    transition: transform 0.8s ease;
  }

  @keyframes school-level-line-march {
    from { background-position-y: 0; }
    to { background-position-y: 16px; }
  }

  /* Without JS, the timeline renders fully visible (progressive
     enhancement). The controller adds .will-animate on connect, which is
     what actually hides items for the scroll-reveal to animate into. */
  .school-level.will-animate .school-level__dot {
    opacity: 0;
    transform: scale(0.4);
  }

  .school-level.will-animate .school-level__line {
    transform: translateX(-50%) scaleY(0);
  }

  .school-level.will-animate.is-visible .school-level__dot {
    opacity: 1;
    transform: scale(1);
  }

  .school-level.will-animate.is-visible .school-level__line {
    transform: translateX(-50%) scaleY(1);
  }

  .school-level__content {
    flex: 1 1 auto;
    min-width: 0;
  }

  .school-level__title {
    margin: 0 0 0.2rem;
    font-size: var(--text-base);
  }

  .school-level__subtitle {
    margin: 0 0 0.4rem;
    font-size: var(--text-xs);
    color: var(--color-ink-light);
  }

  .school-level__desc {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--color-ink-light);
    text-align: justify;
  }

  @media (min-width: 641px) {
    .school-level {
      gap: calc(var(--space-6) * 2);
    }

    .school-level__image-wrap {
      flex-basis: 24rem;
      width: 24rem;
    }

    .school-level__title {
      font-size: var(--text-lg);
    }

    .school-level__subtitle {
      font-size: var(--text-sm);
    }

    .school-level__desc {
      font-size: var(--text-base);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .school-level__dot,
    .school-level__line {
      transition-duration: 0.01ms;
    }

    .school-level__line {
      animation: none;
    }
  }

  .school-whatsapp-heading,
  .school-whatsapp {
    margin-left: 1.5rem;
  }

  .school-whatsapp-heading {
    font-size: var(--text-base);
  }

  @media (min-width: 641px) {
    .school-whatsapp-heading {
      font-size: var(--text-xl);
    }

    .school-whatsapp-heading,
    .school-whatsapp {
      margin-left: 4rem;
    }
  }

  /* WhatsApp number below Jenjang Pendidikan, links out to wa.me. */
  .school-whatsapp__link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--color-ink);
    transition: opacity 0.15s;
  }

  .school-whatsapp__link:hover {
    opacity: 0.75;
  }

  .school-whatsapp__icon {
    width: 1.25rem;
    height: 1.25rem;
    flex-shrink: 0;
  }

  /* Static page banner (e.g. Kontak & Lokasi) -- a shorter, non-slideshow
     sibling of .hero: one fixed image with a dark overlay and a title. */
  .page-hero {
    position: relative;
    height: clamp(110px, 14vw, 170px);
    color: #fff;
    overflow: hidden;
    background: var(--color-navy-dark);
  }

  .page-hero__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .page-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(10, 20, 35, 0.45), rgba(10, 20, 35, 0.8));
  }

  /* Plain banner: a decorative photo/graphic with no CSS-rendered title on
     top of it (e.g. the "Tentang Kami" banner) -- skip the dark overlay so
     it doesn't muddy the image, and crop (not stretch) to fill the short,
     ultra-wide banner without distorting its proportions. */
  .page-hero--plain::after {
    display: none;
  }

  .page-hero--plain .page-hero__image {
    object-fit: cover;
  }

  .page-hero__content {
    position: relative;
    z-index: 1;
    height: 100%;
    display: flex;
    align-items: center;
  }

  .page-hero h1 {
    color: #fff;
    font-size: 2rem;
    margin: 0;
  }

  .page-hero__title--kontak {
    text-transform: uppercase;
  }

  @media (max-width: 640px) {
    .page-hero__title--pos-pi {
      font-size: 1.3rem;
    }

    .page-hero__title--kontak {
      font-size: 1.6rem;
      white-space: nowrap;
    }
  }

  /* Worship schedule poster */
  .schedule-poster {
    margin: var(--space-4) 0;
    text-align: center;
  }

  .schedule-poster__image {
    width: 100%;
    max-width: 60rem;
    margin-inline: auto;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
  }

  /* Homepage CTA banner for the Biodata Jemaat form -- only rendered when
     at least one of the 5 forms is aktif (see PagesController#home). */
  .biodata-banner {
    margin: var(--space-6) 0;
    padding: var(--space-4);
    text-align: center;
    background: #6B21A8;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
  }

  .biodata-banner h2 {
    color: #fff;
    margin-top: 0;
  }

  /* Scales with viewport width so "BIODATA UNTUK GEREJAKU" always fits on
     one line on phones, instead of wrapping at the fixed --text-xl size. */
  @media (max-width: 640px) {
    .biodata-banner h2 {
      font-size: 5.5vw;
      white-space: nowrap;
    }
  }

  .biodata-banner p {
    color: rgba(255, 255, 255, 0.85);
    margin-inline: auto;
  }

  /* Buttons */
  .btn {
    --btn-bg: var(--color-gold);
    --btn-color: var(--color-navy-dark);
    display: inline-flex;
    align-items: center;
    gap: 0.4ch;
    background: var(--btn-bg);
    color: var(--btn-color);
    font-weight: 600;
    font-size: var(--text-sm);
    padding: 0.7em 1.4em;
    border-radius: 999px;
    border: none;
    cursor: pointer;
    transition: filter 0.15s, transform 0.15s;

    @media (any-hover: hover) {
      &:hover {
        filter: brightness(1.08);
        transform: translateY(-1px);
        color: var(--btn-color);
      }
    }
  }

  .btn--sm {
    font-size: var(--text-sm);
    padding: 0.3rem 0.75rem;
  }

  .btn--xs {
    font-size: var(--text-xs);
    padding: 0.2rem 0.5rem;
  }

  .btn--danger {
    --btn-bg: #c0392b;
    --btn-color: #fff;
  }

  .btn--outline {
    --btn-bg: transparent;
    --btn-color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.6);
  }

  input[type="submit"],
  button:not(.btn) {
    display: inline-flex;
    align-items: center;
    background: var(--color-navy);
    color: #fff;
    font-weight: 600;
    font-size: var(--text-sm);
    padding: 0.65em 1.3em;
    border-radius: var(--radius);
    border: none;
    cursor: pointer;
    transition: filter 0.15s;
  }

  input[type="submit"]:hover,
  button:not(.btn):hover {
    filter: brightness(1.15);
  }

  /* Higher specificity than the button:not(.btn) reset above, needed
     since it lives in this same (components) layer and would otherwise
     win regardless of source order. */
  .nav-links .nav-logout-btn {
    display: inline-flex;
    background: none;
    border: 1px solid rgba(255, 255, 255, 0.45);
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--text-sm);
    font-weight: 400;
    padding: 0.25em 0.85em;
    border-radius: 999px;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s;
  }

  .nav-links .nav-logout-btn:hover {
    border-color: var(--color-gold);
    color: var(--color-gold);
    filter: none;
  }

  .nav-links .nav-close {
    display: none;
  }

  @media (max-width: 800px) {
    /* .nav-logout-btn keeps its base (desktop) light-on-dark styling here
       -- the mobile drawer background is sky blue (var(--color-header)),
       same family as the desktop navy header, so no override is needed. */

    /* Overrides the global `form { display: flex; flex-direction: column;
       ... }` reset ("Forms" section further down this same @layer
       components) for the one-button logout form in the mobile drawer
       (see .nav-links form in @layer layout above, where this same
       selector sets margin/text-align -- those aren't contested by the
       reset, only display/width/max-width are, which is why only those
       three live here). Left as `display: flex` on mobile, this tiny form
       becomes a flex container with the default align-items: stretch,
       which both blockifies its only child .nav-logout-btn from
       inline-flex to flex AND stretches it to the form's full width --
       exactly the full-width bar look every other drawer link already
       has, when the point of this button being its own pill is to look
       different from them. */
    .nav-links form {
      display: block;
      width: auto;
      max-width: none;
    }

    .nav-links .nav-close {
      position: absolute;
      top: 0.5rem;
      right: 0.5rem;
      width: 2.5rem;
      height: 2.5rem;
      display: flex;
      align-items: center;
      justify-content: center;
      background: none;
      padding: 0;
      border: none;
      border-radius: 0;
      font-size: 1.75rem;
      font-weight: 400;
      line-height: 1;
      color: rgba(255, 255, 255, 0.85);
      cursor: pointer;
    }

    .nav-links .nav-close:hover {
      color: #fff;
      filter: none;
    }
  }

  .site-nav .nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
    flex-shrink: 0;
  }

  .nav-toggle__bar {
    display: block;
    width: 1.5rem;
    height: 2px;
    background: #fff;
    border-radius: 2px;
    transition: transform 0.2s, opacity 0.2s;
  }

  .nav-toggle.is-open .nav-toggle__bar:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }

  .nav-toggle.is-open .nav-toggle__bar:nth-child(2) {
    opacity: 0;
  }

  .nav-toggle.is-open .nav-toggle__bar:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }

  @media (max-width: 800px) {
    .site-nav .nav-toggle {
      display: flex;
    }
  }

  /* Pengurus in-page nav (the pipe-separated link row under each admin
     page's <h1>, see pengurus/_nav.html.erb): a hamburger toggle on mobile
     only, since the link count varies a lot by role (a few for
     commission_leader/majelis, ~20 for admin) and wraps across several
     cramped lines at narrow widths. Desktop is untouched -- the toggle
     stays hidden and .pengurus-nav__links keeps its normal always-visible
     flow.

     Selectors below are scoped as .pengurus-nav .pengurus-nav-toggle
     (not just .pengurus-nav-toggle), same reasoning as .site-nav
     .nav-toggle above: needs higher specificity than the button:not(.btn)
     reset further down this same layer, or `display: none` loses to the
     reset's `display: inline-flex` and the button stays visibly stuck on
     at every width, desktop included. */
  .pengurus-nav .pengurus-nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 5px;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    background: var(--color-navy-dark);
    border: none;
    border-radius: var(--radius);
    cursor: pointer;
  }

  .pengurus-nav-toggle__bar {
    display: block;
    width: 1.25rem;
    height: 2px;
    background: #fff;
    border-radius: 2px;
    transition: transform 0.2s, opacity 0.2s;
  }

  .pengurus-nav-toggle.is-open .pengurus-nav-toggle__bar:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }

  .pengurus-nav-toggle.is-open .pengurus-nav-toggle__bar:nth-child(2) {
    opacity: 0;
  }

  .pengurus-nav-toggle.is-open .pengurus-nav-toggle__bar:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }

  @media (max-width: 800px) {
    .pengurus-nav .pengurus-nav-toggle {
      display: flex;
      margin-bottom: var(--space-2);
    }

    /* Open/close is animated (see pengurus_nav_controller.js), not an
       instant display:none/block swap: JS measures scrollHeight and drives
       max-height so the panel genuinely expands/collapses, while opacity +
       transform give it a soft pop-in/out. border-color (not border, so
       the 1px width stays constant) and background fade in step with it --
       kept transparent while collapsed so no sliver of red/border shows
       through at max-height: 0. */
    .pengurus-nav__links {
      overflow: hidden;
      max-height: 0;
      opacity: 0;
      transform: translateY(-10px) scale(0.97);
      background: transparent;
      border: 1px solid transparent;
      border-radius: var(--radius);
      padding: 0 var(--space-2);
      margin: 0 0 var(--space-3);
      transition:
        max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1),
        opacity 0.3s ease,
        transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1),
        background 0.3s ease,
        border-color 0.3s ease;
    }

    .pengurus-nav__links.is-open {
      opacity: 1;
      transform: translateY(0) scale(1);
      background: #6e1423;
      border-color: #6e1423;
    }

    /* "|" separators only make sense in the desktop paragraph flow --
       stacking one link per row (below) makes them redundant. */
    .pengurus-nav__links .pengurus-nav__sep {
      display: none;
    }

    /* One link per row, like a drawer/sidebar list, instead of the
       desktop paragraph wrapping several pipe-separated links per line.
       Mobile-only dark-red/white treatment with a decorative serif face
       (Playfair Display, already loaded for headings -- see
       layouts/application.html.erb) so the drawer reads as a distinct
       "menu" surface; desktop keeps the plain sans-serif paragraph flow
       untouched. Each row also fades/slides in with a small stagger (the
       nth-child delays below) so opening the menu reveals its items one
       after another instead of all at once. */
    .pengurus-nav__links a {
      display: block;
      padding: 0.7rem 0.25rem;
      border-bottom: 1px solid rgba(255, 255, 255, 0.25);
      color: #fff;
      font-family: "Playfair Display", var(--font-sans);
      font-weight: 600;
      font-size: 1.05rem;
      opacity: 0;
      transform: translateX(-14px);
      transition: opacity 0.3s ease, transform 0.3s ease, color 0.3s ease;
    }

    .pengurus-nav__links a:hover {
      color: #fff;
    }

    .pengurus-nav__links a:last-child {
      border-bottom: none;
    }

    .pengurus-nav__links.is-open a {
      opacity: 1;
      transform: translateX(0);
    }

    .pengurus-nav__links.is-open a:nth-child(1)  { transition-delay: 0.03s; }
    .pengurus-nav__links.is-open a:nth-child(2)  { transition-delay: 0.06s; }
    .pengurus-nav__links.is-open a:nth-child(3)  { transition-delay: 0.09s; }
    .pengurus-nav__links.is-open a:nth-child(4)  { transition-delay: 0.12s; }
    .pengurus-nav__links.is-open a:nth-child(5)  { transition-delay: 0.15s; }
    .pengurus-nav__links.is-open a:nth-child(6)  { transition-delay: 0.18s; }
    .pengurus-nav__links.is-open a:nth-child(7)  { transition-delay: 0.21s; }
    .pengurus-nav__links.is-open a:nth-child(8)  { transition-delay: 0.24s; }
    .pengurus-nav__links.is-open a:nth-child(9)  { transition-delay: 0.27s; }
    .pengurus-nav__links.is-open a:nth-child(10) { transition-delay: 0.3s; }
    .pengurus-nav__links.is-open a:nth-child(11) { transition-delay: 0.33s; }
    .pengurus-nav__links.is-open a:nth-child(12) { transition-delay: 0.36s; }
    .pengurus-nav__links.is-open a:nth-child(13) { transition-delay: 0.39s; }
    .pengurus-nav__links.is-open a:nth-child(14) { transition-delay: 0.42s; }
    .pengurus-nav__links.is-open a:nth-child(15) { transition-delay: 0.45s; }
    .pengurus-nav__links.is-open a:nth-child(16) { transition-delay: 0.48s; }
    .pengurus-nav__links.is-open a:nth-child(17) { transition-delay: 0.51s; }
    .pengurus-nav__links.is-open a:nth-child(18) { transition-delay: 0.54s; }
    .pengurus-nav__links.is-open a:nth-child(19) { transition-delay: 0.57s; }
    .pengurus-nav__links.is-open a:nth-child(20) { transition-delay: 0.6s; }
  }

  /* Weekly media row: 2 YouTube embeds + 1 photo, left/center/right */
  .media-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3);
    margin: var(--space-4) 0;
  }

  @media (max-width: 760px) {
    .media-grid {
      grid-template-columns: 1fr;
    }
  }

  /* Scripture verse below the homepage media row -- Chinese + English,
     same bilingual verse pattern as .school-verse but wraps onto multiple
     lines since this verse runs much longer. */
  .home-verse {
    text-align: center;
    max-width: 42rem;
    margin: 0 auto var(--space-4);
  }

  /* Override the global p { max-width: 70ch } cap (application.css:108) --
     without this, .home-verse__en (a <p>) is narrower than its Chinese
     sibling and its centering visibly drifts off the shared center. */
  .home-verse p {
    max-width: none;
  }

  .home-verse__zh {
    font-size: clamp(0.85rem, 4vw, var(--text-lg));
    font-weight: 600;
    color: var(--color-navy-dark);
    margin: 0 0 var(--space-1);
  }

  .home-verse__en {
    font-family: "Quicksand", var(--font-sans);
    font-size: var(--text-sm);
    font-style: italic;
    color: var(--color-ink-light);
    margin: 0;
  }

  .home-verse__citation {
    display: block;
    text-align: right;
    font-style: normal;
    margin-top: var(--space-1);
  }

  @media (min-width: 641px) {
    .home-verse {
      max-width: 60rem;
    }

    .home-verse__zh {
      font-size: var(--text-xl);
      white-space: nowrap;
    }

    .home-verse__en {
      font-size: var(--text-lg);
    }
  }

  .media-card {
    background: var(--color-canvas);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-2);
    box-shadow: var(--shadow-sm);
  }

  .media-card__embed {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--color-navy-dark);
  }

  .media-card__embed iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
  }

  .media-card__image {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: var(--radius);
  }

  .media-card__slideshow {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--color-navy-dark);
  }

  .media-card__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 0.6s ease;
  }

  .media-card__slide.is-active {
    opacity: 1;
  }

  .media-card__slide .media-card__image {
    width: 100%;
    height: 100%;
    aspect-ratio: unset;
    border-radius: 0;
  }

  .media-card__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0,0,0,0.45);
    color: #fff;
    border: none;
    cursor: pointer;
    font-size: 1.5rem;
    line-height: 1;
    padding: 0.3rem 0.55rem;
    border-radius: var(--radius);
    z-index: 2;
    opacity: 0;
    transition: opacity 0.2s;
  }

  .media-card__slideshow:hover .media-card__nav {
    opacity: 1;
  }

  .media-card__nav--prev { left: 0.5rem; }
  .media-card__nav--next { right: 0.5rem; }

  .media-card__dots {
    position: absolute;
    bottom: 0.5rem;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 0.4rem;
    z-index: 2;
  }

  .media-card__dot {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: rgba(255,255,255,0.5);
    border: none;
    cursor: pointer;
    padding: 0;
    transition: background 0.2s;
  }

  .media-card__dot.is-active {
    background: #fff;
  }

  .media-card__empty {
    aspect-ratio: 16 / 9;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-canvas-subtle);
    border-radius: var(--radius);
    color: var(--color-ink-light);
    margin: 0;
  }

  /* Titles are admin-entered (HomepageHighlight#title) and can run long --
     e.g. a full Chinese verse like "殷勤不可懶惰。要心裡火熱，常常服事主。"
     (19 characters, each roughly 1em wide) barely overflows the ~317px
     card width at the old var(--text-base) (1.05rem/16.8px), wrapping the
     last character or two onto their own line. clamp() shrinks it just
     enough to fit that line at typical card widths (desktop's 3-column
     grid is the tight case -- mobile's single-column cards are wider, so
     they have even more headroom) without needing white-space: nowrap,
     which would just overflow instead of wrap for longer non-CJK titles
     like "Jalani Harimu Bersama dengan Yesus". */
  .media-card h3 {
    margin: var(--space-2) 0 0.25rem;
    font-size: clamp(0.85rem, 2.6vw, 0.95rem);
  }

  .media-card p {
    margin: 0;
    font-size: var(--text-sm);
  }

  /* Poster grid — portrait poster display on jadwal & commission pages */
  .poster-grid {
    list-style: none;
    padding: 0;
    margin: var(--space-2) 0 0;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-3);
  }

  .poster-grid__img {
    width: 100%;
    height: auto;
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    display: block;
  }

  /* Video posters, rendered below .poster-grid (see commissions/show.html.erb)
     rather than mixed into it -- a 16:9 embed doesn't fit the grid's
     portrait poster cells. One per row since a video needs real width to
     be watchable, unlike the 2-up poster thumbnails above it. */
  .poster-video-list {
    list-style: none;
    padding: 0;
    margin: var(--space-3) 0 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }

  /* Poster admin grid — smaller thumbnails with delete button */
  .poster-admin-grid {
    list-style: none;
    padding: 0;
    margin: var(--space-2) 0 0;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-3);
  }

  .poster-admin-grid__img {
    width: 100%;
    height: auto;
    border-radius: var(--radius);
    display: block;
  }

  /* Video posters (Poster#kind: video) render an embed here instead of
     .poster-admin-grid__img -- same 16:9 box + absolutely-positioned
     iframe pattern as .media-card__embed. */
  .poster-admin-grid__embed {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--color-navy-dark);
  }

  .poster-admin-grid__embed iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: none;
  }

  .poster-admin-grid__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.35rem;
    font-size: var(--text-xs);
    color: var(--color-ink-light);
  }

  /* Photo grid — 3-column gallery used on commission & galeri pages */
  .photo-grid {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-2);
  }

  /* Galeri page only -- narrower 2-column layout instead of the shared 3-column default. */
  .photo-grid--2col {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Komisi page only -- 1 column on mobile instead of the shared 3-column default. */
  @media (max-width: 640px) {
    .photo-grid--commission {
      grid-template-columns: 1fr;
    }

    .poster-grid--commission {
      grid-template-columns: 1fr;
    }
  }

  .photo-grid__item {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
  }

  .photo-grid__img {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: var(--radius);
  }

  .photo-grid__caption {
    margin: 0;
    font-size: var(--text-xs);
    color: var(--color-ink-light);
    text-align: center;
  }

  /* Cards */
  .card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: var(--space-3);
    margin: var(--space-3) 0 0;
    list-style: none;
    padding: 0;
  }

  .card {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    background: var(--color-canvas);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-3);
    box-shadow: var(--shadow-sm);
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
  }

  a.card {
    color: var(--color-ink);
  }

  .card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-md);
    border-color: var(--color-gold);
  }

  .card__icon {
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    background: color-mix(in oklch, var(--color-gold) 18%, white);
    color: var(--color-navy);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--space-1);
  }

  .card__icon svg {
    width: 1.5rem;
    height: 1.5rem;
  }

  .card h3 {
    margin: 0;
    font-size: var(--text-base);
    color: var(--color-navy-dark);
  }

  /* Forms */
  form {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    max-width: 28rem;
  }

  .form-preview-thumb {
    max-width: 12rem;
    border-radius: var(--radius);
  }

  label {
    display: block;
    font-weight: 600;
    font-size: var(--text-sm);
    color: var(--color-ink);
  }

  input, select, textarea {
    font: inherit;
    padding: 0.65em 0.85em;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-canvas);
    color: var(--color-ink);
  }

  input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--color-gold);
    outline-offset: 1px;
    border-color: var(--color-gold);
  }

  /* Password field with a "show password" eye toggle button overlaid on
     the right edge of the input. */
  .password-field {
    position: relative;
    display: inline-block;
  }

  .password-field input {
    width: 100%;
    padding-right: 2.5em;
  }

  button.password-field__toggle {
    position: absolute;
    inset-block: 0;
    right: 0.15em;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2em;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--color-ink-light);
    cursor: pointer;
  }

  button.password-field__toggle:hover {
    filter: none;
    color: var(--color-ink);
  }

  .password-field__icon {
    width: 1.2em;
    height: 1.2em;
  }

  .password-field__icon--hide {
    display: none;
  }

  .password-field__toggle.is-visible .password-field__icon--show {
    display: none;
  }

  .password-field__toggle.is-visible .password-field__icon--hide {
    display: block;
  }

  /* Public registration form headings ("Pendaftaran Calon Baptisan",
     "Pendaftaran Penyerahan Anak"): uppercase at every width, but the
     global h1 size (clamp(2rem, 4vw, 2.75rem)) wraps these long phrases
     onto two lines on phones, so mobile gets its own smaller size that
     scales with viewport width to stay on one line down to narrow phones. */
  .form-pendaftaran-title {
    text-transform: uppercase;
  }

  @media (max-width: 640px) {
    .form-pendaftaran-title {
      font-size: clamp(1rem, 5vw, 1.6rem);
      white-space: nowrap;
    }
  }

  /* Tables */
  table {
    width: 100%;
    border-collapse: collapse;
    margin-block: var(--space-3);
    font-size: var(--text-sm);
  }

  th, td {
    text-align: left;
    padding: var(--space-1) var(--space-2);
    border-bottom: 1px solid var(--color-border);
  }

  th {
    color: var(--color-navy-dark);
    font-weight: 700;
    background: var(--color-canvas-subtle);
  }

  /* Title heading on each commission's detail page (Komisi Anak, Remaja, etc.) */
  .commission-title {
    text-transform: uppercase;
  }

  /* Description paragraph on each commission's detail page. */
  .commission-description {
    font-family: "Quicksand", var(--font-sans);
  }

  /* Facebook/Instagram/YouTube/TikTok icons on a commission's detail page
     (currently only Komisi Pemuda and Komisi Remaja have any URLs filled
     in, see CommissionSocialLink). */
  .commission-social {
    display: flex;
    align-items: center;
    gap: var(--space-2);
  }

  .commission-social__link {
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.15s, transform 0.15s;
  }

  .commission-social__link:hover {
    opacity: 0.8;
    transform: translateY(-2px);
  }

  .commission-social__icon {
    width: 1.75rem;
    height: 1.75rem;
  }

  @media (min-width: 641px) {
    .commission-description {
      font-size: var(--text-lg);
    }
  }

  /* Row pairing the commission's cover image with its description.
     Mobile: image floats left at its natural size so text wraps tightly
     around it. Desktop: switches to a stretched two-column layout. */
  .commission-description-row::after {
    content: "";
    display: block;
    clear: both;
  }

  .commission-description-row__image {
    float: left;
    width: 6.4rem;
    height: auto;
    margin-right: var(--space-3);
    margin-bottom: var(--space-2);
    border-radius: var(--radius-lg);
    object-fit: contain;
  }

  @media (min-width: 641px) {
    .commission-description-row {
      display: flex;
      flex-direction: row;
      align-items: stretch;
      gap: var(--space-4);
    }

    .commission-description-row__image {
      float: none;
      flex: 0 0 6.4rem;
      width: 6.4rem;
      height: auto;
      margin: 0;
      object-fit: contain;
    }
  }

  /* Commission cards: 2×2 photo grid on Komisi & Pelayanan page */
  .commission-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-3);
    margin: var(--space-4) 0;
  }

  @media (max-width: 640px) {
    .commission-grid {
      grid-template-columns: 1fr;
    }
  }

  .commission-card {
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: var(--radius-lg);
    aspect-ratio: 4 / 3;
    background: var(--color-navy);
    text-decoration: none;
  }

  .commission-card--no-image {
    background: linear-gradient(135deg, var(--color-navy) 0%, var(--color-navy-dark) 100%);
  }

  .commission-card__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform 0.4s ease;
  }

  .commission-card:hover .commission-card__image {
    transform: scale(1.06);
  }

  .commission-card__overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(0,0,0,0.72) 0%, rgba(0,0,0,0.12) 55%, transparent 100%);
  }

  .commission-card__heading {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--space-3);
    color: #fff;
    font-size: var(--text-2xl);
    text-shadow: 0 1px 6px rgba(0,0,0,0.6);
    pointer-events: none;
  }

  .commission-card__body {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: var(--space-3);
    z-index: 1;
  }

  .commission-card__name {
    color: #fff;
    font-size: var(--text-lg);
    margin: 0 0 var(--space-2);
    text-shadow: 0 1px 4px rgba(0,0,0,0.5);
  }

  .commission-card__btn {
    display: inline-block;
    background: var(--color-gold);
    color: var(--color-navy-dark);
    font-weight: 700;
    font-size: var(--text-xs);
    letter-spacing: 0.07em;
    text-transform: uppercase;
    padding: 0.5em 1.4em;
    border-radius: 999px;
    transition: filter 0.15s;
  }

  .commission-card:hover .commission-card__btn {
    filter: brightness(1.1);
  }

  /* Hub cards: 3 tall portrait cards on homepage menu */
  .hub-card-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3);
    margin: var(--space-4) 0;
  }

  @media (max-width: 640px) {
    .hub-card-grid {
      grid-template-columns: 1fr;
    }
  }

  .hub-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    overflow: hidden;
    border-radius: var(--radius-lg);
    aspect-ratio: 3 / 4;
    text-decoration: none;
    color: #fff;
  }

  @media (max-width: 640px) {
    .hub-card {
      aspect-ratio: 16 / 9;
    }

    /* The 16:9 box is too short for the title+preview+button stack
       designed for the taller 3:4 card -- trim it down so nothing
       overflows. Preview is hover-only anyway, so drop it on touch. */
    .hub-card__center {
      flex: 0 0 auto;
      padding-bottom: var(--space-1);
    }

    .hub-card__title {
      font-size: var(--text-base);
      margin-bottom: 0;
    }

    .hub-card__preview {
      display: none;
    }

    .hub-card__footer {
      padding: var(--space-1) var(--space-2) var(--space-2);
    }

    .hub-card__btn {
      font-size: var(--text-xs);
      padding: 0.3em 1.2em;
    }
  }

  .hub-card--commissions { background: linear-gradient(160deg, #1a4a7a 0%, #0a1e38 100%); }
  .hub-card--galeri      { background: linear-gradient(160deg, #1a3d4a 0%, #0a1e28 100%); }
  .hub-card--pos_pi      { background: linear-gradient(160deg, #4a3a1a 0%, #28200a 100%); }

  .hub-card__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform 0.45s ease;
  }

  .hub-card:hover .hub-card__image {
    transform: scale(1.05);
  }

  .hub-card__overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(
      to top,
      rgba(0,0,0,0.80) 0%,
      rgba(0,0,0,0.25) 50%,
      rgba(0,0,0,0.08) 100%
    );
    transition: background 0.35s ease;
  }

  .hub-card:hover .hub-card__overlay {
    background: linear-gradient(
      to top,
      rgba(0,0,0,0.88) 0%,
      rgba(0,0,0,0.55) 60%,
      rgba(0,0,0,0.20) 100%
    );
  }

  .hub-card__center {
    position: relative;
    z-index: 1;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    padding: 0 var(--space-3) var(--space-2);
    text-align: center;
    width: 100%;
  }

  .hub-card__title {
    color: #fff;
    font-size: var(--text-xl);
    margin: 0 0 var(--space-1);
    text-shadow: 0 2px 10px rgba(0,0,0,0.7);
    transition: transform 0.35s ease;
  }

  .hub-card__title-text--default {
    display: none;
  }

  .hub-card:hover .hub-card__title {
    transform: translateY(-8px);
  }

  .hub-card__preview {
    color: rgba(255,255,255,0.90);
    font-size: var(--text-sm);
    margin: 0;
    max-width: 22ch;
    line-height: 1.55;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.35s ease 0.05s, transform 0.35s ease 0.05s;
  }

  .hub-card:hover .hub-card__preview {
    opacity: 1;
    transform: translateY(-8px);
  }

  .hub-card__footer {
    position: relative;
    z-index: 1;
    width: 100%;
    display: flex;
    justify-content: center;
    padding: var(--space-2) var(--space-3);
    transition: transform 0.35s ease;
  }

  .hub-card:hover .hub-card__footer {
    transform: translateY(-8px);
  }

  .hub-card__btn {
    display: inline-block;
    background: rgba(255,255,255,0.92);
    color: var(--color-navy-dark);
    font-weight: 600;
    font-size: var(--text-sm);
    padding: 0.4em 1.6em;
    border-radius: 999px;
    transition: background 0.15s;
  }

  .hub-card:hover .hub-card__btn {
    background: #fff;
  }

  /* Pastor slideshow: circular photo cards above footer */
  .pastor-section {
    padding: var(--space-6) 0 var(--space-4);
    text-align: center;
  }

  .pastor-section__heading {
    margin-bottom: var(--space-4);
    color: var(--color-navy-dark);
  }

  .pastor-slider {
    overflow: hidden;
  }

  .pastor-track {
    display: flex;
    gap: 2rem;
    transition: transform 0.4s ease;
    align-items: flex-start;
  }

  .pastor-card {
    flex: 0 0 calc((100% - 4rem) / 3);
    min-width: calc((100% - 4rem) / 3);
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 var(--space-3) var(--space-3);
    text-align: center;
  }

  @media (max-width: 639px) {
    .pastor-track {
      gap: 1rem;
    }

    .pastor-card {
      flex: 0 0 calc((100% - 1rem) / 2);
      min-width: calc((100% - 1rem) / 2);
      padding: 0 0.5rem var(--space-2);
    }

    .pastor-card__photo-wrap {
      width: 6.5rem;
      height: 6.5rem;
      border-width: 2px;
      margin-bottom: 0.75rem;
    }

    .pastor-card__name {
      font-size: 0.95rem;
      line-height: 1.25;
    }

    .pastor-card__desc {
      font-size: 0.75rem;
      max-width: 16ch;
      line-height: 1.4;
    }

    .pastor-card__divider {
      width: 2rem;
      margin-top: var(--space-1);
    }
  }

  .pastor-card__photo-wrap {
    width: 9rem;
    height: 9rem;
    border-radius: 50%;
    overflow: hidden;
    margin-bottom: var(--space-3);
    box-shadow: var(--shadow-md);
    border: 3px solid var(--color-gold-light);
  }

  .pastor-card__photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    display: block;
  }

  .pastor-card__photo--placeholder {
    background: var(--color-canvas-subtle);
  }

  .pastor-card__name {
    color: var(--color-navy-dark);
    font-size: var(--text-lg);
    margin: 0 0 var(--space-1);
  }

  .pastor-card__desc {
    color: var(--color-ink-light);
    font-size: var(--text-sm);
    margin: 0;
    max-width: 26ch;
    line-height: 1.6;
  }

  .pastor-card__divider {
    width: 3rem;
    height: 2px;
    background: var(--color-border);
    margin-top: var(--space-3);
  }

  .pastor-nav {
    display: flex;
    justify-content: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
  }

  .pastor-nav__btn {
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-canvas);
    color: var(--color-navy);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.15s, background 0.15s;
  }

  .pastor-nav__btn:hover:not(:disabled) {
    border-color: var(--color-gold);
    background: color-mix(in oklch, var(--color-gold) 10%, white);
  }

  .pastor-nav__btn:disabled {
    opacity: 0.35;
    cursor: default;
  }

  /* Flash messages */
  .flash {
    padding: var(--space-2);
    border-radius: var(--radius);
    margin-bottom: var(--space-2);
    font-size: var(--text-sm);
    max-width: 28rem;
  }

  .flash--alert {
    background: var(--color-negative-bg);
    color: var(--color-negative-ink);
  }

  .flash--notice {
    background: var(--color-positive-bg);
    color: var(--color-positive-ink);
  }

  /* ── Meeting Notes – Notion-like workspace ───────────────────── */

  .mn-workspace {
    display: flex;
    align-items: flex-start;
    min-height: calc(100dvh - 4.75rem);
    background: #fff;
  }

  /* Sidebar */
  .mn-sidebar {
    width: 230px;
    flex-shrink: 0;
    background: #f7f7f5;
    border-right: 1px solid #e9e9e7;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 4.75rem;
    height: calc(100dvh - 4.75rem);
    overflow-y: auto;
  }

  .mn-sidebar__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 1.25rem 1rem 1rem;
    font-weight: 700;
    font-size: 0.8rem;
    color: #37352f;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border-bottom: 1px solid #e9e9e7;
  }

  .mn-sidebar__close {
    display: none;
    font-size: 1.5rem;
    line-height: 1;
    color: #9b9a97;
    background: none;
    border: none;
    cursor: pointer;
    text-transform: none;
  }

  /* Off-canvas drawer toggle (mobile only, see @media (max-width: 800px)
     below): a floating button so the sidebar can be reopened from any of
     the 4 meeting-notes views (index/show/edit/new), not just the ones
     with their own header row.

     Scoped as `.mn-workspace .mn-sidebar-toggle` (not just
     `.mn-sidebar-toggle`) for the same reason as `.pengurus-nav
     .pengurus-nav-toggle` above: needs higher specificity than the
     `button:not(.btn)` reset in this same layer, or `display: none` loses
     and the button stays visibly stuck on at every width, desktop
     included. */
  .mn-workspace .mn-sidebar-toggle {
    display: none;
    position: fixed;
    left: 1rem;
    bottom: 1.25rem;
    z-index: 30;
    width: 3rem;
    height: 3rem;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    border: none;
    border-radius: 999px;
    background: var(--color-navy-dark);
    box-shadow: var(--shadow-md);
    cursor: pointer;
  }

  .mn-sidebar-toggle__bar {
    display: block;
    width: 1.25rem;
    height: 2px;
    background: #fff;
    border-radius: 2px;
  }

  .mn-sidebar-overlay {
    display: none;
  }

  .mn-sidebar__nav {
    flex: 1;
    padding: 0.75rem 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 2px;
  }

  .mn-sidebar__item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.75rem;
    font-size: 0.875rem;
    color: #37352f;
    border-radius: 5px;
    transition: background 0.1s;
    text-decoration: none;
    cursor: pointer;
  }

  .mn-sidebar__item:hover {
    background: rgba(55, 53, 47, 0.08);
    color: #37352f;
  }

  .mn-sidebar__item.is-active {
    background: rgba(55, 53, 47, 0.11);
    font-weight: 600;
    color: #37352f;
  }

  .mn-sidebar__icon {
    font-size: 1rem;
    flex-shrink: 0;
  }

  .mn-sidebar__footer {
    padding: 0.75rem 1rem;
    border-top: 1px solid #e9e9e7;
  }

  .mn-sidebar__back {
    font-size: 0.775rem;
    color: #9b9a97;
    display: block;
    padding: 0.3rem 0;
    transition: color 0.1s;
  }

  .mn-sidebar__back:hover {
    color: #37352f;
  }

  @media (max-width: 800px) {
    .mn-sidebar {
      position: fixed;
      inset-block: 0;
      left: 0;
      top: 0;
      width: min(80vw, 280px);
      height: 100dvh;
      box-shadow: 2px 0 16px rgba(0, 0, 0, 0.2);
      transform: translateX(-100%);
      transition: transform 0.25s ease;
      z-index: 40;
    }

    .mn-sidebar.is-open {
      transform: translateX(0);
    }

    .mn-sidebar__close {
      display: block;
    }

    .mn-workspace .mn-sidebar-toggle {
      display: flex;
    }

    .mn-sidebar-overlay {
      display: block;
      position: fixed;
      inset: 0;
      background: rgba(0, 0, 0, 0.45);
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.2s;
      z-index: 35;
    }

    .mn-sidebar-overlay.is-open {
      opacity: 1;
      pointer-events: auto;
    }
  }

  /* Main content */
  .mn-main {
    flex: 1;
    padding: 2.5rem 3rem;
    min-width: 0;
  }

  .mn-main__header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 2rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid #e9e9e7;
  }

  .mn-page-icon {
    font-size: 2.25rem;
    line-height: 1;
    margin-bottom: 0.4rem;
  }

  .mn-main__title {
    font-size: 1.85rem;
    font-weight: 700;
    color: #37352f;
    margin: 0;
    line-height: 1.2;
  }

  .mn-main__subtitle {
    font-size: 0.825rem;
    color: #9b9a97;
    margin: 0.25rem 0 0;
  }

  /* Note list */
  .mn-notes {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    align-items: start;
  }

  @media (max-width: 900px) {
    .mn-notes { grid-template-columns: repeat(2, 1fr); }
  }

  @media (max-width: 560px) {
    .mn-notes { grid-template-columns: 1fr; }
  }

  .mn-note-card {
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid #e9e9e7;
    border-radius: 8px;
    padding: 1.1rem 1.15rem 0.9rem;
    transition: box-shadow 0.15s, border-color 0.15s;
    min-height: 140px;
  }

  .mn-note-card:hover {
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
    border-color: #d4d4d2;
  }

  .mn-note-card__date {
    font-size: 0.7rem;
    font-weight: 600;
    color: #9b9a97;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 0.55rem;
  }

  .mn-note-card__link {
    display: block;
    flex: 1;
    text-decoration: none;
    color: inherit;
  }

  .mn-note-card__preview {
    font-size: 0.85rem;
    color: #37352f;
    line-height: 1.6;
    display: -webkit-box;
    -webkit-line-clamp: 5;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0;
  }

  .mn-note-card__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.9rem;
    padding-top: 0.65rem;
    border-top: 1px solid #f0f0ef;
    min-height: 1.75rem;
  }

  .mn-note-card__actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
  }

  /* Inline any button_to <form> elements inside the workspace */
  .mn-note-card__actions form,
  .mn-form__actions form,
  .mn-note-view form {
    display: contents;
    max-width: none;
    gap: 0;
  }

  .mn-action-link {
    font-size: 0.775rem;
    color: #6b6b6b;
    padding: 0.25rem 0.6rem;
    border-radius: 4px;
    transition: background 0.1s;
    text-decoration: none;
    display: inline-block;
  }

  .mn-action-link:hover {
    background: rgba(55, 53, 47, 0.08);
    color: #37352f;
  }

  .mn-action-delete-btn {
    font-size: 0.775rem;
    color: #9b1c1c;
    padding: 0.25rem 0.6rem;
    border-radius: 4px;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    font-weight: 400;
    transition: background 0.1s;
    line-height: 1.4;
  }

  .mn-action-delete-btn:hover {
    background: #fdecec;
    filter: none;
  }

  /* Empty state */
  .mn-empty {
    text-align: center;
    padding: 5rem 2rem;
    color: #9b9a97;
  }

  .mn-empty__icon {
    font-size: 3rem;
    margin-bottom: 1rem;
  }

  .mn-empty p {
    color: #9b9a97;
    margin-bottom: 1.5rem;
    max-width: none;
  }

  /* Note show page */
  .mn-note-view {
    flex: 1;
    padding: 2.5rem 3rem;
    min-width: 0;
    max-width: 760px;
  }

  .mn-note-view__back {
    display: inline-flex;
    align-items: center;
    font-size: 0.825rem;
    color: #9b9a97;
    margin-bottom: 2rem;
    text-decoration: none;
    transition: color 0.1s;
  }

  .mn-note-view__back:hover {
    color: #37352f;
  }

  .mn-note-view__meta {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
  }

  .mn-note-view__date {
    font-size: 0.825rem;
    color: #9b9a97;
    background: #f0f0ef;
    padding: 0.25rem 0.75rem;
    border-radius: 999px;
  }

  .mn-note-view__category {
    font-size: 0.7rem;
    color: #6b6b6b;
    background: #eeeef0;
    padding: 0.25rem 0.75rem;
    border-radius: 999px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
  }

  .mn-note-view__title {
    font-size: 2rem;
    font-weight: 700;
    color: #37352f;
    margin: 0 0 2rem;
    line-height: 1.25;
  }

  .mn-note-view__content {
    font-size: 1rem;
    color: #37352f;
    line-height: 1.85;
    white-space: pre-wrap;
    margin-bottom: 2rem;
  }

  /* Form wrapper */
  .mn-form-wrapper {
    flex: 1;
    padding: 2.5rem 3rem;
    min-width: 0;
    max-width: 760px;
  }

  .mn-form-back {
    display: inline-flex;
    align-items: center;
    font-size: 0.825rem;
    color: #9b9a97;
    margin-bottom: 2rem;
    text-decoration: none;
    transition: color 0.1s;
  }

  .mn-form-back:hover {
    color: #37352f;
  }

  .mn-form-header {
    margin-bottom: 1.5rem;
  }

  .mn-form-header__label {
    font-size: 0.8rem;
    color: #9b9a97;
    margin: 0.25rem 0 0;
  }

  @media (max-width: 800px) {
    .mn-main,
    .mn-note-view,
    .mn-form-wrapper {
      padding: 1.5rem 1rem 5rem;
    }
  }

  /* Notion-like form fields */
  .mn-form {
    display: flex;
    flex-direction: column;
    max-width: 100%;
    gap: 0;
  }

  .mn-form__date-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
  }

  .mn-form__date-label {
    font-size: 0.825rem;
    color: #9b9a97;
    font-weight: 400;
    flex-shrink: 0;
  }

  .mn-form__date-input {
    font-size: 0.875rem;
    color: #37352f;
    border: 1px solid #e9e9e7;
    background: #f7f7f5;
    padding: 0.35em 0.75em;
    border-radius: 5px;
    font-family: inherit;
  }

  .mn-form__date-input:focus {
    outline: 2px solid var(--color-gold);
    outline-offset: 1px;
    border-color: var(--color-gold);
  }

  .mn-form__title-input {
    font-size: 2rem;
    font-weight: 700;
    color: #37352f;
    border: none;
    outline: none;
    padding: 0.1rem 0;
    margin-bottom: 1rem;
    line-height: 1.25;
    background: transparent;
    width: 100%;
    font-family: inherit;
  }

  .mn-form__title-input::placeholder {
    color: #c4c3c1;
  }

  .mn-form__title-input:focus {
    outline: none;
    box-shadow: none;
    border-color: transparent;
  }

  .mn-form__divider {
    height: 1px;
    background: #e9e9e7;
    margin: 1.25rem 0;
  }

  .mn-form__content-input {
    font-size: 1rem;
    color: #37352f;
    border: none;
    outline: none;
    padding: 0;
    line-height: 1.85;
    background: transparent;
    width: 100%;
    resize: none;
    min-height: 420px;
    font-family: inherit;
  }

  .mn-form__content-input::placeholder {
    color: #c4c3c1;
  }

  .mn-form__content-input:focus {
    outline: none;
    box-shadow: none;
    border-color: transparent;
  }

  .mn-form__actions {
    display: flex;
    gap: 0.75rem;
    align-items: center;
  }

  /* Image upload section in form */
  .mn-form__images-section {
    margin-bottom: 0.5rem;
  }

  .mn-form__images-label {
    font-size: 0.825rem;
    color: #9b9a97;
    margin: 0 0 0.85rem;
  }

  .mn-form__file-input {
    display: block;
    font-size: 0.875rem;
    color: #37352f;
    border: 1.5px dashed #c4c3c1;
    border-radius: 6px;
    padding: 0.75rem 1rem;
    width: 100%;
    cursor: pointer;
    background: #fafaf9;
    transition: border-color 0.15s;
  }

  .mn-form__file-input:hover {
    border-color: #9b9a97;
  }

  .mn-form__file-input:focus {
    outline: 2px solid var(--color-gold);
    outline-offset: 1px;
    border-color: var(--color-gold);
  }

  .mn-form__file-hint {
    font-size: 0.75rem;
    color: #c4c3c1;
    margin: 0.4rem 0 0;
  }

  /* Image grid — used in form (edit/new) and show page */
  /* Grid di form (edit/new) — thumbnail kecil persegi */
  .mn-images-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 0.75rem;
    margin-bottom: 1rem;
  }

  .mn-image-item {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }

  .mn-image-thumb {
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid #e9e9e7;
    display: block;
  }

  /* Grid di halaman detail — gambar besar, tampil penuh */
  .mn-images-grid--view {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.85rem;
    margin-top: 1.75rem;
    margin-bottom: 1.75rem;
  }

  .mn-images-grid--view .mn-image-item {
    gap: 0;
  }

  .mn-images-grid--view .mn-image-thumb {
    aspect-ratio: unset;
    width: 100%;
    height: auto;
    max-height: 480px;
    object-fit: contain;
    background: #f7f7f6;
    border-radius: 8px;
    border: 1px solid #e9e9e7;
    transition: opacity 0.15s;
  }

  .mn-images-grid--view .mn-image-item a:hover .mn-image-thumb {
    opacity: 0.88;
  }

  /* Jika hanya 1 gambar: tampilkan full lebar */
  .mn-images-grid--view:has(.mn-image-item:only-child) {
    grid-template-columns: 1fr;
  }

  .mn-images-grid--view:has(.mn-image-item:only-child) .mn-image-thumb {
    max-height: 600px;
  }

  .mn-image-remove {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    color: #9b1c1c;
    cursor: pointer;
    user-select: none;
  }

  .mn-image-remove input[type="checkbox"] {
    accent-color: #c0392b;
    width: 14px;
    height: 14px;
    padding: 0;
    border: none;
    border-radius: 3px;
  }

  /* Photo badge on note card in index */
  .mn-note-card__img-badge {
    font-size: 0.7rem;
    color: #9b9a97;
    margin-top: 0.25rem;
  }

  /* ── Trix / Action Text: Notion-like overrides ── */

  /* Toolbar: hide buttons not relevant for meeting notes */
  .mn-form trix-toolbar .trix-button--icon-strike,
  .mn-form trix-toolbar .trix-button--icon-quote,
  .mn-form trix-toolbar .trix-button--icon-heading-1,
  .mn-form trix-toolbar .trix-button--icon-code,
  .mn-form trix-toolbar .trix-button--icon-attach,
  .mn-form trix-toolbar .trix-button--icon-undo,
  .mn-form trix-toolbar .trix-button--icon-redo {
    display: none;
  }

  .mn-form trix-toolbar {
    padding: 0 0 0.6rem;
    border-bottom: 1px solid #e9e9e7;
    margin-bottom: 1rem;
  }

  .mn-form trix-toolbar .trix-button-group {
    border: none;
    border-radius: 5px;
    background: #f1f1ef;
    margin-bottom: 0;
    padding: 2px;
    gap: 1px;
  }

  .mn-form trix-toolbar .trix-button {
    border-bottom: none;
    border-radius: 4px;
    height: 1.75rem;
    width: 1.75rem;
    color: #787774;
    padding: 0;
    transition: background 0.1s, color 0.1s;
  }

  .mn-form trix-toolbar .trix-button:not(:first-child) {
    border-left: none;
  }

  .mn-form trix-toolbar .trix-button:hover {
    background: #e3e3e0;
    color: #37352f;
  }

  .mn-form trix-toolbar .trix-button.trix-active {
    background: #e3e3e0;
    color: #37352f;
  }

  /* Editor area */
  trix-editor.mn-form__content-input {
    border: none;
    padding: 0;
    min-height: 400px;
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.85;
    color: #37352f;
    background: transparent;
  }

  /* Placeholder for trix-editor */
  trix-editor.mn-form__content-input:empty::before {
    color: #c4c3c1;
  }

  /* Bullet / numbered lists inside the editor */
  trix-editor ul, .trix-content ul {
    list-style-type: disc;
    padding-left: 1.5rem;
    margin: 0.25rem 0;
  }

  trix-editor ul ul, .trix-content ul ul {
    list-style-type: circle;
  }

  trix-editor ul ul ul, .trix-content ul ul ul {
    list-style-type: square;
  }

  trix-editor ol, .trix-content ol {
    list-style-type: decimal;
    padding-left: 1.5rem;
    margin: 0.25rem 0;
  }

  trix-editor li, .trix-content li {
    margin: 0.15rem 0;
    line-height: 1.75;
  }

  /* Rendered content on show page */
  .mn-note-view__content .trix-content {
    font-size: 1rem;
    line-height: 1.85;
    color: #37352f;
  }

  .mn-note-view__content .trix-content p {
    margin: 0 0 0.25rem;
  }

  /* Bold / italic in rendered content */
  .trix-content strong { font-weight: 600; }
  .trix-content em     { font-style: italic; }
}

@layer utilities {
  .txt-center { text-align: center; }
  .txt-muted { color: var(--color-ink-light); }
}
