/* ============================================================
   Margin, product page
   ------------------------------------------------------------
   The page is set the way the app sets a document: one sheet of
   warm paper, a real margin column with marginalia hanging off a
   printed rule, ink for everything, vermilion only as a mark.

   Tokens are the app's own (Margin docs/research/identity-paper-
   and-margin.md). They are page-scoped: the site's ink/paper/gold
   system still governs the header pill and everything off this
   page. Only the header is shared; the rest of this page owns
   its own type, colour and rhythm.
   ============================================================ */

@font-face {
  font-family: "iA Writer Quattro S";
  src: url("/assets/fonts/iawriterquattros-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "iA Writer Quattro S";
  src: url("/assets/fonts/iawriterquattros-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "iA Writer Quattro S";
  src: url("/assets/fonts/iawriterquattros-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

.mg-page {
  /* Surfaces */
  --paper: #f2f0e9;
  --slip: #eceae2;
  --night: #1a1815;

  /* Ink */
  --ink: #26231d;
  --ink-2: #666156;
  --night-ink: #e4dfd3;
  --night-body: #d7d1c4;
  --night-ink-2: #a39d90;
  --night-rule: rgba(228, 223, 211, 0.09);

  /* The one colour */
  --vermilion: #b5513c;
  --vermilion-text: #a8462f;

  /* Lines */
  --hair: rgba(38, 35, 29, 0.1);
  --rule: rgba(38, 35, 29, 0.07);

  /* Type */
  --face: "iA Writer Quattro S", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* Space (4pt base) */
  --s1: 4px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s8: 64px;
  --s9: 96px;
  --section: clamp(88px, 10.5vw, 152px);

  /* Grid */
  --shell: 1240px;
  --pad: clamp(20px, 4.4vw, 56px);
  --margin-col: 15.5rem;
  --gutter: clamp(28px, 3.6vw, 56px);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- Page ground ------------------------------------ */

body.sp-page.mg-page {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--face);
  font-size: 1.1875rem;
  line-height: 1.62;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
}

.mg-page ::selection {
  background: rgba(181, 81, 60, 0.18);
  color: var(--ink);
}

.mg-page :focus-visible {
  outline: 2px solid var(--vermilion);
  outline-offset: 3px;
  border-radius: 3px;
}

.mg-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 12px 18px;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.875rem;
}

.mg-skip:focus {
  left: 12px;
  top: 12px;
}

/* The site header keeps its shape; only the call to action changes,
   because on this page the thing to do is buy an app, not start a
   consulting conversation. */
.mg-page .nav-cta {
  font-variant-numeric: tabular-nums;
}

/* ---------- Grid: a margin column and a text column ---------- */

.mg-wrap {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.mg-spread {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s5);
}

@media (min-width: 1080px) {
  .mg-spread {
    grid-template-columns: var(--margin-col) minmax(0, 1fr);
    column-gap: var(--gutter);
  }

  /* The printed rule: the same line the app draws at 26% across.
     It is here because the marginalia hang off it, not as ruling. */
  .mg-spread--ruled > .mg-margin {
    position: relative;
  }

  .mg-spread--ruled > .mg-margin::after {
    content: "";
    position: absolute;
    top: 0.35em;
    bottom: 0;
    right: calc(var(--gutter) / -2);
    width: 1px;
    background: var(--rule);
  }

  .mg-margin {
    grid-column: 1;
    text-align: right;
  }

  .mg-text {
    grid-column: 2;
  }
}

/* Marginalia: small, secondary, right-aligned against the rule, and
   italic, the way a printed gloss has always been set. It also keeps the
   page's own voice distinct from the app's UI text, which is roman. */
.mg-note {
  margin: 0;
  font-style: italic;
  font-size: 0.8125rem;
  line-height: 1.5;
  letter-spacing: 0.005em;
  color: var(--ink-2);
  text-wrap: pretty;
}

.mg-note + .mg-note {
  margin-top: var(--s4);
}

.mg-note--mark {
  position: relative;
}

@media (min-width: 1080px) {
  .mg-note--mark::before {
    content: "";
    position: absolute;
    top: 0.62em;
    right: calc(var(--gutter) / -2 - 1px);
    width: 11px;
    height: 2px;
    background: var(--vermilion);
  }
}

/* ---------- Type ------------------------------------------- */

.mg-page h1,
.mg-page h2 {
  font-family: var(--face);
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.015em;
  text-wrap: balance;
  margin-block: 0;
}

.mg-display {
  font-size: clamp(2.75rem, 6vw, 5.125rem);
  line-height: 1.045;
}

.mg-page h2 {
  font-size: clamp(1.9375rem, 3.5vw, 3.125rem);
  line-height: 1.08;
  letter-spacing: -0.013em;
}

.mg-page p {
  font-family: var(--face);
  margin-block: 0;
  text-wrap: pretty;
}

.mg-body {
  max-width: 34em;
  color: var(--ink);
}

.mg-body + .mg-body {
  margin-top: 1.1em;
}

.mg-lead {
  max-width: 33em;
  font-size: clamp(1.125rem, 1.35vw, 1.3125rem);
  line-height: 1.55;
  color: var(--ink);
}

.mg-caption {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 38em;
}

.mg-eyebrow {
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-2);
  font-weight: 400;
}

.mg-tnum {
  font-variant-numeric: tabular-nums;
}

.mg-page a.mg-link {
  color: var(--ink);
  border-bottom: 1px solid var(--vermilion);
  padding-bottom: 1px;
  transition: color 160ms var(--ease);
}

.mg-page a.mg-link:hover {
  color: var(--vermilion-text);
}

/* ---------- Buttons ---------------------------------------- */

.mg-cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s5);
}

