/*
 * Pemampat PDF / PDF Compressor stylesheet: hand-written, no build step,
 * no framework.
 *
 * Design system: MYDS (Malaysia Government Design System) as written up in
 * GovTech's DESIGN.md (../pigeon/design/DESIGN.md): primary blue #2563EB,
 * Poppins headings, Inter for everything else, 4/6/8/12/14 radius scale,
 * three shadows, semantic bg-* / txt-* / otl-* / fr-* tokens with a dark theme.
 *
 * NO JAVASCRIPT. The CSP sends `script-src 'none'`; every state comes from
 * HTML (`<details>`, radio state, `:valid`, plain form POSTs) and CSS
 * (`:checked`, `:has()`, `light-dark()`). The CSP also refuses inline
 * `style=""`, so templates use classes only.
 *
 * Browser floor: `:has()`, CSS nesting and `light-dark()` (2024 evergreen).
 *
 * Cascade layers, lowest to highest priority:
 *   reset, base, layout, components, screens, utilities
 *
 * No hex values below the tokens: use the custom properties.
 */

@layer reset, base, layout, components, screens, utilities;

/* =============================================================== fonts == */

/* Self-hosted (SIL OFL, licences beside the files), so the CSP stays 'self'. */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/poppins-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/poppins-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/poppins-600-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================== tokens == */

/*
 * MYDS / GovTech tokens, transcribed from ../pigeon/design/DESIGN.md.
 *
 * Two layers, as in DESIGN.md:
 *   primitives  gray-*, primary-*, danger-*, success-*, warning-*: same in both themes
 *   semantic    bg-* fills, txt-* text, otl-* outlines, fr-* focus rings: switch with the theme
 *
 * Themes without JavaScript: every semantic token is `light-dark(light, dark)`,
 * resolved by `color-scheme`. With no cookie the page follows the OS
 * (`light dark`); the navbar switch sets a cookie and the server renders
 * `data-theme`, which pins `color-scheme`.
 *
 * Rules below use semantic tokens only, except primary-600 / danger-600
 * fills with white text (DESIGN.md: "Build with semantic tokens").
 */

