/* ============================================================
   MOBILE v6 — "One Column"
   ------------------------------------------------------------
   Loaded only at <=768px (index.html, <link media>), so nothing
   in this file can reach the desktop rendering.

   This file does two jobs:
     A. It removes the desktop page at phone widths — the twelve
        desktop <section>s are switched off outright, not resized.
     B. It styles #m-page, a purpose-built phone page defined in
        index.html. That markup has its own blocks, its own order
        and its own components, and it is what a phone visitor
        actually reads.

   Rules of this file
   ------------------
   1. THEME IS LOCKED. Every colour is either a desktop token
      copied verbatim from css/site.css :root, or the five
      Defense-in-Depth layer colours that main.js already owns.
      No new hues — mobile and desktop must read as one site.
   2. LESS, NOT SMALLER. Blocks are deleted, not compressed.
      Three desktop sections collapse into the single lab block;
      the ATT&CK canvas, both SVG diagrams, the ticker, the
      terminal, the particle portrait and both live feeds are
      gone at this width, not shrunk.
   3. Flat surfaces, hairline borders, no shadows, no glows.
      One accent colour on screen at a time.
   4. Specificity: this file loads after site.css, so at equal
      specificity + equal !important the later rule wins. Where
      an override has to beat a more specific desktop rule, the
      selector is matched or raised accordingly. The .m-* classes
      belong to #m-page alone and need no !important.
   ============================================================ */