.mg-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0 26px;
  border-radius: 10px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--face);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.005em;
  transition:
    background-color 180ms var(--ease),
    transform 120ms var(--ease);
}

.mg-btn:hover {
  background: #17150f;
}

.mg-btn:active {
  transform: scale(0.98);
}

.mg-btn--quiet {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--hair);
  font-weight: 400;
}

.mg-btn--quiet:hover {
  background: rgba(38, 35, 29, 0.04);
}

/* ---------- Support page CTA contrast fix -------------------- */
/* subpages.css's .sp-legal-stack article p a rule (v30, link-visibility fix
   for the legal/support pages) is more specific than .sp-btn-dark -- one more
   element in the selector beats one fewer class -- so it was winning and
   painting the "Email Margin support" button's own ink colour onto its ink
   background: a 1.00:1 button nobody could read. This page loads after
   subpages.css and only has to out-rank that one rule for its one button. */
.sp-legal-stack article p a.sp-btn {
  color: var(--sp-paper);
  text-decoration: none;
}

.sp-legal-stack article p a.sp-btn:hover {
  text-decoration: none;
}

/* ---------- Launch-state switch ----------------------------- */
/* Every store call to action on this page -- and on support/index.html,
   which loads this stylesheet too, for its own copy of the nav pill -- is
   written twice in the markup: a data-launch-el="live" node carrying the
   real apps.apple.com link, and a data-launch-el="pre" node carrying an
   honest stand-in (a mailto, or an on-page anchor to #buy). This is the only
   rule that decides which one renders, keyed off the single data-launch
   token on <body>; flipping that one attribute (in both HTML files) is the
   entire switch. It only ever hides the non-matching node, so the node that
   stays keeps whatever display value its own class already gives it
   (inline-flex button, list-item, inline span) instead of this rule having
   to know it. The :not([data-launch]) line is a fail-safe: an unset switch
   reads as pre-launch, never as a working store link. */
body[data-launch="pre"] [data-launch-el="live"],
body[data-launch="live"] [data-launch-el="pre"],
body:not([data-launch]) [data-launch-el="live"] {
  display: none !important;
}

/* ---------- Hero ------------------------------------------- */

/* The fold does the selling, so the block above the window is set to the
   tightest rhythm the type will carry: the headline stays at 82px and the
   window still clears 400px of itself above a 900px fold. */