:root {
  color-scheme: light dark;

  /* Primitives */
  --white: #FFFFFF;
  --primary-600: #2563EB;
  --primary-700: #1D4ED8;
  --danger-600: #DC2626;
  --danger-700: #B91C1C;
  --success-600: #16A34A;
  --warning-500: #EAB308;

  /* Fills */
  --bg-white: light-dark(#FFFFFF, #18181B);
  --bg-white-hover: light-dark(#FAFAFA, #27272A);
  --bg-washed: light-dark(#F4F4F5, #1D1D21);
  --bg-dialog: light-dark(#FFFFFF, #1D1D21);
  --bg-gray-50: light-dark(#FAFAFA, #161619);
  --bg-black-200: light-dark(#E4E4E7, #27272A);
  --bg-primary-50: light-dark(#EFF6FF, #172554);
  --bg-primary-100: light-dark(#DBEAFE, #1E3A8A);
  --bg-danger-50: light-dark(#FEF2F2, #450A0A);
  --bg-success-50: light-dark(#F0FDF4, #052E16);
  --bg-warning-50: light-dark(#FEFCE8, #422006);

  /* Text */
  --txt-black-900: light-dark(#18181B, #FFFFFF);
  --txt-black-700: light-dark(#3F3F46, #D4D4D8);
  --txt-black-500: light-dark(#6B6B74, #A1A1AA);
  --txt-primary: light-dark(#2563EB, #6394FF);
  --txt-danger: light-dark(#B91C1C, #F87171);
  --txt-success: light-dark(#15803D, #22C55E);
  --txt-warning: light-dark(#A16207, #EAB308);

  /* Outlines */
  --otl-divider: light-dark(#F4F4F5, #1D1D21);
  --otl-gray-200: light-dark(#E4E4E7, #27272A);
  --otl-gray-300: light-dark(#D4D4D8, #3F3F46);
  --otl-primary-200: light-dark(#C2D5FF, #1E40AF);
  --otl-primary-300: light-dark(#96B7FF, #1D4ED8);
  --otl-danger-200: light-dark(#FECACA, #991B1B);
  --otl-danger-300: light-dark(#FCA5A5, #B91C1C);
  --otl-success-200: light-dark(#BBF7D0, #166534);
  --otl-warning-200: light-dark(#FEF08A, #854D0E);

  /* Tag outlines: the status text colour at 20% (DESIGN.md "Tag"). */
  --otl-tag-primary: light-dark(#2563EB33, #6394FF33);
  --otl-tag-success: light-dark(#15803D33, #22C55E33);
  --otl-tag-warning: light-dark(#A1620733, #EAB30833);
  --otl-tag-danger: light-dark(#B91C1C33, #F8717133);

  /* Focus rings */
  --fr-primary: light-dark(#96B7FF66, #1D4ED866);
  --fr-danger: light-dark(#FCA5A566, #B91C1C66);

  /* Shadows (DESIGN.md "Elevation"), deeper in the dark theme. */
  --shadow-button: 0 1px 3px light-dark(#00000012, #00000040);
  --shadow-card: 0 2px 6px light-dark(#0000000D, #00000033), 0 6px 24px light-dark(#0000000D, #00000033);
  --shadow-context: 0 2px 6px light-dark(#0000000D, #00000033), 0 12px 50px light-dark(#0000001A, #00000066);

  /* Type */
  --font-heading: Poppins, ui-sans-serif, system-ui, sans-serif;
  --font-body: Inter, ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Roboto Mono", "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Radius */
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 14px;
  --radius-full: 9999px;

  /* Layout: 12-8-4 grid, 1280px max, 18px / 24px gutters. */
  --container-max: 1280px;
  --gutter: 18px;
  --navbar-height: 56px;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  /* Mobile bottom bar (replaces the footer below 48rem). */
  --bottom-nav-height: 4rem;
  --bottom-nav-space: calc(var(--bottom-nav-height) + var(--safe-bottom));

  @media (width >= 48rem) {
    --gutter: 24px;
    --navbar-height: 64px;
    --bottom-nav-space: 0px;
  }
}

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* =============================================================== reset == */

@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 0 solid;
  }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    line-height: 1.5;
    tab-size: 4;
  }

  h1, h2, h3, h4, h5, h6 {
    font-size: inherit;
    font-weight: inherit;
  }

  a {
    color: inherit;
    text-decoration: inherit;
  }

  b, strong {
    font-weight: 600;
  }

  ol, ul {
    list-style: none;
  }

  img, svg {
    display: block;
    flex-shrink: 0;
  }

  img {
    max-width: 100%;
  }

  button, input, select, textarea {
    font: inherit;
    letter-spacing: inherit;
    color: inherit;
    background-color: transparent;
    border-radius: 0;
  }

  button, label, summary, input[type="radio"], input[type="file"] {
    cursor: pointer;
  }

  fieldset {
    min-width: 0;
  }

  address {
    font-style: normal;
  }

  summary {
    list-style: none;
  }

  summary::-webkit-details-marker {
    display: none;
  }
}

/* ================================================================ base == */

@layer base {
  html {
    height: 100%;
    scroll-padding-top: calc(var(--navbar-height) + 1rem);
    scroll-padding-bottom: var(--bottom-nav-space);
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }

  body {
    display: flex;
    flex-direction: column;
    min-height: 100%;
    font-family: var(--font-body);
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--txt-black-900);
    background: var(--bg-white);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Room for the fixed mobile bottom bar (0 from 48rem). */
    padding-bottom: var(--bottom-nav-space);
  }

  h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
  }

  /* WCAG 2.1 AA: always-visible keyboard focus, MYDS 3px soft blue ring. */
  :focus-visible {
    outline: 3px solid var(--fr-primary);
    outline-offset: 2px;
  }

  /* No long-press callout / selection on UI chrome; content stays selectable. */
  button,
  summary,
  label,
  svg,
  .btn,
  .tag,
  .logo,
  .status-icon {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
  }

  img {
    -webkit-user-drag: none;
  }

  /*
   * Touch screens: an app-like feel. No pinch/double-tap zoom (with the
   * viewport meta in base.html), and no long-press selection, callout or
   * image menu anywhere. The few things people may need to copy stay
   * selectable. CSS only: the CSP forbids scripts.
   */
  @media (pointer: coarse) {
    html {
      touch-action: pan-x pan-y;
    }

    body {
      -webkit-user-select: none;
      user-select: none;
      -webkit-touch-callout: none;
    }

    input,
    textarea,
    .log {
      -webkit-user-select: text;
      user-select: text;
    }

    img {
      pointer-events: none;
    }
  }

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

/* ============================================================== layout == */

@layer layout {
  .container {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  .main {
    flex: 1;
    outline: none;
  }

  /* A centred page column (job status screens). */
  .page {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    max-width: calc(560px + 2 * var(--gutter));
    padding-block: 1.5rem 3rem;

    @media (width >= 48rem) {
      padding-block: 2rem 4rem;
    }
  }

  .section {
    border-top: 1px solid var(--otl-gray-200);
  }

  .section--subtle {
    background: var(--bg-gray-50);
  }

  .section__inner {
    display: flex;
    flex-direction: column;
    gap: 2rem;
    padding-block: 3rem;

    @media (width >= 64rem) {
      gap: 2.5rem;
      padding-block: 4rem;
    }
  }
}

/* ========================================================== components == */

@layer components {
  /* ----------------------------------------------------------- type -- */

  .heading {
    font-family: var(--font-heading);
    font-weight: 600;
    color: var(--txt-black-900);
    text-wrap: balance;
  }

  /* Landing h1: 32/40 on phones (pigeon mobile), heading-lg 48/60 on desktop. */
  .heading--hero {
    text-wrap: pretty;
    font-size: 2rem;
    line-height: 2.5rem;

    @media (width >= 64rem) {
      font-size: 3rem;
      line-height: 3.75rem;
    }
  }

  /* Page title: heading-md 36/44 from tablet up. */
  .heading--page {
    font-size: 1.75rem;
    line-height: 2.25rem;

    @media (width >= 48rem) {
      font-size: 2.25rem;
      line-height: 2.75rem;
    }
  }

  /* h2: heading-sm 30/38. */
  .heading--section {
    font-size: 1.5rem;
    line-height: 2rem;

    @media (width >= 48rem) {
      font-size: 1.875rem;
      line-height: 2.375rem;
    }
  }

  /* Card and dialog titles: heading-2xs 20/28. */
  .heading--card {
    font-size: 1.25rem;
    line-height: 1.75rem;
  }

  /* Reading text: body-md 16/24, body-lg 18/26 in the hero. */
  .lead {
    font-size: 1rem;
    line-height: 1.5rem;
    color: var(--txt-black-700);
    text-wrap: pretty;
  }

  .muted {
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--txt-black-500);
  }

  .skip-link {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 100;
    border-radius: var(--radius-md);
    background: var(--primary-600);
    padding: 0.5rem 0.75rem;
    font-weight: 500;
    color: var(--white);
    transform: translateY(-200%);

    &:focus-visible {
      transform: none;
    }
  }

  /* -------------------------------------------------------- buttons -- */

  /*
   * MYDS button: 8px radius, Inter 500, `shadow-button`, 3px focus ring,
   * presses down 0.5px. Sizes S 32 / M 40 / L 48 px.
   */
  .btn {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-weight: 500;
    white-space: nowrap;
    transition: background-color 0.15s, color 0.15s, border-color 0.15s;

    &:active {
      translate: 0 0.5px;
    }
  }

  .btn--s { height: 2rem; padding-inline: 0.625rem; font-size: 0.875rem; line-height: 1.25rem; }
  .btn--m { height: 2.5rem; padding-inline: 0.75rem; font-size: 1rem; line-height: 1.5rem; }
  .btn--l { height: 3rem; padding-inline: 1rem; font-size: 1.125rem; line-height: 1.625rem; }

  .btn--block {
    width: 100%;
  }

  .btn--primary {
    background: var(--primary-600);
    color: var(--white);
    box-shadow: var(--shadow-button);

    &:hover { background: var(--primary-700); }
  }

  .btn--secondary {
    border-color: var(--otl-gray-200);
    background: var(--bg-white);
    color: var(--txt-black-700);
    box-shadow: var(--shadow-button);

    &:hover { background: var(--bg-washed); }
  }

  .btn--tertiary {
    color: var(--txt-black-700);

    &:hover { background: var(--bg-washed); }
  }

  /* Square 32px icon button (navbar theme switch). */
  .icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-md);
    color: var(--txt-black-700);
    transition: background-color 0.15s;

    &:hover { background: var(--bg-washed); }
    &:active { translate: 0 0.5px; }
  }

  /* ------------------------------------------------------------ tags -- */

  /* MYDS tag: tinted fill, coloured text, 20%-opacity border. 6px inline, pill on status. */
  .tag {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.25rem;
    height: 1.75rem;
    border: 1px solid var(--otl-gray-300);
    border-radius: var(--radius-sm);
    background: var(--bg-washed);
    padding-inline: 0.5rem;
    font-size: 0.875rem;
    line-height: 1.25rem;
    font-weight: 500;
    color: var(--txt-black-700);
    white-space: nowrap;
  }

  .tag--pill { border-radius: var(--radius-full); padding-inline: 0.625rem; }

  .tag__dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: var(--radius-full);
    background: currentColor;
  }

  .tag--primary {
    border-color: var(--otl-tag-primary);
    background: var(--bg-primary-50);
    color: var(--txt-primary);
  }

  .tag--success {
    border-color: var(--otl-tag-success);
    background: var(--bg-success-50);
    color: var(--txt-success);

    & .tag__dot { background: var(--success-600); }
  }

  .tag--warning {
    border-color: var(--otl-tag-warning);
    background: var(--bg-warning-50);
    color: var(--txt-warning);

    & .tag__dot { background: var(--warning-500); }
  }

  .tag--danger {
    border-color: var(--otl-tag-danger);
    background: var(--bg-danger-50);
    color: var(--txt-danger);

    & .tag__dot { background: var(--danger-600); }
  }

  /* -------------------------------------------------------- callouts -- */

  /* MYDS callout: full width, 12px padding, tint + matching title, 20px icon. */
  .callout {
    --callout-bg: var(--bg-primary-50);
    --callout-fg: var(--txt-primary);

    display: flex;
    gap: 0.625rem;
    width: 100%;
    border-radius: var(--radius-md);
    background: var(--callout-bg);
    padding: 0.75rem;
    font-size: 0.875rem;
    line-height: 1.25rem;
    text-align: left;

    & > .icon {
      margin-top: 1px;
      color: var(--callout-fg);
    }
  }

  .callout--success { --callout-bg: var(--bg-success-50); --callout-fg: var(--txt-success); }
  .callout--warning { --callout-bg: var(--bg-warning-50); --callout-fg: var(--txt-warning); }
  .callout--danger { --callout-bg: var(--bg-danger-50); --callout-fg: var(--txt-danger); }

  .callout__body {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
  }

  .callout__title {
    font-weight: 600;
    color: var(--callout-fg);
  }

  .callout__text {
    color: var(--txt-black-700);
  }

  /* ----------------------------------------------------------- cards -- */

  .card {
    width: 100%;
    border: 1px solid var(--otl-gray-200);
    border-radius: var(--radius-lg);
    background: var(--bg-white);
    box-shadow: var(--shadow-card);
  }

  .card--padded {
    padding: 1.25rem;

    @media (width >= 48rem) {
      padding: 1.5rem;
    }
  }

  .card--stack {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
  }

  /* ---------------------------------------------------- status icon -- */

  .status-icon {
    position: relative;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 4rem;
    height: 4rem;
    border-radius: var(--radius-full);
    background: var(--bg-washed);
    color: var(--txt-black-700);
  }

  .status-icon--info { background: var(--bg-primary-50); color: var(--txt-primary); }
  .status-icon--success { background: var(--bg-success-50); color: var(--txt-success); }
  .status-icon--warning { background: var(--bg-warning-50); color: var(--txt-warning); }
  .status-icon--danger { background: var(--bg-danger-50); color: var(--txt-danger); }

  /* A spinning arc around the icon while a job runs. Pure CSS. */
  .status-icon--busy::after {
    content: "";
    position: absolute;
    inset: -5px;
    border: 2px solid var(--otl-primary-200);
    border-top-color: var(--primary-600);
    border-radius: var(--radius-full);
    animation: spin 0.9s linear infinite;
  }

  @keyframes spin {
    to { rotate: 360deg; }
  }

  /* ----------------------------------------------------- form fields -- */

  .field {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    width: 100%;
    min-width: 0;
  }

  /* label-sm: 14px Inter 500. */
  .field__label {
    font-size: 0.875rem;
    line-height: 1.25rem;
    font-weight: 500;
    color: var(--txt-black-900);
  }

  /* <legend> ignores flex gap. */
  legend.field__label {
    margin-bottom: 0.375rem;
  }

  /* body-xs 12/18. */
  .field__hint {
    font-size: 0.75rem;
    line-height: 1.125rem;
    color: var(--txt-black-500);
  }

  /* -------------------------------------------------------- dropzone -- */

  /*
   * The <input type=file> itself is the whole dashed box, so dropping a file
   * anywhere on it works natively and the browser prints the filename. The
   * caption is painted over its top with `pointer-events: none`.
   */
  .dropzone {
    position: relative;
  }

  .dropzone__input {
    display: block;
    width: 100%;
    border: 1.5px dashed var(--otl-gray-300);
    border-radius: var(--radius-md);
    background: var(--bg-gray-50);
    padding: 7.75rem 1rem 1.25rem;
    font-size: 0.875rem;
    color: var(--txt-black-500);
    text-align: center;
    transition: border-color 0.15s, background-color 0.15s;

    &:hover {
      border-color: var(--otl-primary-300);
      background: var(--bg-primary-50);
    }

    &:focus-visible {
      border-color: var(--otl-primary-300);
    }

    &::file-selector-button {
      margin-right: 0.75rem;
      height: 2rem;
      border: 1px solid var(--otl-gray-200);
      border-radius: var(--radius-md);
      background: var(--bg-white);
      padding-inline: 0.625rem;
      font: inherit;
      font-weight: 500;
      color: var(--txt-black-700);
      box-shadow: var(--shadow-button);
      cursor: pointer;
    }

    /* A required file input becomes :valid once a file is chosen. */
    &:required:valid {
      border-style: solid;
      border-color: var(--otl-success-200);
      background: var(--bg-success-50);
      color: var(--txt-success);
    }
  }

  .dropzone__caption {
    position: absolute;
    inset: 1.5rem 1rem auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    pointer-events: none;
    text-align: center;
  }

  .dropzone__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--radius-full);
    background: var(--bg-primary-50);
    color: var(--txt-primary);
  }

  .dropzone__title {
    max-width: 22rem;
    font-size: 0.875rem;
    line-height: 1.25rem;
    font-weight: 500;
    color: var(--txt-black-900);
  }

  .dropzone:has(.dropzone__input:required:valid) .dropzone__icon {
    background: var(--bg-white);
    color: var(--txt-success);
  }

  /* --------------------------------------------------- option cards -- */

  /*
   * Radio cards: each <label class="option"> wraps a real, visually hidden
   * radio; `:has(:checked)` paints the chosen card. No script involved.
   */
  .options {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;

    @media (width >= 48rem) {
      gap: 0.75rem;
    }
  }

  .option {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    border: 1px solid var(--otl-gray-200);
    border-radius: var(--radius-md);
    background: var(--bg-white);
    padding: 0.75rem;
    box-shadow: var(--shadow-button);
    transition: border-color 0.15s, background-color 0.15s;

    &:hover {
      background: var(--bg-white-hover);
    }

    &:has(:checked) {
      border-color: var(--primary-600);
      background: var(--bg-primary-50);
      box-shadow: var(--shadow-button), inset 0 0 0 1px var(--primary-600);
    }

    &:has(:focus-visible) {
      outline: 3px solid var(--fr-primary);
      outline-offset: 2px;
    }

    &:active {
      translate: 0 0.5px;
    }
  }

  .option__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
  }

  .option__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
  }

  .option__label {
    font-weight: 600;
    color: var(--txt-black-900);
  }

  /* The radio indicator, drawn: white ring, primary-600 when chosen. */
  .option__dot {
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    border: 1px solid var(--otl-gray-300);
    border-radius: var(--radius-full);
    background: var(--bg-white);
    box-shadow: var(--shadow-button);

    .option:has(:checked) & {
      border: 5px solid var(--primary-600);
      background: var(--white);
    }
  }

  .option__dpi {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.125rem;
    color: var(--txt-primary);
  }

  .option__hint {
    font-size: 0.75rem;
    line-height: 1.125rem;
    color: var(--txt-black-500);
  }

  /* ------------------------------------------------------- file chip -- */

  .file-chip {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    border-radius: var(--radius-md);
    background: var(--bg-washed);
    padding: 0.75rem;
    text-align: left;

    & > .icon { color: var(--txt-black-500); }
  }

  .file-chip__text {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-width: 0;
  }

  .file-chip__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
    color: var(--txt-black-900);
  }

  .file-chip__meta {
    font-size: 0.75rem;
    line-height: 1.125rem;
    color: var(--txt-black-500);
  }

  /* ----------------------------------------------------- key / value -- */

  .kv {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--otl-gray-200);
    padding: 0.5rem 1.25rem;
  }

  .kv__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-block: 0.625rem;

    & + & { border-top: 1px solid var(--otl-divider); }
    & dt { flex-shrink: 0; color: var(--txt-black-500); }
    & dd { min-width: 0; font-weight: 500; color: var(--txt-black-900); text-align: right; }
  }

  .kv__muted {
    font-weight: 400;
    color: var(--txt-black-500);
  }

  .kv__file {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
  }

  /* ------------------------------------------------------ disclosure -- */

  .disclosure {
    border: 1px solid var(--otl-gray-200);
    border-radius: var(--radius-md);
    text-align: left;
  }

  .disclosure__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-radius: var(--radius-md);
    padding: 0.5rem 0.75rem;
    font-weight: 500;
    color: var(--txt-black-700);

    & .icon { transition: rotate 0.15s; }
    .disclosure[open] > & .icon { rotate: 180deg; }
    &:hover { background: var(--bg-washed); }
  }

  .log {
    max-height: 14rem;
    overflow: auto;
    border-top: 1px solid var(--otl-gray-200);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    background: var(--bg-gray-50);
    padding: 0.75rem;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    line-height: 1.6;
    color: var(--txt-black-700);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }

  /* ------------------------------------------------------ breadcrumb -- */

  .breadcrumb a {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    border-radius: var(--radius-sm);
    font-weight: 500;
    color: var(--txt-black-500);

    &:hover { color: var(--txt-black-900); }
  }

  /* ======================================================== chrome == */

  /* -------------------------------------------------------- masthead -- */

  /*
   * MYDS masthead: bg-washed strip with the flag, "Laman Web Rasmi Kerajaan
   * Malaysia" and a blue "Ketahui Lebih Lanjut" toggle. A <details>, so it
   * opens without JavaScript.
   */
  .masthead {
    background: var(--bg-washed);
  }

  .masthead__bar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-block: 0.25rem;
    font-size: 0.75rem;
    line-height: 1.125rem;
    color: var(--txt-black-700);

    @media (width >= 48rem) {
      font-size: 0.875rem;
      line-height: 1.25rem;
    }

    &:focus-visible { outline-offset: -3px; }
  }

  .masthead__flag {
    width: 1.5rem;
    height: 0.75rem;

    @media (width >= 48rem) {
      width: 2rem;
      height: 1rem;
    }
  }

  .masthead__toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
    padding: 0.25rem 0.25rem 0.25rem 0.375rem;
    color: var(--txt-primary);

    & .icon { transition: rotate 0.15s; }
    .masthead[open] & .icon { rotate: 180deg; }
  }

  /* Phones keep only the chevron (pigeon "compact" masthead). */
  .masthead__toggle-label {
    @media (width < 48rem) {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }
  }

  .masthead__panel {
    display: grid;
    gap: 1.125rem;
    padding-block: 1rem 1.5rem;

    @media (width >= 48rem) {
      grid-template-columns: 1fr 1fr;
    }
  }

  .masthead__tip {
    display: flex;
    gap: 0.75rem;

    & > .icon { color: var(--txt-black-500); }
  }

  .masthead__tip-text {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
  }

  .masthead__tip-title {
    font-weight: 500;
    color: var(--txt-black-900);
  }

  .masthead__tip-body {
    max-width: 26.25rem;
    color: var(--txt-black-700);
  }

  /* ---------------------------------------------------------- navbar -- */

  /* MYDS navbar: white, bottom border + `shadow-button`, sticky, 64px. */
  .navbar {
    position: sticky;
    top: 0;
    z-index: 30;
    border-bottom: 1px solid var(--otl-gray-200);
    background: var(--bg-white);
    box-shadow: var(--shadow-button);
  }

  .navbar__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    height: var(--navbar-height);
  }

  .navbar__start {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    min-width: 0;
  }

  .navbar__links {
    display: none;
    align-items: center;
    gap: 0.25rem;

    @media (width >= 48rem) {
      display: flex;
    }
  }

  .navbar__link {
    border-radius: var(--radius-md);
    padding: 0.375rem 0.625rem;
    font-weight: 500;
    color: var(--txt-black-700);
    transition: background-color 0.15s;

    &:hover,
    &[aria-current="page"] {
      background: var(--bg-washed);
      color: var(--txt-black-900);
    }
  }

  .navbar__end {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }

  .navbar__form {
    display: contents;
  }

  .logo {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-width: 0;
    border-radius: var(--radius-md);
  }

  .logo__crest {
    width: 31px;
    height: 24px;
    object-fit: contain;

    @media (width >= 48rem) {
      width: 41px;
      height: 32px;
    }
  }

  .logo__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-heading);
    font-size: 1rem;
    line-height: 1.5rem;
    font-weight: 600;
    color: var(--txt-black-900);

    @media (width >= 48rem) {
      font-size: 1.125rem;
      line-height: 1.75rem;
    }
  }

  /* BM / EN: the bordered globe button from pigeon's header. */
  .lang-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    height: 2rem;
    border: 1px solid var(--otl-gray-200);
    border-radius: var(--radius-md);
    background: var(--bg-white);
    padding-inline: 0.5rem;
    font-weight: 500;
    color: var(--txt-black-900);
    transition: background-color 0.15s;

    & .icon { color: var(--txt-black-700); }
    &:hover { background: var(--bg-washed); }
    &:active { translate: 0 0.5px; }
  }

  /*
   * Theme switch: both buttons are in the HTML, CSS shows only the one that
   * switches AWAY from the current look (explicit cookie, else the OS).
   */
  .theme-btn--to-light { display: none; }

  :root[data-theme="dark"] {
    & .theme-btn--to-dark { display: none; }
    & .theme-btn--to-light { display: inline-flex; }
  }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme]) {
      & .theme-btn--to-dark { display: none; }
      & .theme-btn--to-light { display: inline-flex; }
    }
  }

  /* ---------------------------------------------------------- footer -- */

  /*
   * MYDS footer: bg-gray-50, top border, agency info + link groups + legal row.
   * Desktop/tablet only; on mobile the bottom bar takes its place.
   */
  .footer {
    display: none;
    margin-top: auto;
    border-top: 1px solid var(--otl-gray-200);
    background: var(--bg-gray-50);
    color: var(--txt-black-700);

    @media (width >= 48rem) {
      display: block;
    }
  }

  .footer__inner {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding-block: 2rem calc(1.5rem + var(--safe-bottom));

    @media (width >= 48rem) {
      gap: 2rem;
      padding-block: 4rem 3rem;
    }
  }

  .footer__top {
    display: flex;
    flex-direction: column;
    gap: 2rem;

    @media (width >= 64rem) {
      flex-direction: row;
      justify-content: space-between;
      gap: 3.5rem;
    }
  }

  .footer__brand {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    max-width: 24rem;
  }

  .footer__logo {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-family: var(--font-heading);
    font-size: 1rem;
    line-height: 1.5rem;
    font-weight: 600;
    color: var(--txt-black-900);

    @media (width >= 48rem) {
      font-size: 1.125rem;
      line-height: 1.75rem;
    }

    & img { width: 36px; height: 28px; object-fit: contain; }
  }

  .footer__address {
    @media (width < 48rem) {
      display: none;
    }
  }

  .footer__links {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2rem;

    @media (width >= 64rem) {
      grid-template-columns: repeat(2, 10rem);
      gap: 3.5rem;
    }
  }

  .footer__group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;

    & a:hover {
      color: var(--txt-black-900);
      text-decoration: underline;
      text-underline-offset: 3px;
    }
  }

  .footer__heading {
    font-weight: 600;
    color: var(--txt-black-900);
  }

  .footer__bottom {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    border-top: 1px solid var(--otl-gray-200);
    padding-top: 1.5rem;
    color: var(--txt-black-500);

    @media (width >= 40rem) {
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
    }
  }

  .footer__legal {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;

    & a {
      color: var(--txt-black-700);

      &:hover { text-decoration: underline; text-underline-offset: 3px; }
    }
  }

  .footer__rule {
    width: 1px;
    height: 1rem;
    background: var(--otl-gray-300);

    @media (width < 40rem) {
      display: none;
    }
  }

  /* ------------------------------------------------------ bottom nav -- */

  /* Mobile only: fixed tab bar, above the iPhone home indicator. */
  .bottom-nav {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 30;
    display: grid;
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
    border-top: 1px solid var(--otl-gray-200);
    background: var(--bg-white);
    box-shadow: 0 -1px 3px light-dark(#00000012, #00000040);
    padding-bottom: var(--safe-bottom);

    @media (width >= 48rem) {
      display: none;
    }
  }

  .bottom-nav__link {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    height: var(--bottom-nav-height);
    padding-inline: 0.25rem;
    font-size: 0.75rem;
    line-height: 1rem;
    font-weight: 500;
    color: var(--txt-black-500);
    text-align: center;
    transition: color 0.15s;

    & .icon { color: inherit; }

    &:active { background: var(--bg-washed); }

    &[aria-current="page"] {
      color: var(--txt-primary);
      font-weight: 600;
    }

    &:focus-visible { outline-offset: -3px; }
  }
}

/* ============================================================= screens == */

@layer screens {
  /* ------------------------------------------------------------ index -- */

  .hero__inner {
    display: grid;
    gap: 2rem;
    padding-block: 2rem 3rem;

    @media (width >= 64rem) {
      grid-template-columns: minmax(0, 1fr) minmax(0, 32.5rem);
      align-items: center;
      gap: 4rem;
      padding-block: 5rem;
    }
  }

  .hero__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;

    & .lead {
      max-width: 35rem;

      @media (width >= 64rem) {
        font-size: 1.125rem;
        line-height: 1.625rem;
      }
    }
  }

  .checklist {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
    color: var(--txt-black-500);

    & li {
      display: flex;
      align-items: center;
      gap: 0.5rem;
    }
  }

  .hero__form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  .upload-card {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding: 1.25rem;

    @media (width >= 48rem) {
      padding: 1.5rem;
    }
  }

  .upload-card__header {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
  }

  .how {
    display: grid;
    gap: 2rem;

    @media (width >= 48rem) {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
  }

  .how__item {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  .how__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--radius-md);
    background: var(--bg-primary-50);
    color: var(--txt-primary);
  }

  .how__text {
    font-size: 1rem;
    line-height: 1.5rem;
    color: var(--txt-black-700);
  }

  .disclaimer {
    color: var(--txt-black-500);

    & strong { color: var(--txt-black-700); }
  }

  /* -------------------------------------------------------------- job -- */

  .result {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.5rem;
    text-align: center;
  }

  .result__heading {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }

  .result__actions {
    display: flex;
    flex-direction: column-reverse;
    gap: 0.5rem;
    width: 100%;

    @media (width >= 40rem) {
      flex-direction: row;
      justify-content: center;
    }
  }

  .result__note {
    margin-top: -0.75rem;
    font-size: 0.75rem;
    line-height: 1.125rem;
  }

  /* Progress steps while the worker runs. */
  .steps {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-top: 1.25rem;
    text-align: left;
  }

  .steps__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--txt-black-500);

    /* Connector to the next step. */
    &:not(:last-child)::after {
      content: "";
      position: absolute;
      top: 1.25rem;
      left: calc(0.625rem - 0.5px);
      width: 1px;
      height: 0.75rem;
      background: var(--otl-gray-200);
    }
  }

  .steps__marker {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    border: 1.5px solid var(--otl-gray-300);
    border-radius: var(--radius-full);
    background: var(--bg-white);
  }

  .steps__item--done {
    color: var(--txt-black-900);

    & .steps__marker {
      border-color: var(--success-600);
      background: var(--success-600);
      color: var(--white);
    }
  }

  .steps__item--active,
  .steps__item--waiting {
    font-weight: 500;
    color: var(--txt-black-900);

    & .steps__marker {
      border-color: var(--otl-primary-200);
      border-top-color: var(--primary-600);
      animation: spin 0.9s linear infinite;
    }
  }

  .steps__item--waiting .steps__marker {
    animation-duration: 2.4s;
  }

  /* Big "−96.9% lebih kecil" readout with a native <progress> as the bar. */
  .saving {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1.5rem 1.25rem 1.25rem;
  }

  .saving__headline {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.5rem;
  }

  .saving__value {
    font-family: var(--font-heading);
    font-size: 3rem;
    line-height: 1;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--txt-success);
    font-variant-numeric: tabular-nums;
  }

  .saving__label {
    font-size: 1rem;
    color: var(--txt-black-500);
  }

  .saving__bar {
    appearance: none;
    width: 100%;
    height: 0.5rem;
    border: 0;
    border-radius: var(--radius-full);
    background: var(--bg-black-200);
    overflow: hidden;

    &::-webkit-progress-bar {
      border-radius: var(--radius-full);
      background: var(--bg-black-200);
    }

    &::-webkit-progress-value {
      border-radius: var(--radius-full);
      background: var(--primary-600);
    }

    &::-moz-progress-bar {
      border-radius: var(--radius-full);
      background: var(--primary-600);
    }
  }

  .saving__scale {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    font-size: 0.75rem;
    line-height: 1.125rem;
    color: var(--txt-black-500);
    font-variant-numeric: tabular-nums;
  }
}

/* =========================================================== utilities == */

@layer utilities {
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  @media print {
    .no-print { display: none !important; }
    * { box-shadow: none !important; }
  }
}