@media (max-width: 768px) {

  /* ----------------------------------------------------------
     1 · TOKENS
     ---------------------------------------------------------- */
  :root {
    color-scheme: dark;

    /* — desktop tokens, verbatim — */
    --bg: #05070d;
    --surface: #0d1526;
    --text: #ffffff;
    --muted: #e9effc;
    --stroke: #1b2740;
    --gradient-accent: linear-gradient(90deg, #1e3a5f 0%, #3b82f6 100%);
    --glow: rgba(59, 130, 246, 0.35);
    --sev-low: #22c55e;
    --cyan-live: #22d3ee;

    /* — desktop utility values, re-stated so #m-page does not
         depend on the Tailwind subset — */
    --text-2: #e8edf5;          /* .text-txt  */
    --muted-2: #c5d0e4;          /* .text-muted — brightened 3× */
    --accent: #3b82f6;
    --accent-hi: #60a5fa;       /* .sec-num   */

    /* — derived from the tokens above, nothing new — */
    --stroke-soft: color-mix(in srgb, #1b2740 78%, transparent);
    --copy: color-mix(in srgb, #c5d0e4 15%, #e9effc);

    /* — rhythm — 8pt grid: every pad/gap below is a multiple of 4/8 — */
    --pad-x: 20px;                 /* 8×2.5  gutter */
    --sec-y: 48px;                 /* 8×6    section breathing */
    --r-sm: 12px;
    --r: 16px;
    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
    --quick: 160ms;

    /* — type scale — 8 sizes, no orphans in between — */
    --fs-micro: 0.6875rem;         /* 11px  tiny labels                 */
    --fs-chip: 0.75rem;            /* 12px  chips, pills, dates         */
    --fs-small: 0.8125rem;         /* 13px  captions, sub-lines       */
    --fs-body: 0.9375rem;          /* 15px  paragraph copy            */
    --fs-lede: 1rem;               /* 16px  hero lede, inputs         */
    --fs-num: 1.25rem;             /* 20px  stat numbers              */
    --fs-h2: 1.375rem;             /* 22px  section headings          */
    --fs-name: clamp(2.25rem, 10.5vw, 2.75rem);
  }

  /* ----------------------------------------------------------
     2 · SHELL — the desktop page is removed, not adapted.

     Every desktop section is switched off. #m-page, added at the
     end of <body>, is the whole phone page. Both decisions sit
     behind this media query, so desktop layout is untouched.
     ---------------------------------------------------------- */
  html, body { overflow-x: clip !important; background: var(--bg) !important; }
  html { scroll-behavior: smooth; scroll-padding-top: 4.5rem; }

  /* Menu scroll lock. It has to land on <html> as well as <body>:
     body overflow only propagates to the viewport while html's is
     `visible`, and the rule above gives html `overflow-x: clip`, so
     a body-only lock would leave the page scrolling behind the
     overlay. mobile.js sets the class on both elements. */
  html.mobile-menu-open, body.mobile-menu-open { overflow: hidden !important; }

  #home, #mission, #ticker, #about, #defense-depth, #experience,
  #soc-lab, #skills, #attack-coverage, #investigations,
  #live-activity, #credentials, footer#contact { display: none !important; }

  /* Desktop-only chrome that lives outside those sections. */
  #section-rail, #hero-canvas, #mission-bg, #bg-tint, #stats-tint,
  #ambient-vignette, #projects-pinned, #palette,
  #main-header .star, #main-header .nav-border-line,
  #main-header a.btn-gradient-border, #main-header nav > ul {
    display: none !important;
  }

  section, footer { scroll-margin-top: 4.5rem; }

  /* ----------------------------------------------------------
     3 · HEADER — a flat hairline bar instead of a floating pill
     ---------------------------------------------------------- */
  #main-header {
    position: fixed !important;
    top: 0; left: 0; right: 0;
    z-index: 70;
    padding: 0 !important;
    background: transparent !important;
    transition: transform 240ms var(--ease);
  }
  #main-header.m-hide { transform: translateY(-100%); }
  #main-header .nav-pill {
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    width: 100%;
    padding: 0.65rem var(--pad-x) !important;
    border: 0 !important;
    border-bottom: 1px solid var(--stroke-soft) !important;
    border-radius: 0 !important;
    background: color-mix(in srgb, #05070d 88%, transparent) !important;
    backdrop-filter: blur(16px) saturate(140%);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    box-shadow: none !important;
    transform: none !important;
  }
  #main-header .logo-ring {
    width: 2rem !important;
    height: 2rem !important;
    font-size: 0.7rem !important;
  }
  #main-header .pulse-dot { width: 5px !important; height: 5px !important; }
  #main-header #nav-clock {
    font-size: var(--fs-micro) !important;
    letter-spacing: 0.1em !important;
  }
  #main-header .hamburger span { width: 16px; height: 1.5px; }

  /* ----------------------------------------------------------
     4 · MENU — a numbered index, not a stack of fat pills
     ---------------------------------------------------------- */
  /* The menu must sit ABOVE the fixed header (z-70): the ✕ lives at
     top-right, exactly where the header is — at z-60 every tap on it
     landed on the hamburger underneath and the menu could never close. */
  #mobile-menu { z-index: 90; }
  /* `hidden` must survive .mobile-pill's display:grid !important —
     attribute hiding beats inline styles (CSP-proof, wipe-proof). */
  #mobile-menu .mobile-pill[hidden] { display: none !important; }
  /* Redesigned open state: editorial index — display type, accent
     numerals, staggered rise-in, contact footer. All JS contracts
     untouched (.open, remap, order, focus, scroll-lock). */
  #mobile-menu {
    background:
      radial-gradient(120% 60% at 50% 0%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 60%),
      #05070d;
  }
  #mobile-menu .menu-panel {
    justify-content: flex-start !important;
    overflow-y: auto;
    padding: 5.5rem var(--pad-x) 2rem !important;
  }
  #menu-close {
    width: 44px !important;
    height: 44px !important;
    background: var(--surface) !important;
    border: 1px solid var(--stroke) !important;
    border-radius: 999px !important;
    color: var(--text-2) !important;
  }
  #menu-close:active { border-color: var(--accent) !important; color: var(--accent-hi) !important; }
  #mobile-menu nav {
    display: block !important;
    width: 100% !important;
    max-width: none !important;
    counter-reset: mnav;
    border-top: 1px solid var(--stroke-soft);
  }
  #mobile-menu nav::before {
    content: "Navigate";
    display: block;
    margin: 0 0 8px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted-2);
  }
  .mobile-pill {
    display: grid !important;
    grid-template-columns: auto minmax(0, 1fr) !important;
    align-items: center !important;
    gap: 0.75rem;
    width: 100%;
    min-height: 3.3rem;
    padding: 0.7rem 0 !important;
    font-family: var(--font-display, "Space Grotesk", sans-serif) !important;
    font-size: 1.15rem !important;
    font-weight: 600 !important;
    letter-spacing: -0.02em !important;
    line-height: 1.15 !important;
    color: var(--text) !important;
    border: 0 !important;
    border-bottom: 1px solid var(--stroke-soft) !important;
    border-radius: 0 !important;
  }
  /* Row numerals join the chip system: boxed, aired, accent-edged —
     same 12px-voiced mono treatment as every other chip on the page. */
  .mobile-pill::before {
    counter-increment: mnav;
    content: counter(mnav, decimal-leading-zero);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 20px;
    box-sizing: border-box;
    padding: 2px 8px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    font-weight: 500;
    letter-spacing: 0.1em;
    color: var(--accent-hi);
    background: var(--surface);
    border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--stroke));
    border-radius: var(--r-sm);
    transform: translateZ(0);
  }
  .mobile-pill svg { display: none; }
  .mobile-pill:active { background: transparent !important; transform: none !important; color: var(--accent-hi) !important; }
  .mobile-pill:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 4px; }
  /* staggered rise-in — visible pills sit at DOM positions 6–11
     (hidden ones keep their numbers out of the sequence) */
  #mobile-menu.open .mobile-pill { animation: m-menu-in 0.5s var(--ease) both; }
  #mobile-menu.open .mobile-pill:nth-child(6) { animation-delay: 0.03s; }
  #mobile-menu.open .mobile-pill:nth-child(7) { animation-delay: 0.06s; }
  #mobile-menu.open .mobile-pill:nth-child(8) { animation-delay: 0.09s; }
  #mobile-menu.open .mobile-pill:nth-child(9) { animation-delay: 0.12s; }
  #mobile-menu.open .mobile-pill:nth-child(10) { animation-delay: 0.15s; }
  #mobile-menu.open .mobile-pill:nth-child(11) { animation-delay: 0.18s; }
  @keyframes m-menu-in {
    from { opacity: 0; translate: 0 14px; }
    to { opacity: 1; translate: 0 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    #mobile-menu.open .mobile-pill { animation: none; }
  }
  /* footer: direct contact, thumb-reachable at panel bottom */
  .m-menu-foot { width: 100%; margin-top: 32px; }
  .m-menu-mail {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 34px;
    padding: 0 20px;
    border-radius: 999px;
    background: var(--gradient-accent);
    color: #fff;
    font-size: var(--fs-small);
    font-weight: 600;
    text-decoration: none;
  }
  .m-menu-tag {
    margin: 12px 0 0;
    text-align: center;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted-2);
  }

  /* ----------------------------------------------------------
     5 · THE MOBILE PAGE
     ---------------------------------------------------------- */
  #m-page {
    display: block;
    padding-top: 3.6rem;          /* clears the fixed header */
    scroll-margin-top: 4.5rem;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-body, Inter, system-ui, sans-serif);
    -webkit-font-smoothing: antialiased;
  }
  #m-page * { box-sizing: border-box; }

  /* gradient text needs a floor: if the clip is unsupported the
     fill is transparent and the name would vanish */
  @supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    #m-page .grad-text {
      background: none !important;
      -webkit-text-fill-color: currentColor;
      color: var(--accent-hi);
    }
  }

  /* — shared block furniture — */
  .m-block {
    padding: var(--sec-y) var(--pad-x);
    border-top: 1px solid var(--stroke-soft);
  }
  .m-block-flush { padding-top: 16px; border-top: 0; }

  .m-head { margin-bottom: 20px; }
  .m-kicker {
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted-2);
    margin: 0 0 8px;
  }
  .m-h2 {
    font-family: var(--font-display, "Space Grotesk", sans-serif);
    font-size: var(--fs-h2);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--text);
    margin: 0;
    text-wrap: balance;
  }
  .m-h3 {
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted-2);
    margin: 40px 0 0;
  }
  .m-body {
    font-size: var(--fs-body);
    line-height: 1.65;
    color: var(--copy);
    margin: 0;
    text-wrap: pretty;
  }

  /* — buttons — */
  .m-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 48px;
    padding: 0 20px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-family: inherit;
    font-size: var(--fs-small);
    font-weight: 500;
    letter-spacing: 0.01em;
    text-decoration: none;
    white-space: nowrap;
    transition: opacity var(--quick) var(--ease);
  }
  .m-btn-solid { background: var(--gradient-accent); color: #fff; }
  /* Ghost is NOT a bare hairline: a tinted accent fill + accent border
     so it reads tappable at a glance and matches the gradient family.
     Border tint ~3.2:1 on --bg, meeting WCAG 2.2 non-text contrast. */
  .m-btn-ghost {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
    border-color: color-mix(in srgb, var(--accent) 44%, transparent);
    color: var(--text);
  }
  .m-btn-full { display: flex; width: 100%; }
  .m-btn:active { opacity: 0.75; }

  /* ── 1 · IDENTITY ───────────────────────────────────────── */
  .m-hero {
    padding: 24px var(--pad-x) 20px;   /* bottom halved — tighter run into stats */
    border-bottom: 1px solid var(--stroke-soft);
  }
  .m-eyebrow {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--muted-2);
    margin: 0 0 24px;
  }
  .m-dot {
    width: 6px; height: 6px;
    border-radius: 999px;
    background: var(--sev-low);
    box-shadow: 0 0 0 3px color-mix(in srgb, #22c55e 16%, transparent);
    flex: 0 0 auto;
  }
  .m-name {
    font-family: var(--font-display, "Space Grotesk", sans-serif);
    font-size: var(--fs-name);
    font-weight: 600;
    line-height: 1.05;
    letter-spacing: -0.035em;
    color: var(--text);
    margin: 0;
  }
  .m-role {
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-small);
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--accent-hi);
    margin: 12px 0 0;
  }
  .m-lede {
    font-size: var(--fs-lede);
    line-height: 1.6;
    color: var(--copy);
    margin: 20px 0 0;
    text-wrap: pretty;
  }
  .m-ctas {
    display: flex;
    gap: 8px;
    margin-top: 28px;
  }
  .m-ctas .m-btn { flex: 1 1 0; min-width: 0; }

  /* Meta strip: one line per fact, icon-led, 8pt rhythm — reads as
     credentials instead of three cramped micro-columns. */
  .m-strip {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
    margin: 28px 0 0;
    padding-top: 20px;
    border-top: 1px solid var(--stroke-soft);
  }
  .m-strip > div {
    display: grid;
    grid-template-columns: 76px minmax(0, 1fr);
    align-items: baseline;
    gap: 12px;
  }
  .m-strip dt {
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--muted-2);
    margin: 0;
  }
  .m-strip dd {
    font-size: var(--fs-small);
    line-height: 1.4;
    color: var(--text-2);
    margin: 0;
  }

  /* ── 2 · NUMBERS ──────────────────────────────────────────
     ONE card language, desktop colors: every tile keeps the same
     bordered surface, radius, padding and alignment — but each tile
     carries its desktop XStats accent (--a), tinting the number and
     the border exactly the way the desktop cards tint their bar. */
  .m-stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  .m-stat { --a: var(--accent); }
  .m-stat:nth-child(1) { --a: #EAB308; }   /* KC7 Top 1% — kcu yellow */
  .m-stat:nth-child(2) { --a: #06B6D4; }   /* alerts triaged — soc cyan */
  .m-stat:nth-child(3) { --a: #8B5CF6; }   /* CyberDefenders — cd violet */
  .m-stat:nth-child(4) { --a: #F59E0B; }   /* YARA rules — intel amber */
  .m-stat:nth-child(6) { --a: #2dd4bf; }   /* write-ups — res teal */
  .m-stat {
    display: block;
    padding: 10px;                           /* 20% tighter box — text sizes untouched */
    /* Darker than --surface (user call): tile fill sinks toward --bg
       so the accent numbers/bars carry the tile. Token-derived mix,
       no new hue. */
    background: color-mix(in srgb, var(--surface) 35%, #05070d);
    border: 1px solid color-mix(in srgb, var(--a) 38%, var(--stroke));
    border-radius: var(--r-sm);
    text-decoration: none;
    color: inherit;
    min-height: 96px;                        /* 120px − 20%, box only */
  }
  .m-stat:nth-child(odd) { padding-right: 13px; }
  .m-stat:nth-child(even) { padding-left: 13px; }
  /* Desktop xcard anatomy, compressed: tag + dot, white number,
     accent bar, label — same elements, same order, same voice. */
  /* Achievement tags join the chip system: same surface box +
     hairline edge (in the tile's own --a), sized for half-width tiles
     — 32px tall, tighter tracking so labels hold one line. */
  .m-stat .m-xtag {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-height: 17px;                        /* −20% again, box only, text stays 11px */
    width: fit-content;
    max-width: 100%;
    box-sizing: border-box;
    margin: 0 auto 6px;
    padding: 2px 6px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--a);
    background: var(--surface);
    border: 1px solid color-mix(in srgb, var(--a) 55%, var(--stroke));
    border-radius: var(--r-sm);
  }
  .m-xtag i {
    width: 5px;
    height: 5px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--a);
    font-style: normal;
  }
  .m-stat b {
    display: block;
    font-family: var(--font-display, "Space Grotesk", sans-serif);
    font-size: 1rem;                       /* 16px — tile-scoped 20% step-down */
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.02em;
    color: #fff;
    text-align: left;
    padding-left: 8px;                     /* 1 extra space from left edge */
  }
  .m-xbar {
    display: block;
    width: 24px;
    height: 2px;
    border-radius: 2px;
    background: var(--a);
    margin: 10px 0 12px 8px;               /* same 1-space left indent */
    font-style: normal;
  }
  .m-stat span:not(.m-xtag):not(.m-verify) {
    display: block;
    margin-top: 6px;
    padding-left: 8px;                     /* same 1-space left indent */
    font-size: var(--fs-micro);
    line-height: 1.45;
    text-align: left;
    color: var(--muted-2);
  }
  .m-xbar + span { margin-top: 0; }
  /* Verify mini-pill: lives on the NUMBER (b), inline right after
     "Top 1%" / "Top 5%". ~50% smaller box than before; 10px is the
     legibility floor. The whole tile is the link; the pill is a visual
     affordance, not the tap target. */
  .m-stat.is-link > b::after, .m-verify {
    display: inline-flex; align-items: center; height: 18px;
    box-sizing: border-box;
    margin-left: 6px; padding: 2px 7px;
    font-size: 0.625rem; font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    vertical-align: middle;
    color: var(--text);
    background: var(--surface);
    border: 1px solid color-mix(in srgb, var(--accent) 44%, var(--stroke));
    border-radius: 8px;
  }
  .m-stat.is-link > b::after { content: "Verify ↗"; }
  /* Featured (first) tile: real pill + KC7 tag sit inline on the number
     line — Top 1% [Verify] [KC7] — so the ::after pill is suppressed
     there to avoid a double Verify. */
  .m-stats > :first-child .m-xtag {
    display: inline-flex;
    margin: 0 0 0 6px;
    vertical-align: middle;
  }
  .m-stats > :first-child.m-stat.is-link > b::after { content: none; }

  /* ── 3 · SELECTED WORK ──────────────────────────────────── */
  .mproj {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 8px;
  }
  .mproj-card {
    display: block;
    width: 100%;
    padding: 0;
    text-align: left;
    font: inherit;
    color: inherit;
    cursor: pointer;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--stroke-soft);
    border-radius: 0;
    overflow: hidden;
    -webkit-tap-highlight-color: transparent;
  }
  .mproj-card.m-featured {
    background: color-mix(in srgb, var(--surface) 35%, #05070d);
    border: 1px solid var(--stroke);
    border-radius: var(--r-sm);
    margin-bottom: 0;
  }
  .mproj-media { display: block; overflow: hidden; background: var(--surface); }
  /* Full screenshot, never a zoom-crop: the featured shot keeps its
     natural aspect and row thumbs letterbox (contain) on the surface,
     so every dashboard reads at its original size and ratio. */
  .mproj-card.m-featured .mproj-media { aspect-ratio: auto; }
  .mproj-card.m-featured .mproj-media img { height: auto; }
  .mproj-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
    background: var(--surface);
  }
  .mproj-body { display: block; padding: 0.8rem 0; }
  .m-featured .mproj-body { padding: 0.9rem 1rem 1rem; }
  .mproj-title {
    display: block;
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--text);
  }
  /* ══ UNIFIED CHIP SYSTEM (from scratch) — projects · cases · certs ══
     Every chip on the page shares ONE geometry: 28px tall, 12px/500
     mono uppercase, solid surface fill, hairline accent edge. Contexts
     differ ONLY in text color. Containers are flex clouds (6px gap):
     identical with JS pills or no-JS fallback text. */
  .mproj-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px;
    margin-top: 10px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-chip);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted-2);
  }
  /* Row thumbs: ROOT-CAUSE fix. A 64px box turns every dashboard
     into an illegible sliver, whatever the fit. Thumbs are width-
     locked (104px) with natural height instead — zero crop, zero
     distortion, every screenshot fully visible at original ratio. */
  /* Rows top-anchor: thumbs run 45–81px tall against text columns
     up to ~90px. Center-gluing floated small thumbs at the vertical
     middle (up to 36px below the title) — the ragged look. Pinning
     both columns to the top gives every row one clean start line. */
  /* Sub-project rows are cards too: darker box, hairline edge,
     12/16px inner air. Text and thumb both pin to the card's padding
     edge (body padding and thumb offset → 0). */
  .m-project-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 104px;
    align-items: start;
    gap: 16px;
    background: color-mix(in srgb, var(--surface) 35%, #05070d);
    border: 1px solid var(--stroke);
    border-radius: var(--r-sm);
    padding: 12px 16px;
    text-align: left;
  }
  .m-project-row .mproj-media {
    width: 104px;
    height: auto;
    order: 2;
    margin-top: 0;
    border-radius: 8px;
    border: 1px solid var(--stroke);
  }
  .m-project-row .mproj-body { order: 1; padding: 0; }
  .m-project-row .mproj-title { font-size: var(--fs-body); font-weight: 500; }
  /* Project blurbs: 2-line clamp, small muted voice between title and tags. */
  .mproj-desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 6px;
    font-size: var(--fs-small);
    line-height: 1.45;
    color: var(--muted-2);
  }
  /* Project tags ~50% smaller than the shared chip: scoped to #m-work
     only, so case-file and achievement chips keep their full size. */
  #m-work .mproj-meta { gap: 6px; margin-top: 8px; }
  #m-work .m-tag {
    min-height: 20px;
    padding: 3px 8px;
    margin: 0 6px 6px 0;
    font-size: 0.625rem;
    letter-spacing: 0.06em;
    line-height: 1.3;
    border-radius: 8px;
  }
  .mproj-card:active { border-color: var(--accent); }

  /* ── 4 · THE LAB ────────────────────────────────────────── */
  /* One accent, not five. Desktop layer colours formed a categorical
     system; five competing hues read as noise on a phone. Hierarchy now
     comes from the layer name and the Hunts line, not from colour. */
  .m-layers li { --lc: var(--accent); }
  .m-layers {
    list-style: none;
    margin: 24px 0 0;
    padding: 0;
    border-top: 1px solid var(--stroke-soft);
  }
  .m-layers li {
    position: relative;
    display: block;
    padding: 16px 0 16px 16px;
    border-bottom: 1px solid var(--stroke-soft);
  }
  .m-layers li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 16px;
    bottom: 16px;
    width: 2px;
    border-radius: 2px;
    background: var(--lc);
    opacity: 0.9;
  }
  .m-layers b {
    display: block;
    font-size: var(--fs-body);
    font-weight: 600;
    color: var(--text);
  }
  .m-layers span {
    display: block;
    margin-top: 6px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted-2);
    line-height: 1.5;
  }
  .m-layers em {                                  /* hunts line — the highlight */
    display: block;
    margin-top: 6px;
    font-family: var(--font-mono, monospace);
    font-style: normal;
    font-size: var(--fs-micro);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-hi);
    line-height: 1.5;
  }
  .m-layers em::before {
    content: "Hunts ";
    color: var(--muted-2);
  }

  /* ── 5 · BACKGROUND ─────────────────────────────────────── */
  /* The job card is .m-job, NOT .m-role — .m-role is the hero's
     role line up in §3 and a second rule for it here would pull
     that line's margin out of shape. */
  .m-job { margin-top: 1.6rem; }
  .m-job-date {
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent-hi);
    margin: 0 0 6px;
  }
  .m-job h3 {
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.01em;
    color: var(--text);
    margin: 0;
  }
  .m-job-sub {
    font-size: var(--fs-small);
    color: var(--muted-2);
    margin: 4px 0 0;
  }
  .m-bullets {
    list-style: none;
    margin: 16px 0 0;
    padding: 0;
    display: grid;
    gap: 10px;
  }
  .m-bullets li {
    position: relative;
    padding-left: 16px;
    font-size: var(--fs-body);
    line-height: 1.6;
    color: var(--copy);
  }
  .m-bullets li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.65em;
    width: 5px;
    height: 1px;
    background: var(--accent);
  }

  /* Certs mirror the case cards: separated darker boxes, 8px apart. */
  .m-certs {
    list-style: none;
    margin: 16px 0 0;
    padding: 0;
    display: grid;
    gap: 8px;
  }
  .m-certs > li {
    background: color-mix(in srgb, var(--surface) 35%, #05070d);
    border: 1px solid var(--stroke);
    border-radius: var(--r-sm);
  }
  .m-certs a {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
    padding: 14px 16px;
    text-decoration: none;
  }
  .m-certs b {
    flex: 1 1 100%;
    min-width: 0;
    font-size: var(--fs-body);
    font-weight: 500;
    line-height: 1.35;
    color: var(--text-2);
  }
  .m-certs span {
    flex: 1 1 100%;
    min-width: 0;
    font-size: var(--fs-small);
    color: var(--muted-2);
  }
  /* Cert date: neutral chip voice, right-pinned in its grid cell. */
  .m-certs i {
    display: inline-flex;
    align-items: center;
    height: 34px;
    box-sizing: border-box;
    margin-top: 2px;
    padding: 8px 14px;
    font-family: var(--font-mono, monospace);
    font-style: normal;
    font-size: var(--fs-chip);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--text-2);
    background: var(--surface);
    border: 1px solid var(--stroke);
    border-radius: var(--r-sm);
    white-space: nowrap;
  }
  .m-certs a:active b { color: var(--accent-hi); }
  .m-certs a::after {                              /* little verify button */
    content: "Verify ↗";
    display: inline-flex; align-items: center; height: 34px;
    box-sizing: border-box;
    margin-top: 2px; padding: 8px 14px;
    font-family: var(--font-mono, monospace); font-size: var(--fs-chip);
    font-weight: 500;
    letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap;
    color: var(--text);
    background: var(--surface);
    border: 1px solid color-mix(in srgb, var(--accent) 44%, var(--stroke));
    border-radius: var(--r-sm);
  }

  .m-edu {
    margin-top: 14px;
    padding: 16px;
    border: 1px solid var(--stroke);
    border-radius: var(--r-sm);
  }
  .m-edu b {
    display: block;
    font-size: var(--fs-body);
    font-weight: 500;
    line-height: 1.35;
    color: var(--text-2);
  }
  .m-edu span {
    display: block;
    margin-top: 5px;
    font-size: var(--fs-small);
    color: var(--muted-2);
  }
  .m-edu i {
    display: block;
    margin-top: 8px;
    font-family: var(--font-mono, monospace);
    font-style: normal;
    font-size: var(--fs-micro);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
  }

  #m-background .m-btn-full { margin-top: 28px; }

  /* ── 6 · FIELD REPORTS ──────────────────────────────────── */
  /* Seven rows is a wall on a phone. JS adds .m-cases-collapsed and
     the list shows the newest four; the toggle reveals the rest.
     With no JS the class never lands, so the button stays hidden
     (see the sibling rule below) and every case remains visible. */
  /* Cases are SEPARATED CARDS, not hairline rows: each <li> is its
     own surface box (the BCA-card language) with 8px of air between,
     so boxes never touch and content never crowds a divider. */
  .m-cases {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 8px;
  }
  .m-cases > li {
    background: color-mix(in srgb, var(--surface) 35%, #05070d);
    border: 1px solid var(--stroke);
    border-radius: var(--r-sm);
  }
  .m-cases.m-cases-collapsed > li:nth-child(n+5) { display: none; }
  .m-cases a {
    display: block;
    padding: 16px;
    text-decoration: none;
  }
  /* Accent voice: case IDs. Same edu-card rounded rect — only the
     text color speaks. */
  .m-case-id {
    display: inline-flex;
    align-items: center;
    height: 34px;
    box-sizing: border-box;
    margin-bottom: 8px;
    padding: 8px 14px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-chip);
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    white-space: normal;
    text-align: center;
    line-height: 1.35;
    overflow-wrap: break-word;
    color: var(--accent-hi);
    background: var(--surface);
    border: 1px solid color-mix(in srgb, var(--accent) 52%, var(--stroke));
    border-radius: var(--r-sm);
  }
  .m-cases b {
    position: relative;
    display: block;
    padding-right: 28px;
    font-size: var(--fs-body);
    font-weight: 500;
    line-height: 1.4;
    color: var(--text-2);
  }
  /* Arrow lives ON the title, not the card: it centers against the
     1–2 line title block, so tag-cloud height can never drag it away.
     Absolute (not flex) = nothing to wrap or shrink, ever. */
  .m-cases b::after {
    content: "→";
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    font-size: var(--fs-small);
    color: var(--muted-2);
  }
  .m-cases a:active b::after { color: var(--accent-hi); }
  /* Same flex-cloud container as .mproj-meta: one gap, one margin. */
  .m-case-tag {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px;
    margin-top: 10px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-chip);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted-2);
  }
  /* Neutral voice: tech tags. SHAPE mirrors the education card
     (rounded rect, not pill). Separation is MARGINS, not flex gap —
     margins work in every browser, with or without gap support. */
  .m-tag {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
    box-sizing: border-box;
    padding: 8px 14px;
    margin: 0 8px 8px 0;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-chip);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    max-width: 100%;
    line-height: 1.35;
    text-align: center;
    overflow-wrap: break-word;
    color: var(--text-2);
    background: var(--surface);
    border: 1px solid color-mix(in srgb, var(--accent) 52%, var(--stroke));
    border-radius: var(--r-sm);
  }
  /* GPU-consistent raster for every chip: letter-spacing makes chip
     boxes fractional-width (58.25px etc.), and hairline borders on
     fractional boxes antialias unevenly per corner. One composited
     layer per chip = identical raster everywhere. (Audit: chips use a
     SINGLE border property — no ::before/::after glow, no gradient
     trick, no box-shadow on any chip — so there is no layer geometry
     to sync; the seam is purely sub-pixel rasterization.) */
  /* GPU-consistent raster + inflation lock: phones auto-enlarge
     small text (font boosting), which bursts fixed chip boxes. Locking
     text-size-adjust keeps specified sizes so air survives everywhere. */
  .m-tag, .m-case-id, .m-certs i,
  .m-cases b::after, .m-certs a::after,
  .m-stat.is-link > b::after, .m-verify,
  .m-stat .m-xtag, .mobile-pill::before {
    transform: translateZ(0);
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }
  /* (stray margin rule removed — the unified container above owns it) */
  .m-cases a:active b { color: var(--accent-hi); }

  .m-cases-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 44px;
    margin-top: 14px;
    border: 1px solid color-mix(in srgb, var(--accent) 44%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent) 10%, transparent);
    color: var(--text);
    font-family: inherit;
    font-size: var(--fs-small);
    font-weight: 500;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }
  .m-cases.m-cases-collapsed + .m-cases-toggle { display: flex; }
  .m-cases-toggle:active { border-color: var(--accent-hi); }

  .m-more {
    display: inline-block;
    margin-top: 20px;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent-hi);
    text-decoration: none;
  }

  /* ── 7 · CONTACT ────────────────────────────────────────── */
  /* Dark-mode fields vanish without a fill and a border that clears
     3:1 against the page. A lighter surface fill plus a brighter
     stroke gives the field a visible edge before focus, so the form
     reads as a form and not as free-floating placeholder text. */
  .m-form {
    display: grid;
    gap: 12px;
    margin-top: 20px;
  }
  .m-form input:not([type="hidden"]),
  .m-form textarea {
    width: 100%;
    padding: 14px 16px;
    background: color-mix(in srgb, var(--surface) 82%, #ffffff 5%);
    border: 1px solid color-mix(in srgb, var(--stroke) 60%, var(--muted-2));
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 1rem;            /* 16px — stops iOS zoom-on-focus */
    line-height: 1.45;
    color: var(--text);
    outline: none;
    -webkit-appearance: none;
    appearance: none;
    transition: border-color var(--quick) var(--ease), background var(--quick) var(--ease);
  }
  .m-form textarea { resize: none; }
  .m-form input::placeholder,
  .m-form textarea::placeholder { color: var(--muted-2); }
  .m-form input:focus,
  .m-form textarea:focus {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--surface) 88%, #ffffff 8%);
  }
  .m-form button {
    min-height: 48px;
    margin-top: 4px;
    border: 0;
    border-radius: 999px;
    background: var(--gradient-accent);
    color: #fff;
    font-family: inherit;
    font-size: var(--fs-small);
    font-weight: 600;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }
  .m-form button:disabled { opacity: 0.6; }
  .m-form .m-sent {
    padding: 24px 0;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-small);
    color: var(--accent-hi);
    text-align: center;
  }
  .m-form .form-err {
    margin: 0;
    color: var(--sev-low);
    font-size: var(--fs-small);
    line-height: 1.4;
  }

  .m-socials {
    display: flex;
    gap: 0.5rem;
    margin-top: 1.6rem;
  }
  .m-socials a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border: 1px solid var(--stroke);
    border-radius: 999px;
    color: var(--muted-2);
    transition: color var(--quick) var(--ease), border-color var(--quick) var(--ease);
  }
  .m-socials a:active { color: var(--accent); border-color: var(--accent); }
  .m-socials svg { width: 17px; height: 17px; }

  .m-foot {
    margin: 28px 0 0;
    font-family: var(--font-mono, monospace);
    font-size: var(--fs-micro);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--muted-2);
  }
  #m-contact .m-body + .m-btn-full { margin-top: 20px; }
  /* Foot carries no bottom margin — trim the 48px block pad to a
     hairline so the page ends right below the Meerut line. */
  #m-contact { padding-bottom: 6px; }

  /* ----------------------------------------------------------
     6 · CASE SHEET — the one desktop overlay a phone keeps
     ---------------------------------------------------------- */
  #case-modal.bottom-sheet #cm-box {
    border-radius: 20px 20px 0 0 !important;
    border: 0 !important;
    border-top: 1px solid var(--stroke) !important;
    background: var(--surface) !important;
    box-shadow: none !important;
    max-height: 88dvh;
  }
  #case-modal.bottom-sheet #cm-box::before {
    content: "";
    display: block;
    width: 34px;
    height: 3px;
    margin: 0.7rem auto 0;
    border-radius: 999px;
    background: var(--stroke);
  }
  #cm-title { font-size: 1.05rem !important; }
  #cm-body { padding: 1.1rem 1.25rem 1.6rem !important; }
  #cm-body img { border-radius: var(--r-sm); }

  /* ----------------------------------------------------------
     8 · AMBIENT — atmosphere from existing tokens only.
     No new hues: accent/gradient tints ≤7%, static (no JS, no
     animation) so the cost is one composite. Flat stays flat —
     this is a wash of light, not a glow effect.
     ---------------------------------------------------------- */
  .m-hero { position: relative; overflow: clip; }
  .m-hero::before {                                  /* desktop grid echo */
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background-image:
      linear-gradient(rgba(96, 165, 250, 0.07) 1px, transparent 1px),
      linear-gradient(90deg, rgba(96, 165, 250, 0.07) 1px, transparent 1px);
    background-size: 34px 34px;
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 82%);
    mask-image: linear-gradient(to bottom, #000 0%, transparent 82%);
  }
  .m-hero::after {                                   /* tint behind the name */
    content: ""; position: absolute; top: -5rem; left: 50%;
    transform: translateX(-50%); width: 22rem; height: 17rem;
    pointer-events: none;
    background: radial-gradient(closest-side, rgba(59, 130, 246, 0.10), transparent 70%);
  }
  .m-hero > * { position: relative; }                /* content above the wash */
  #m-work, #m-lab, #m-background, #m-certs, #m-reports, #m-contact { position: relative; }
  #m-work::before, #m-lab::before, #m-background::before, #m-certs::before,
  #m-reports::before, #m-contact::before {           /* anchor wash per block */
    content: ""; position: absolute; top: 0; left: 50%;
    transform: translateX(-50%); width: 20rem; height: 12rem;
    pointer-events: none;
    background: radial-gradient(closest-side, rgba(59, 130, 246, 0.08), transparent 70%);
  }
  .m-head { position: relative; }
  .m-head::after {                                   /* gradient seam under head */
    content: ""; display: block; width: 2.75rem; height: 1px;
    margin-top: 0.8rem; opacity: 0.7;
    background: linear-gradient(90deg, var(--accent), transparent);
  }

  /* ----------------------------------------------------------
     9 · ENTRANCES — fade-up on scroll, one-shot.
     Hidden state applies ONLY under .m-motion, which mobile.js
     adds when IO exists and reduced-motion is off. No JS, no IO,
     or reduced-motion → content renders normally, never hidden.
     ---------------------------------------------------------- */
  .m-motion .m-hero > *, .m-motion .m-stat, .m-motion .mproj-card,
  .m-motion .m-layers li, .m-motion .m-cases li, .m-motion .m-certs li,
  .m-motion #m-background .m-job, .m-motion #m-certs .m-certs,
  .m-motion #m-background .m-edu, .m-motion #m-background .m-btn-full,
  .m-motion .m-form > *, .m-motion .m-socials {
    opacity: 0; transform: translateY(10px);
    transition: opacity 280ms var(--ease), transform 280ms var(--ease);
  }
  .m-motion .m-stats > :nth-child(2), .m-motion .mproj > :nth-child(2),
  .m-motion .m-layers > :nth-child(2), .m-motion .m-cases > :nth-child(2) { transition-delay: 60ms; }
  .m-motion .m-stats > :nth-child(n+3), .m-motion .mproj > :nth-child(n+3),
  .m-motion .m-layers > :nth-child(n+3), .m-motion .m-cases > :nth-child(n+3) { transition-delay: 120ms; }
  .m-motion .is-in { opacity: 1 !important; transform: none !important; }

  /* ----------------------------------------------------------
     10 · SIGNATURE — small static portrait, contact only.
     Brand continuity with the desktop portrait; lazy + async so
     it never blocks first paint.
     ---------------------------------------------------------- */
  /* Portrait retired from mobile — its float/glow language now
     lives on every button (§12 below). */

  /* ----------------------------------------------------------
     11 · VISIBLE EFFECTS — glow, sheen, float, pop.
     Transform/opacity only. Accent-derived tints, zero new hues.
     Loops are slow and few (3). Reduced-motion (§7) kills all.
     ---------------------------------------------------------- */
  /* primary CTA glow — omnidirectional + travelling sheen removed */
  .m-ctas .m-btn-solid, #m-background .m-btn-full, .m-form button {
    position: relative; overflow: hidden;
    box-shadow:
      0 0 22px rgba(59, 130, 246, 0.24),
      0 0 44px rgba(59, 130, 246, 0.11),
      inset 0 1px 0 rgba(255, 255, 255, 0.14);
  }
  /* Sheen sweep removed per owner — glow + drift carry the light. */
  .m-ctas .m-btn, .m-form button {
    transition: opacity var(--quick) var(--ease), transform var(--quick) var(--ease), box-shadow var(--d-base, 280ms) var(--ease);
  }
  .m-ctas .m-btn:active, .m-form button:active { transform: scale(.97); }
  /* live dot ping */
  .m-dot { animation: m-ping 2.4s ease-out infinite; }
  @keyframes m-ping {
    0%, 100% { box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.16); }
    50% { box-shadow: 0 0 0 7px rgba(34, 197, 94, 0); }
  }
  /* case sheet pops on every open */
  #case-modal.bottom-sheet.open #cm-box { animation: m-sheet-in 320ms var(--ease); }
  @keyframes m-sheet-in {
    from { opacity: 0; transform: translateY(26px); }
    to { opacity: 1; transform: none; }
  }
  /* press glows on cards + rows */
  .mproj-card {
    transition: border-color var(--quick) var(--ease), transform var(--quick) var(--ease), box-shadow var(--d-base, 280ms) var(--ease);
  }
  .mproj-card:active {
    border-color: var(--accent);
    box-shadow:
      0 0 20px rgba(59, 130, 246, 0.28),
      0 0 40px rgba(59, 130, 246, 0.12);
    transform: scale(.985);
  }
  .m-cases a:active, .m-certs a:active { border-color: var(--stroke-strong); }

  /* ----------------------------------------------------------
     12 · EVERY BUTTON breathes light. Omnidirectional glow on
     all 4 sides + non-uniform drift so same-row items never bob
     in sync. Each element type gets its own drift cadence + per-
     nth-child offset. translate-property drift composes with
     :active scale (no transform fight). Reduced-motion (§8)
     kills every loop below.
     ---------------------------------------------------------- */
  .m-btn, .mproj-card, .m-socials a, .mobile-pill,
  .lab-tab, .did-touch-btn, .m-stat.is-link,
  .m-cases a, .m-certs a, .m-form button {
    position: relative;
    overflow: hidden;
    box-shadow:
      0 0 18px rgba(59, 130, 246, 0.22),
      0 0 36px rgba(59, 130, 246, 0.10),
      inset 0 1px 0 rgba(255, 255, 255, 0.10);
  }
  /* hero CTAs — fast light drift */
  .m-ctas .m-btn { animation: m-drift-a 5.8s ease-in-out infinite; }
  .m-ctas .m-btn:nth-child(2) { animation-delay: 0.9s; }
  /* stat tiles — medium drift */
  .m-stat.is-link { animation: m-drift-b 6.4s ease-in-out infinite; }
  .m-stat.is-link:nth-child(2) { animation-delay: 0.6s; }
  .m-stat.is-link:nth-child(n+3) { animation-delay: 1.3s; }
  /* project / case / cert ROWS stay static on purpose: they carry
     the hairline chip pills, and fractional drift offsets rasterize
     1px borders + 999px corners unevenly (some crisp, some shimmer).
     Ambient motion lives on buttons, tiles and socials instead. */
  /* socials — quick light flutter */
  .m-socials a { animation: m-drift-a 5.2s ease-in-out infinite; }
  .m-socials a:nth-child(2) { animation-delay: 0.7s; }
  .m-socials a:nth-child(3) { animation-delay: 1.4s; }
  /* pills + chips — tiny bob */
  .mobile-pill, .did-touch-btn { animation: m-drift-e 5.5s ease-in-out infinite; }
  .mobile-pill:nth-child(2), .did-touch-btn:nth-child(2) { animation-delay: 0.4s; }
  .mobile-pill:nth-child(n+3), .did-touch-btn:nth-child(n+3) { animation-delay: 1.0s; }
  .mobile-pill:nth-child(n+5), .did-touch-btn:nth-child(n+5) { animation-delay: 1.8s; }
  /* lab tabs — steady slow drift */
  .lab-tab { animation: m-drift-b 6.8s ease-in-out infinite; }
  .lab-tab:nth-child(2) { animation-delay: 0.5s; }
  .lab-tab:nth-child(3) { animation-delay: 1.0s; }
  .lab-tab:nth-child(4) { animation-delay: 1.5s; }
  .lab-tab:nth-child(5) { animation-delay: 2.0s; }
  /* form + background CTA — deep slow */
  .m-form button, #m-background .m-btn-full { animation: m-drift-c 7.0s ease-in-out infinite; }
  .m-form button:nth-child(2) { animation-delay: 0.8s; }
  /* five unique drift keyframes — non-uniform distance + curve */
  @keyframes m-drift-a {
    0%, 100% { translate: 0 0; }
    35% { translate: 0 -3px; }
    70% { translate: 0 -1px; }
  }
  @keyframes m-drift-b {
    0%, 100% { translate: 0 0; }
    50% { translate: 0 -2.5px; }
  }
  @keyframes m-drift-c {
    0%, 100% { translate: 0 0; }
    40% { translate: 0 -4px; }
    80% { translate: 0 -1.5px; }
  }
  @keyframes m-drift-d {
    0%, 100% { translate: 0 0; }
    55% { translate: 0 -2px; }
  }
  @keyframes m-drift-e {
    0%, 100% { translate: 0 0; }
    45% { translate: 0 -1.5px; }
  }

  /* ── 8 · REDUCED MOTION ─────────────────────────────────── */
  @media (prefers-reduced-motion: reduce) {
    :root { --quick: 0s; }
    html { scroll-behavior: auto; }
    #mobile-menu, #mobile-menu .menu-panel { transition: none !important; }
    .m-hero::before, .m-hero::after,
    #m-work::before, #m-lab::before, #m-background::before,
    #m-reports::before, #m-contact::before { display: none; }
    .m-dot { animation: none !important; }
    .m-btn, .mproj-card, .m-cases a, .m-certs a, .m-socials a,
    .mobile-pill, .lab-tab, .did-touch-btn, .m-stat.is-link,
    .m-form button, #m-background .m-btn-full { animation: none !important; }
    #case-modal.bottom-sheet.open #cm-box { animation: none !important; }
  }
}