.mg-hero {
  padding-top: clamp(84px, 9.6vh, 116px);
  padding-bottom: 0;
}

/* The margin cell stretches so the printed rule runs the height of the
   headline block, the way it runs the height of a page in the app. */
.mg-hero-head {
  align-items: stretch;
}

@media (min-width: 1080px) {
  .mg-hero-head > .mg-margin {
    padding-top: 1.5em;
  }

  .mg-hero-head .mg-text {
    position: relative;
  }

  .mg-note--cta {
    position: absolute;
    right: calc(100% + var(--gutter));
    bottom: 2px;
    width: var(--margin-col);
    margin-top: 0;
    text-align: right;
  }
}

.mg-hero .mg-display {
  margin-bottom: clamp(18px, 1.7vw, 24px);
  max-width: 15ch;
}

.mg-hero .mg-lead {
  margin-bottom: clamp(22px, 2vw, 28px);
}

.mg-hero-cta {
  margin-bottom: 0;
}

/* Price and requirement sit beside the button, not under it: one purchase
   line instead of two stacked ones. The flex row wraps them apart again
   when the button goes full width on a phone. */
.mg-hero-cta .mg-caption {
  margin: 0;
  max-width: 30em;
}

/* The second gloss. In the DOM it follows the button so a narrow page reads
   it as a footnote to the button; from 1080px up it hangs in the margin
   column beside the button, the way the annotations do on the plate. */
.mg-note--cta {
  margin-top: var(--s4);
}

/* The window. Large, straight on, no tilt, no glass. One layered
   shadow so the sheet sits on the page instead of floating over it. */
.mg-plate {
  /* figure carries a 40px UA margin; the plate is a full-width object. */
  margin: clamp(34px, 4vw, 58px) 0 0;
  border-radius: 12px;
  overflow: hidden;
  box-shadow:
    0 1px 2px rgba(38, 35, 29, 0.07),
    0 8px 20px rgba(38, 35, 29, 0.07),
    0 28px 60px rgba(38, 35, 29, 0.09);
}

.mg-plate img {
  width: 100%;
  height: auto;
  display: block;
}

.mg-hero .mg-plate {
  margin-top: clamp(26px, 2.6vw, 36px);
}

.mg-plate--dark {
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.3),
    0 10px 26px rgba(0, 0, 0, 0.34),
    0 34px 70px rgba(0, 0, 0, 0.32);
}

/* ---------- Sections --------------------------------------- */

.mg-section {
  padding-block: var(--section);
}

.mg-section--tight {
  padding-block: calc(var(--section) * 0.72);
}

.mg-page h2 + .mg-body,
.mg-page h2 + .mg-lead,
.mg-page h2 + .mg-facts {
  margin-top: clamp(18px, 2vw, 26px);
}

.mg-section .mg-plate {
  margin-top: clamp(36px, 4.4vw, 60px);
}

/* ---------- Annotated plate (typography) -------------------- */

.mg-annotated {
  position: relative;
}

.mg-annos {
  margin: var(--s5) 0 0;
  padding: 0;
  list-style: none;
}

.mg-annos li {
  position: relative;
  padding-left: 22px;
  font-style: italic;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-2);
}

.mg-annos li + li {
  margin-top: var(--s3);
}

.mg-annos li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 11px;
  height: 2px;
  background: var(--vermilion);
}

@media (min-width: 1080px) {
  /* On a wide page the annotations leave the list and hang in the
     margin beside the thing they describe, which is the whole idea. */
  .mg-annos {
    position: absolute;
    inset: 0;
    margin: 0;
  }

  .mg-annos li {
    position: absolute;
    right: calc(100% + var(--gutter));
    width: var(--margin-col);
    padding-left: 0;
    text-align: right;
  }

  .mg-annos li + li {
    margin-top: 0;
  }

  .mg-annos li::before {
    left: auto;
    right: calc(var(--gutter) / -2 - 1px);
  }

  .mg-anno-1 { top: 11%; }
  .mg-anno-2 { top: 29%; }
  .mg-anno-3 { top: 55%; }
  .mg-anno-4 { top: 88%; }
}

