/* ===========================================================================
   WebDeviAnt — adapt
   How the site responds to its reader. Three modes, all driven by overriding
   a handful of custom properties rather than by maintaining parallel
   stylesheets — and none of them has a switch on it. A site that needs a
   user-facing escape hatch has already admitted its default is hostile.
   ========================================================================= */

/* --------------------------------------------------------- reduced motion --
   Not "slightly less motion" — none. The perpetual grid loop is the whole
   point of the objection: an infinite animation in the corner of the eye is
   exactly what triggers vestibular symptoms. The layout is identical either
   way, so nothing is lost but the movement.                                */

@media (prefers-reduced-motion: reduce) {
  :root { --dur: 0.001; }

  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }

  html { scroll-behavior: auto; }

  /* The floor stays as a static plane — the aesthetic survives, the motion
     does not. */
  .baseline__tiles { animation: none; }
  .hero__mark { animation: none; rotate: 0turn; opacity: 1; scale: 1; }

  .reveal { opacity: 1; transform: none; }
  .reveal.is-in > * { animation: none; }
  .btn:hover { transform: none; }
}

/* ----------------------------------------------------------- more contrast --
   Raise the dim greys, harden every hairline, and drop the glows. The neon
   stays because it is already 14:1 — it is the greys that fail people.     */

@media (prefers-contrast: more) {
  :root {
    --fg-dim:      #c9d4de;
    --fg-faint:    #a9b6c2;
    --rule:        #4a5560;
    --rule-strong: #6e7d8a;
    --past-text:   #cba8ff;
  }

  /* Must be on `body`: components.css declares --floor-intensity there, and a
     child's own declaration always beats an inherited one from :root, so the
     same rule written on :root would be silently inert. */
  body, body.is-lit { --floor-intensity: 0.1; }

  .wordmark .ant { text-shadow: none; }
  .baseline__horizon { box-shadow: none; }
  .btn--primary:hover { box-shadow: none; }
  .role--current::before { box-shadow: 0 0 0 4px var(--bg); }
}

/* Honour a user who has asked for a light UI, without shipping a whole
   second theme: the instrument inverts, the semantics stay put. */
@media (prefers-contrast: more) and (prefers-color-scheme: light) {
  :root {
    --bg:        #ffffff;
    --bg-raised: #f6f8fa;
    --bg-sunken: #ffffff;
    --fg:        #0d1117;
    --fg-dim:    #3d4650;
    --fg-faint:  #55606b;
    --live:      #1a7f37;
    --live-ink:  #ffffff;
    --past:      #6639ba;
    --past-text: #5b2ea6;
    --rule:      #b9c1ca;
    --rule-strong: #7b8794;
  }

  body, body.is-lit { --floor-intensity: 0.08; }
}

/* ------------------------------------------------------------------ print --
   The CV must print to a clean A4 without anyone reaching for a separate
   PDF. Ink on white, no chrome, no neon, links resolved to their URLs, and
   nothing allowed to break across a page mid-role.                         */

@media print {
  :root {
    --bg: #fff;
    --bg-raised: #fff;
    --bg-sunken: #fff;
    --fg: #000;
    --fg-dim: #333;
    --fg-faint: #555;
    --live: #000;
    --past: #000;
    --past-text: #333;
    --rule: #bbb;
    --rule-strong: #999;
    --sigma: 0.5rem;
    --m: 1.5rem;
  }

  @page {
    size: A4;
    margin: 14mm 14mm 16mm;
  }

  html { font-size: 10.5pt; }
  body {
    background: #fff !important;
    color: #000;
    line-height: 1.45;
  }

  /* Chrome, atmosphere and anything interactive is not part of a document. */
  .baseline,
  .rail,
  .skip-link,
  .footer__socials,
  .no-print,
  .copy-btn,
  .btn,
  form,
  .plot,
  /* Both are painted as a background through a mask, and print drops
     background graphics — they would reserve space and render nothing.
     The profile URLs beside them are plain text and survive. */
  .icon,
  .mark { display: none !important; }

  .section { padding-block: 0 var(--m-3); break-inside: auto; }
  .hero { min-height: 0; padding-block: 0 var(--m-3); display: block; }
  .hero__mark { display: none; }

  a { color: #000; text-decoration: none; }

  /* Resolve links so a printed CV is still actionable. Skip in-page anchors,
     and skip mailto/tel where the visible text is already the address. */
  .prose a[href^='http']::after,
  .role a[href^='http']::after {
    content: ' <' attr(href) '>';
    font-size: 0.85em;
    color: #555;
    word-break: break-all;
  }

  /* A role split across a page break is unreadable. */
  .role,
  .cap,
  .card,
  .stat { break-inside: avoid; }

  h1, h2, h3 { break-after: avoid; }

  .reveal { opacity: 1 !important; transform: none !important; }
  .reveal.is-in > * { animation: none !important; }

  .timeline::before { background: #999; }
  .role::before { background: #000 !important; box-shadow: none !important; }
  .role--deviant { border-left-color: #999; }

  .tools { border-color: #ccc; }
  .tool img { filter: grayscale(1) !important; opacity: 1; }

  /* Print-only contact block, so the paper copy carries the details that
     live in the header rail on screen. */
  .print-only { display: block !important; }
}

.print-only { display: none; }

/* Data-saver: drop the perpetual animation and the backdrop blur, which are
   the two things on the page with an ongoing cost. */
@media (prefers-reduced-data: reduce) {
  .baseline__tiles { animation: none; }
  .rail { backdrop-filter: none; background: var(--bg); }
}