/* Fresh live-mobile finish pass: STRUCTURAL rules only.
   Type, spacing and rhythm live in the main block above (tokens);
   this layer keeps layout intent — grid shape, featured span,
   tap-target floors, focus visibility — and declares no font-size
   or padding literals, so the two layers can never fight again. */
@media (max-width: 768px) {
  #m-page .m-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #m-page .m-stats > :nth-child(5) { display: none; }
  #m-page .m-stats > :first-child {
    grid-column: 1 / -1;
    text-align: left;
  }

  #m-page .m-certs a { min-height: 3.6rem; }

  /* The `hidden` attribute must survive the sibling display rule:
     with no JS the toggle stays hidden and every case stays visible. */
  #m-page .m-cases-toggle[hidden] { display: none !important; }
  #m-page .mproj-card:focus-visible,
  #m-page .m-cases a:focus-visible,
  #m-page .m-btn:focus-visible,
  #m-page .m-certs a:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 3px; }

}

/* ============================================================
   Very narrow phones — one column for everything.
   ============================================================ */
@media (max-width: 374px) {
  .m-stats { grid-template-columns: minmax(0, 1fr); }
  .m-stat:nth-child(odd) { padding-right: 0; border-right: 0; }
  .m-stat:nth-child(even) { padding-left: 0; }
  .m-ctas { flex-direction: column; }
  /* .m-strip stays single-column: its icon-led rows need full width. */
  .m-name { letter-spacing: -0.04em; }
}