/* ---------- Plates and crops -------------------------------- */

.mg-crop img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 10px;
  border: 1px solid var(--hair);
}

.mg-crop {
  margin: 0;
}

/* A figure row: the plate in the text column, its gloss in the margin,
   which is the same arrangement the app uses for its own outline. */
.mg-figrow {
  margin-top: clamp(34px, 3.8vw, 54px);
}

@media (min-width: 1080px) {
  .mg-figrow > .mg-margin {
    padding-top: 0.2em;
  }
}

/* ---------- After dark ------------------------------------- */

.mg-dark {
  background: var(--night);
  color: var(--night-body);
  padding-block: var(--section);
}

.mg-dark h2 {
  color: var(--night-ink);
}

.mg-dark .mg-body,
.mg-dark .mg-note {
  color: var(--night-body);
}

.mg-dark .mg-note {
  color: var(--night-ink-2);
}

@media (min-width: 1080px) {
  .mg-dark .mg-spread--ruled > .mg-margin::after {
    background: var(--night-rule);
  }
}

/* ---------- Yours ------------------------------------------ */

.mg-facts {
  margin: clamp(28px, 3.4vw, 44px) 0 0;
  padding: 0;
  list-style: none;
  max-width: 34em;
}

.mg-facts li {
  padding-block: var(--s5);
  border-top: 1px solid var(--hair);
}

.mg-facts li:last-child {
  border-bottom: 1px solid var(--hair);
}

.mg-facts strong {
  display: block;
  font-weight: 700;
  letter-spacing: -0.005em;
}

.mg-facts span {
  display: block;
  margin-top: var(--s1);
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---------- Buy -------------------------------------------- */

.mg-buy {
  /* Full section rhythm above, a closing measure below: the slip used to
     run 152px of empty paper under a two-line caption before the footer
     hairline, which read as a dropped page rather than an ending. */
  background: var(--slip);
  padding-block: var(--section) clamp(52px, 6vw, 86px);
}

/* .mg-page p zeroes the block margins, so this needs the page class to win. */
.mg-page .mg-buy-note {
  margin-top: var(--s5);
}

/* The heading is the price and its condition together, so the document
   outline reads "$9.99 once, and it is yours to keep" rather than "$9.99". */
.mg-price-block {
  font-size: inherit;
  letter-spacing: normal;
}

.mg-price {
  display: block;
  font-size: clamp(3.5rem, 8vw, 6rem);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.mg-price-note {
  display: block;
  margin-top: var(--s3);
  font-size: 1.0625rem;
  font-weight: 400;
  letter-spacing: normal;
  color: var(--ink-2);
}

.mg-includes {
  margin: clamp(26px, 3vw, 38px) 0 clamp(30px, 3.4vw, 42px);
  padding: 0;
  list-style: none;
  max-width: 34em;
}

.mg-includes li {
  padding-block: var(--s4);
  border-bottom: 1px solid var(--hair);
  font-size: 1rem;
  line-height: 1.5;
}

.mg-includes li:first-child {
  border-top: 1px solid var(--hair);
}

/* ---------- Footer ----------------------------------------- */

.mg-foot {
  border-top: 1px solid var(--hair);
  padding-block: var(--s8) var(--s9);
}

.mg-foot-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s5);
  font-size: 0.9375rem;
}

.mg-foot nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s6);
}

.mg-foot a {
  color: var(--ink-2);
  padding-block: 8px;
  transition: color 160ms var(--ease);
}

.mg-foot a:hover {
  color: var(--ink);
}

.mg-foot-made {
  color: var(--ink-2);
}

/* ---------- Motion ----------------------------------------- */
/* Everything above is visible with no JavaScript. The reveal only
   exists once the inline head script has set html.js, so a headless
   render or a blocked script never ships a blank section. */

.js [data-mg-reveal] {
  opacity: 0;
  transform: translateY(11px);
  transition:
    opacity 300ms var(--ease),
    transform 300ms var(--ease);
}

.js [data-mg-reveal].is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  /* subpages.css sets scroll-behavior: smooth on html. margin.css loads
     after it, so this equal-specificity rule wins, and it only exists on
     this page. In-page jumps land instantly instead of gliding. */
  html {
    scroll-behavior: auto;
  }

  .js [data-mg-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* The button keeps its colour change and loses every movement: no
     transform in the transition list, no press scale. */
  .mg-btn {
    transition: background-color 180ms var(--ease);
  }

  .mg-btn:active {
    transform: none;
  }
}

/* ---------- Narrow ----------------------------------------- */

@media (max-width: 1079px) {
  .mg-margin {
    order: -1;
  }

  .mg-note {
    text-align: left;
  }

  .mg-note--mark {
    padding-left: 22px;
  }

  .mg-note--mark::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.62em;
    width: 11px;
    height: 2px;
    background: var(--vermilion);
  }
}

/* A 1160pt Mac window scaled into a 350px column puts the app's 17px type at
   5px, which proves nothing. At 480px and below the four product shots swap
   for art-directed crops of the same renders (<picture> in the markup), and
   the three detail crops run to both edges: 390px instead of 350 buys the
   last 11% and lands the app's body type at 11px on the screen. */
@media (max-width: 480px) {
  #interface .mg-crop {
    margin-inline: calc(var(--pad) * -1);
  }

  #interface .mg-crop img {
    border-radius: 0;
    border-inline: 0;
  }
}

/* The phone crops stop mid-line by design (a page seen up close). A fade
   into the surrounding paper at the right edge says "continues" rather than
   "cut"; the find strip and the Aa card keep their right edge because that is
   where their controls live. */
@media (max-width: 480px) {
  .mg-fade img {
    -webkit-mask-image: linear-gradient(to right, #000 72%, rgba(0, 0, 0, 0) 100%);
    mask-image: linear-gradient(to right, #000 72%, rgba(0, 0, 0, 0) 100%);
  }
}

@media (max-width: 640px) {
  body.sp-page.mg-page {
    font-size: 1.0625rem;
  }

  .mg-hero {
    padding-top: 104px;
  }

  .mg-hero .mg-display {
    max-width: none;
  }

  .mg-btn {
    width: 100%;
  }

  .mg-cta-row {
    gap: var(--s4);
  }

}

/* ============================================================
   Serif display variant, not the shipped default
   ------------------------------------------------------------
   Add `mg-serif` to <body class="sp-page mg-page"> and the
   display line, the section heads and the price are set in
   Fraunces (already loaded by subpages.css) instead of Quattro.
   Nothing else moves: eyebrow, lead, buttons, body copy, facts,
   marginalia and every word inside a screenshot stay Quattro.

   Fraunces is asked for its display cut (opsz 144) at the light
   weight, with the terminals softened (SOFT 30) so the page does
   not read as the studio's own Fraunces voice. Sizes are tuned
   so the two-line headline occupies the same 167px at 1440 as
   the Quattro original: the variant swaps in without re-tuning
   the hero's rhythm or the fold.
   ============================================================ */

body.mg-page.mg-serif {
  --display-face: "Fraunces", ui-serif, Georgia, "Times New Roman", serif;
}

.mg-serif .mg-display,
.mg-serif h2:not(.mg-price-block),
.mg-serif .mg-price {
  font-family: var(--display-face);
  font-weight: 300;
  font-variation-settings: "opsz" 144, "SOFT" 30;
  font-synthesis-weight: none;
  letter-spacing: -0.02em;
}

.mg-serif .mg-display {
  font-size: clamp(2.875rem, 5.85vw, 5.0625rem);
  line-height: 1.03;
}

/* The shared 15ch is measured in Quattro's very wide zero; in Fraunces the
   same 15ch is wide enough to hold the whole headline on one line. 8em keeps
   the two-line break, and being an em it tracks the display size. */
.mg-serif .mg-hero .mg-display {
  max-width: 8em;
}

.mg-serif h2:not(.mg-price-block) {
  font-size: clamp(2.0625rem, 3.7vw, 3.3125rem);
  line-height: 1.05;
}

.mg-serif .mg-price {
  font-size: clamp(3.75rem, 8.4vw, 6.375rem);
  line-height: 1.02;
}

/* ---------- Inline code ------------------------------------ */
/* Quattro is already duospace, so a code span cannot announce itself by
   changing face. It takes the tint the app gives it instead: the same
   6% ink wash, the same 3px corner, nothing else. */

.mg-page .mg-code {
  font-family: inherit;
  font-size: 0.9375em;
  padding: 0.1em 0.34em;
  border-radius: 3px;
  background: rgba(38, 35, 29, 0.06);
  white-space: nowrap;
}

.mg-dark .mg-code {
  background: rgba(228, 223, 211, 0.1);
}

/* ---------- Term list (the Obsidian vocabulary) ------------- */
/* .mg-facts with the term carrying the weight: eight rows on hairlines,
   each one a word a reader already knows from their vault. Same anatomy
   as the facts list under "Nothing leaves your Mac", tighter rhythm
   because there are eight of them instead of three. */

.mg-facts--terms {
  max-width: 34em;
}

.mg-facts--terms li {
  padding-block: var(--s4);
}

.mg-facts--terms span {
  max-width: 34em;
}

/* ---------- Questions -------------------------------------- */
/* Hairline rows, the same rhythm as .mg-includes. The disclosure marker is
   the page's own vermilion mark: a horizontal bar that gains a vertical one
   when the answer is closed, so the mark reads as a plus and then a minus,
   and no new shape enters the page. */

.mg-faq {
  margin-top: clamp(28px, 3.4vw, 44px);
  max-width: 34em;
  border-top: 1px solid var(--hair);
}

.mg-q {
  border-bottom: 1px solid var(--hair);
}

.mg-q > summary {
  position: relative;
  display: block; /* kills the UA triangle in every engine */
  padding: var(--s5) 34px var(--s5) 0;
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1.45;
  letter-spacing: -0.005em;
  cursor: pointer;
  list-style: none;
  text-wrap: pretty;
  transition: color 160ms var(--ease);
}

.mg-q > summary::-webkit-details-marker {
  display: none;
}

@media (hover: hover) {
  .mg-q > summary:hover {
    color: var(--vermilion-text);
  }
}

/* The mark: the horizontal bar is always there. */
.mg-q > summary::before,
.mg-q > summary::after {
  content: "";
  position: absolute;
  right: 0;
  top: calc(var(--s5) + 0.72em);
  width: 13px;
  height: 2px;
  background: var(--vermilion);
}

/* The vertical bar is the "+", and it leaves when the answer opens. */
.mg-q > summary::after {
  transform: rotate(90deg);
  transition:
    transform 220ms var(--ease),
    opacity 160ms var(--ease);
}

.mg-q[open] > summary::after {
  transform: rotate(0deg);
  opacity: 0;
}

.mg-a {
  padding-bottom: var(--s5);
}

.mg-a .mg-body {
  max-width: 33em;
  color: var(--ink-2);
}

/* The answer is visible the moment <details> opens; the fade only softens
   an arrival that has already happened, so a headless render or a blocked
   animation still shows the text. */
.mg-q[open] > .mg-a {
  animation: mg-answer-in 220ms var(--ease) both;
}

@keyframes mg-answer-in {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.mg-q > summary:active {
  transform: scale(0.995);
}

@media (prefers-reduced-motion: reduce) {
  .mg-q[open] > .mg-a {
    animation: none;
  }

  .mg-q > summary::after {
    transition: none;
  }

  .mg-q > summary:active {
    transform: none;
  }
}

/* ---------- Inline link hit area --------------------------- */
/* An inline link lives in running text, so it cannot be given height without
   breaking the line it sits in, and padding would drag its vermilion underline
   away from the baseline. A positioned overlay enlarges the target instead:
   19px of italic marginalia becomes a 33px tap target and the type does not
   move a pixel. */

.mg-page a.mg-link {
  position: relative;
}

.mg-page a.mg-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -7px;
  bottom: -7px;
}
