/* ══════════════════════════════════════════════════════════════
   MMGY UI LAYER
   Every interactive and structural component a deck needs, built only
   from mmgy.css tokens. No new colours. No new fonts.

   Sizes are px on the 1920 × 1080 slide canvas, EXCEPT the "deck chrome"
   block at the bottom, which lives outside the scaled canvas and is
   therefore sized in real viewport px.

   Contents
     A · Affordances            H · Comparison / matrix
     B · Accordion              I · Quotes
     C · Tabs                   J · Logo wall & credentials
     D · Timeline               K · Devices & media placeholders
     E · Hotspots               L · Before / after
     F · Cards & reveal cards   M · Tables
     G · Process & steps        N · Chips, pills, icons
                                O · Deck chrome (viewport-sized)
   ══════════════════════════════════════════════════════════════ */

/* ═══ A · Affordances ═══════════════════════════════════════════ */
.tap { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.tap:focus-visible { outline: 4px solid var(--mmgy-red); outline-offset: 6px; }
button.tap, .tabs__tab, .acc__head, .tl__node, .chip {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  text-align: left; cursor: pointer;
}
[data-count] { font-variant-numeric: tabular-nums; }

/* Anything filtered out by a chip. */
.is-filtered { opacity: .16; pointer-events: none; transition: opacity .35s cubic-bezier(.2,.7,.2,1); }
[data-tags] { transition: opacity .35s cubic-bezier(.2,.7,.2,1); }

/* ═══ B · Accordion ═════════════════════════════════════════════
   <div class="acc">
     <div class="acc__item is-open">
       <button class="acc__head tap" aria-expanded="true">
         <span class="acc__num">01</span><span class="acc__title">…</span>
         <span class="acc__x"></span></button>
       <div class="acc__body"><div class="acc__inner">…</div></div>
     </div>
   </div>
   Add data-multi to .acc to allow several open at once.          */
.acc { display: flex; flex-direction: column; }
.acc__item { border-top: 3px solid var(--mmgy-ink); }
.acc__item:last-child { border-bottom: 3px solid var(--mmgy-ink); }
.slide--ink .acc__item, .slide--red .acc__item { border-color: var(--mmgy-white); }
.acc--red .acc__item { border-color: var(--mmgy-red) !important; }
.acc__head {
  width: 100%; display: grid; grid-template-columns: 150px 1fr 72px;
  align-items: center; gap: 0 40px; padding: 34px 0;
}
.acc__head--tight { grid-template-columns: 1fr 72px; padding: 26px 0; }

/* Preview variant — the closed state carries the actual point, not a teaser.
   A reader who never opens the panel should still get the argument, because
   most of them won't open it. Preview sits lighter and smaller than the
   headline, but never so light it reads as disabled. */
.acc__head--preview { align-items: start; }
.acc__stack { display: flex; flex-direction: column; gap: 12px; }
.acc__preview {
  font-family: var(--font-text); font-weight: 400; font-size: 28px;
  line-height: 1.32; opacity: .62; max-width: 1180px;
}
.acc__head--preview .acc__x { align-self: center; }
.acc__num { font-family: var(--font-text); font-weight: 700; font-size: 48px; color: var(--mmgy-red); }
.acc__title { font-family: var(--font-text); font-weight: 700; font-size: 48px; line-height: 1.05; }
.acc__head:hover .acc__title { color: var(--mmgy-red); }
/* plus → × marker, pure CSS */
.acc__x { position: relative; width: 56px; height: 56px; justify-self: end; }
.acc__x::before, .acc__x::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 40px; height: 5px; background: var(--mmgy-red);
  translate: -50% -50%; transition: rotate .35s cubic-bezier(.2,.7,.2,1);
}
.acc__x::after { rotate: 90deg; }
.acc__item.is-open .acc__x::before { rotate: 180deg; }
.acc__item.is-open .acc__x::after  { rotate: 225deg; }
/* grid 0fr→1fr animates height with no JS measurement */
.acc__body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .5s cubic-bezier(.2,.7,.2,1); }
.acc__item.is-open .acc__body { grid-template-rows: 1fr; }
.acc__inner { overflow: hidden; }
.acc__inner > * { margin: 0; padding-bottom: 40px; max-width: 1100px; }

/* ═══ C · Tabs ══════════════════════════════════════════════════ */
.tabs__rail { display: flex; gap: 64px; border-bottom: 3px solid currentColor; }
.tabs__rail--sm { gap: 44px; }
.tabs__tab {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 56px; line-height: 1; padding: 0 0 26px; position: relative;
  opacity: .45; transition: opacity .25s;
}
.tabs__rail--sm .tabs__tab { font-size: 40px; padding-bottom: 20px; }
.tabs__tab:hover { opacity: .8; }
.tabs__tab.is-on { opacity: 1; }
.tabs__tab::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 6px;
  background: var(--mmgy-red); scale: 0 1; transform-origin: left;
  transition: scale .35s cubic-bezier(.2,.7,.2,1);
}
.tabs__tab.is-on::after { scale: 1 1; }
/* Left-rail variant. Horizontal tabs only work when the labels are short;
   four long questions across 1664px shrink to unreadable or wrap to a mess.
   Stacked down the left, each tab gets room for a number, the question and
   a one-line descriptor — which is what a tab carrying an argument needs. */
.tabs--rail { display: grid; grid-template-columns: 620px 1fr; gap: 88px; align-items: start; }
.tabs--rail .tabs__rail { display: block; border-bottom: 0; border-left: 3px solid color-mix(in srgb, currentColor 22%, transparent); }
.tabs--rail .tabs__tab {
  display: grid; grid-template-columns: 74px 1fr; align-items: baseline;
  width: 100%; padding: 24px 0 24px 34px; margin-left: -3px;
  border-left: 3px solid transparent; opacity: .5; font-size: inherit;
  transition: opacity .25s, border-color .25s;
}
.tabs--rail .tabs__tab::after { display: none; }
.tabs--rail .tabs__tab:hover { opacity: .8; }
.tabs--rail .tabs__tab.is-on { opacity: 1; border-left-color: var(--mmgy-red); }
.tabs__tab-num {
  font-family: var(--font-display); font-weight: 700; font-size: 30px;
  line-height: 1.05; color: var(--mmgy-red);
}
.tabs__tab-q {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 40px; line-height: .98; display: block;
}
.tabs__tab-sub {
  font-family: var(--font-text); font-weight: 400; text-transform: none;
  font-size: 23px; line-height: 1.35; letter-spacing: 0; display: block;
  margin-top: 12px; opacity: .7;
}
.tabs--rail .tabs__panels { margin-top: 0; }

.tabs__panels { position: relative; margin-top: 64px; min-height: 420px; }
.tabs__panel {
  position: absolute; inset: 0; opacity: 0; visibility: hidden;
  translate: 0 24px; transition: opacity .4s, translate .4s, visibility 0s .4s;
}
.tabs__panel.is-on { opacity: 1; visibility: visible; translate: 0 0; transition: opacity .4s .05s, translate .4s .05s; }

/* ═══ D · Timeline ══════════════════════════════════════════════ */
.tl__track {
  position: relative; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  align-items: start; padding-top: 34px;
}
.tl__track::before {
  content: ""; position: absolute; left: 0; right: 0; top: 44px;
  height: 3px; background: currentColor; opacity: .25;
}
.tl__line {
  position: absolute; left: 0; top: 44px; height: 3px;
  background: var(--mmgy-red); width: 0;
  transition: width .6s cubic-bezier(.2,.7,.2,1);
}
.tl__node { display: grid; justify-items: start; gap: 18px; padding-right: 48px; }
.tl__dot {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--mmgy-stone); border: 3px solid currentColor;
  margin-top: -46px; position: relative; z-index: 1;
  transition: background .3s, scale .3s;
}
.slide--ink .tl__dot { background: var(--mmgy-ink); }
.slide--red .tl__dot { background: var(--mmgy-red); }
.tl__label { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 44px; line-height: .95; }
.tl__date  { font-family: var(--font-text); font-weight: 700; font-size: 22px; letter-spacing: .16em; text-transform: uppercase; color: var(--mmgy-red); }
.slide--red .tl__date { color: var(--mmgy-ink); }
.tl[data-autobuild] .tl__node { opacity: 0; translate: 0 32px; transition: opacity .5s, translate .5s cubic-bezier(.2,.7,.2,1); }
.tl[data-autobuild] .tl__node.is-built { opacity: 1; translate: 0 0; }
.tl__node:hover .tl__label { color: var(--mmgy-red); }
.tl__node.is-on .tl__dot { background: var(--mmgy-red); border-color: var(--mmgy-red); scale: 1.35; }
.tl__node.is-on .tl__label { color: var(--mmgy-red); }
.tl__details { position: relative; margin-top: 72px; min-height: 300px; }
.tl__detail {
  position: absolute; inset: 0; opacity: 0; visibility: hidden;
  translate: 0 24px; transition: opacity .4s, translate .4s, visibility 0s .4s;
  border-top: 3px solid var(--mmgy-red); padding-top: 40px;
}
.tl__detail.is-on { opacity: 1; visibility: visible; translate: 0 0; transition: opacity .4s .1s, translate .4s .1s; }

/* ═══ E · Hotspots ══════════════════════════════════════════════ */
.hot-wrap { position: relative; }
.hot { position: absolute; }
.hot__dot {
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--mmgy-red); border: 5px solid var(--mmgy-white);
  cursor: pointer; position: relative; z-index: 2; display: block;
}
.hot__dot::after {
  content: ""; position: absolute; inset: -14px; border-radius: 50%;
  border: 3px solid var(--mmgy-red); opacity: 0;
  animation: hot-pulse 2.2s ease-out infinite;
}
@keyframes hot-pulse { 0% { scale: .6; opacity: .9; } 70% { scale: 1.25; opacity: 0; } 100% { opacity: 0; } }
.hot__card {
  position: absolute; left: 60px; top: -20px; z-index: 3; width: 460px;
  background: var(--mmgy-ink); color: var(--mmgy-white); padding: 36px 40px;
  opacity: 0; visibility: hidden; translate: -16px 0;
  transition: opacity .3s, translate .3s, visibility 0s .3s;
}
.hot.is-open .hot__card { opacity: 1; visibility: visible; translate: 0 0; transition: opacity .3s, translate .3s; }
.hot--flip .hot__card { left: auto; right: 60px; translate: 16px 0; }
.hot--up .hot__card { top: auto; bottom: 60px; }
.hot__card .t-eyebrow { color: var(--mmgy-red); margin-bottom: 14px; }

/* ═══ F · Cards ═════════════════════════════════════════════════
   <article class="card card--stone"> … </article>
   Cards are flat colour blocks with a red top rule — never shadows,
   never rounded corners (the arch and the notch are the only curves). */
.card {
  position: relative; padding: 48px 48px 56px;
  border-top: 6px solid var(--mmgy-red);
  background: var(--mmgy-stone); color: var(--mmgy-ink);
  display: flex; flex-direction: column; gap: 22px;
}
.card--stone { background: var(--mmgy-stone); color: var(--mmgy-ink); }
.card--ink   { background: var(--mmgy-ink);   color: var(--mmgy-white); }
.card--red   { background: var(--mmgy-red);   color: var(--mmgy-white); border-top-color: var(--mmgy-ink); }
.card--white { background: var(--mmgy-white); color: var(--mmgy-ink); }
.card--line  { background: none; border: 3px solid currentColor; border-top-width: 6px; border-top-color: var(--mmgy-red); }
.card__num   { font-family: var(--font-display); font-weight: 700; font-size: 72px; line-height: 1; color: var(--mmgy-red); }
.card--red .card__num { color: var(--mmgy-ink); }
.card__title { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 56px; line-height: .96; margin: 0; }
.card__body  { font-size: var(--text-body); margin: 0; }
.card__foot  { margin-top: auto; padding-top: 28px; }

/* Reveal card — front copy, click for the detail. Use for "our thinking"
   grids where the answer should land after the question. */
.rcard { position: relative; overflow: hidden; cursor: pointer; }
.rcard__back {
  position: absolute; inset: 0; padding: 48px;
  background: var(--mmgy-red); color: var(--mmgy-white);
  display: flex; flex-direction: column; justify-content: center; gap: 18px;
  clip-path: inset(0 0 100% 0); transition: clip-path .45s cubic-bezier(.2,.7,.2,1);
}
.rcard.is-open .rcard__back { clip-path: inset(0 0 0 0); }
.rcard__hint { position: absolute; right: 34px; bottom: 30px; font-size: 22px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--mmgy-red); }
.rcard.is-open .rcard__hint { display: none; }

/* Stat block — the atom of every numbers slide. */
.stat { display: flex; flex-direction: column; gap: 18px; }
.stat__num { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; line-height: .9; font-size: var(--text-stat); color: var(--mmgy-red); margin: 0; }
.stat--ink .stat__num { color: var(--mmgy-ink); }
.stat--white .stat__num { color: var(--mmgy-white); }
.stat__rule { border: 0; border-top: 3px solid var(--mmgy-red); margin: 8px 0 0; }
.stat__label { font-size: var(--text-body); margin: 0; }
.stat--sm .stat__num { font-size: 128px; }

/* ═══ G · Process & numbered steps ══════════════════════════════
   Horizontal chain of beats with a connecting hairline. */
.process { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 0; }
.process__step { position: relative; padding: 0 48px 0 0; }
.process__step::before {
  content: ""; position: absolute; left: 0; right: 0; top: 26px;
  height: 3px; background: var(--mmgy-red);
}
.process__step:last-child::before { right: 48px; }
.process__dot {
  position: relative; z-index: 1; width: 56px; height: 56px; border-radius: 50%;
  background: var(--mmgy-red); color: var(--mmgy-white);
  font-family: var(--font-text); font-weight: 700; font-size: 26px;
  display: flex; align-items: center; justify-content: center;
}
.process__title { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 52px; line-height: .95; margin: 34px 0 16px; }
.process__body { font-size: var(--text-body-sm); margin: 0; padding-right: 24px; }

/* Vertical numbered rows separated by red hairlines. */
.rows { display: flex; flex-direction: column; }
.rows__row {
  display: grid; grid-template-columns: 130px 1fr 1fr; gap: 56px;
  align-items: baseline; padding: 40px 0; border-top: 3px solid var(--mmgy-red);
}
.rows__row:last-child { border-bottom: 3px solid var(--mmgy-red); }
.rows__num { font-family: var(--font-display); font-weight: 700; font-size: 64px; line-height: 1; color: var(--mmgy-red); }
.rows__title { font-family: var(--font-text); font-weight: 700; font-size: 44px; line-height: 1.05; margin: 0; }
.rows__body { font-size: var(--text-body); margin: 0; }
.rows--two .rows__row { grid-template-columns: 130px 1fr; }
/* Five or more rows on one slide need the tighter rhythm to fit the canvas. */
.rows--tight .rows__row { padding: 26px 0; }
.rows--tight .rows__title { font-size: 38px; }
/* Quiet rules. The red hairline is right when the rows ARE the argument;
   on a slide that already carries red elsewhere it just adds noise. */
.rows--quiet .rows__row { border-color: color-mix(in srgb, currentColor 20%, transparent); }
.rows--quiet .rows__row:last-child { border-bottom-color: color-mix(in srgb, currentColor 20%, transparent); }

/* ═══ H · Comparison & matrix ═══════════════════════════════════ */
.vs { display: grid; grid-template-columns: 1fr 3px 1fr; gap: 72px; align-items: start; }
.vs__rule { background: var(--mmgy-red); align-self: stretch; }
.vs__head { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 72px; line-height: .95; margin: 0 0 40px; }
.vs__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 28px; }
.vs__list li { display: grid; grid-template-columns: 46px 1fr; gap: 24px; font-size: var(--text-body); }
.vs__list li::before { content: "—"; color: var(--mmgy-red); font-weight: 700; }
.vs__list--yes li::before { content: "✓"; }
.vs__list--no li::before  { content: "✕"; opacity: .4; }

/* 2 × 2 positioning matrix. Axis labels are set on the wrapper. */
.matrix { position: relative; aspect-ratio: 1.35; border-left: 3px solid currentColor; border-bottom: 3px solid currentColor; }
.matrix::before, .matrix::after { content: ""; position: absolute; background: currentColor; opacity: .18; }
.matrix::before { left: 0; right: 0; top: 50%; height: 3px; }
.matrix::after  { top: 0; bottom: 0; left: 50%; width: 3px; }
.matrix__pt {
  position: absolute; translate: -50% 50%;
  font-family: var(--font-text); font-weight: 700; font-size: 26px;
  display: flex; align-items: center; gap: 16px; white-space: nowrap;
}
.matrix__pt::before { content: ""; width: 22px; height: 22px; border-radius: 50%; background: currentColor; opacity: .35; flex: none; }
.matrix__pt--us { color: var(--mmgy-red); font-size: 32px; }
.matrix__pt--us::before { width: 32px; height: 32px; opacity: 1; }
.matrix__axis { font-family: var(--font-text); font-weight: 700; font-size: 20px; letter-spacing: .18em; text-transform: uppercase; position: absolute; }

/* ═══ I.5 · Letter ══════════════════════════════════════════════
   For the covering note at the front of a proposal. One narrow measure,
   generous leading, nothing else on the slide. It should feel like paper,
   which mostly means resisting everything you'd normally add.
   A long letter runs across several slides: repeat .letter, carry the
   page marker, and put the signature block on the last one only.        */
.letter { max-width: 1160px; margin: 0 auto; }
.letter p { font-size: 27px; line-height: 1.66; margin: 0 0 30px; text-wrap: pretty; }
/* Two-page variant: tighter measure and leading so a ~550-word note lands
   in two slides instead of three. Still comfortably above the size where
   a letter starts to read as fine print. */
.letter--dense { max-width: 1300px; }
.letter--dense p { font-size: 24px; line-height: 1.58; margin: 0 0 22px; }
.letter--dense .letter__sig { margin-top: 38px; }
.letter--dense .letter__sig .name { font-size: 46px; }
.letter--dense .letter__office { margin-top: 24px; }
.letter p:last-child { margin-bottom: 0; }
.letter__sal { font-weight: 700; }
.letter strong { font-weight: 700; }
.letter__sig { margin-top: 52px; }
.letter__sig .name {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 52px; line-height: 1; margin: 0 0 10px;
}
.letter__sig p { font-size: 24px; line-height: 1.5; margin: 0; opacity: .78; }
.letter__office { margin-top: 34px; font-size: 20px; line-height: 1.5; opacity: .5; }
.letter__page {
  position: absolute; right: var(--margin); bottom: 60px;
  font-family: var(--font-text); font-weight: 700; font-size: 20px;
  letter-spacing: .18em; text-transform: uppercase; opacity: .4;
}

/* ═══ I · Quotes ════════════════════════════════════════════════ */
.quote { position: relative; padding-left: 150px; }
.quote::before {
  content: "“"; position: absolute; left: 0; top: -40px;
  font-family: var(--font-display); font-weight: 700; font-size: 260px;
  line-height: 1; color: var(--mmgy-red);
}
.quote__text { font-family: var(--font-text); font-weight: 700; font-size: 72px; line-height: 1.12; margin: 0; text-wrap: balance; }
.quote__cite { font-style: normal; display: block; margin-top: 48px; font-size: var(--text-body); }
.quote__cite strong { display: block; font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 40px; line-height: 1; margin-bottom: 8px; }

/* ═══ J · Logo wall & credentials ═══════════════════════════════ */
.logos { display: grid; grid-template-columns: repeat(5, 1fr); gap: 3px; background: currentColor; border: 3px solid currentColor; }
.logos--4 { grid-template-columns: repeat(4, 1fr); }
.logos--5 { grid-template-columns: repeat(5, 1fr); }
.logos--6 { grid-template-columns: repeat(6, 1fr); }
.logo-cell {
  background: var(--mmgy-white); aspect-ratio: 16/9;
  display: flex; align-items: center; justify-content: center; padding: 32px;
}
.slide--ink .logo-cell { background: var(--mmgy-ink); }
.slide--stone .logo-cell { background: var(--mmgy-stone); }
.logo-cell img { max-width: 100%; max-height: 100%; object-fit: contain; }
/* Text fallback while real marks are being sourced. */
.logo-cell__name { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 34px; line-height: 1; opacity: .45; text-align: center; }

/* Award / credential badge */
.badge { display: flex; flex-direction: column; gap: 12px; padding-top: 26px; border-top: 3px solid var(--mmgy-red); }
.badge__year { font-family: var(--font-text); font-weight: 700; font-size: 20px; letter-spacing: .18em; text-transform: uppercase; color: var(--mmgy-red); }
.badge__name { font-family: var(--font-display); font-weight: 700; text-transform: uppercase; font-size: 46px; line-height: .96; margin: 0; }

/* ═══ K · Devices & media placeholders ══════════════════════════ */
/* Frames are DRAWN, not photographed — a stock device render drags in
   gradients, shadows and a colour palette the brand doesn't own. Both
   frames force `color: ink` on a white ground so their hairlines survive
   on an ink or red slide. */
.device { position: relative; display: block; background: var(--mmgy-white); color: var(--mmgy-ink); }
.device__screen { position: relative; overflow: hidden; }
.device__screen > img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Browser chrome for site work — three dots, no OS mimicry. */
.device--browser { border: 3px solid var(--mmgy-ink); }
.device--browser .device__bar { display: flex; align-items: center; gap: 14px; padding: 20px 26px; border-bottom: 3px solid var(--mmgy-ink); }
.device--browser .device__bar span { width: 18px; height: 18px; border-radius: 50%; background: var(--mmgy-ink); opacity: .28; }
.device--browser .device__bar span:first-child { background: var(--mmgy-red); opacity: 1; }

/* Phone: a bezel and a speaker slot. Enough to read as a handset without
   pretending to be one particular one. */
.device--phone { border: 12px solid var(--mmgy-ink); padding: 34px 0 26px; }
.device--phone::before {
  content: ""; position: absolute; top: 14px; left: 50%; translate: -50% 0;
  width: 96px; height: 8px; background: var(--mmgy-ink); opacity: .5;
}
.device--phone .device__screen { border-top: 3px solid var(--mmgy-stone); border-bottom: 3px solid var(--mmgy-stone); }

/* Designed placeholder — reads as intentional, not unfinished. Use it so
   a deck can be built and reviewed before the real imagery exists. */
.media-ph {
  position: relative; background: var(--mmgy-stone); color: var(--mmgy-ink);
  border: 3px solid var(--mmgy-red);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; text-align: center; padding: 48px; overflow: hidden;
}
.slide--ink .media-ph, .slide--red .media-ph { background: transparent; color: currentColor; }
.media-ph::before {
  content: ""; position: absolute; inset: 0;
  background: repeating-linear-gradient(-45deg, transparent 0 22px, color-mix(in srgb, var(--mmgy-red) 12%, transparent) 22px 24px);
  pointer-events: none;
}
.media-ph__label { font-family: var(--font-text); font-weight: 700; font-size: 20px; letter-spacing: .18em; text-transform: uppercase; color: var(--mmgy-red); margin: 0; position: relative; }
.media-ph__note  { font-size: var(--text-body-sm); margin: 0; max-width: 520px; position: relative; opacity: .7; }

/* ═══ L · Before / after ════════════════════════════════════════
   <div class="ba" style="--split:50%">
     <img class="ba__a" …><img class="ba__b" …>
     <input class="ba__range" type="range" min="0" max="100" value="50">
   </div>                                                          */
.ba { position: relative; overflow: hidden; --split: 50%; }
.ba img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ba__b { clip-path: inset(0 0 0 var(--split)); }
.ba::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: var(--split);
  width: 5px; background: var(--mmgy-red); pointer-events: none; z-index: 2;
}
.ba__range { position: absolute; inset: auto 0 0; width: 100%; z-index: 3; opacity: 0; height: 100%; cursor: ew-resize; }
.ba__tag { position: absolute; bottom: 32px; z-index: 2; font-family: var(--font-text); font-weight: 700; font-size: 20px; letter-spacing: .18em; text-transform: uppercase; background: var(--mmgy-red); color: var(--mmgy-white); padding: 12px 20px; }
.ba__tag--a { left: 32px; } .ba__tag--b { right: 32px; }

/* ═══ M · Tables ════════════════════════════════════════════════
   Scope, deliverables, pricing, media plans. Hairlines only. */
.qtable { width: 100%; border-collapse: collapse; font-size: var(--text-body-sm); }
.qtable th, .qtable td { text-align: left; padding: 28px 32px 28px 0; border-top: 3px solid var(--mmgy-red); vertical-align: top; }
.qtable thead th {
  border-top: 0; border-bottom: 3px solid var(--mmgy-red); padding-bottom: 20px;
  font-family: var(--font-text); font-weight: 700; font-size: 20px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--mmgy-red);
}
.qtable tbody th { font-family: var(--font-text); font-weight: 700; font-size: 32px; }
.qtable .num { text-align: right; font-variant-numeric: tabular-nums; padding-right: 0; }
/* Centred variant. Right-aligned reads best for money in a column of its
   own; a tier matrix of ticks and short words wants centring under its
   header instead. Row labels stay left. */
.qtable .c { text-align: center; padding-right: 0; }
.qtable thead th.c, .qtable tfoot th.c { text-align: center; }
.qtable tfoot td, .qtable tfoot th { border-top-width: 6px; font-weight: 700; font-size: 34px; }
/* Quiet variant. The default table rules every row in red, which is right
   for three or four rows and shouting by ten. Here red is reserved for the
   header and anything explicitly marked — the rows fall back to hairlines.
   Use whenever a table is the main event on the slide. */
.qtable--quiet th, .qtable--quiet td { border-top-color: color-mix(in srgb, currentColor 18%, transparent); }
.qtable--quiet thead th { border-bottom-color: var(--mmgy-red); }
.qtable--quiet tfoot td, .qtable--quiet tfoot th { border-top-color: var(--mmgy-red); }
.qtable--quiet .is-on { color: var(--mmgy-red); font-weight: 700; }
.qtable--quiet .off { opacity: .3; }

/* Seven rows or more only fit at the tighter rhythm. */
.qtable--tight th, .qtable--tight td { padding: 14px 32px 14px 0; }
.qtable--tight tbody th { font-size: 28px; }
.qtable--tight { font-size: 24px; }
.qtable tr.is-total { font-weight: 700; }

/* ═══ M.5 · Trait map & stack diagram ═══════════════════════════
   Two structural components that aren't charts: a frequency-tiered word
   map, and a layered architecture stack. Both are markup so the labels
   stay selectable and translatable.                                     */
.trait-tier { display: flex; flex-wrap: wrap; gap: 18px 20px; align-items: baseline; }
.trait-tier + .trait-tier { margin-top: 40px; }
.trait {
  display: inline-block; padding: 12px 26px; border: 3px solid currentColor;
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  line-height: 1;
}
.trait-tier--high .trait { font-size: 52px; padding: 18px 32px; border-color: var(--mmgy-red); color: var(--mmgy-red); }
.trait-tier--mid  .trait { font-size: 34px; opacity: .88; }
.trait-tier--low  .trait { font-size: 26px; opacity: .55; }
.trait-tier__label {
  font-family: var(--font-text); font-weight: 700; font-size: 20px;
  letter-spacing: .18em; text-transform: uppercase; opacity: .5;
  width: 100%; margin: 0 0 6px;
}

.stack-diagram { display: flex; flex-direction: column; gap: 6px; }
.stack-row {
  display: grid; grid-template-columns: 300px 1fr; gap: 32px; align-items: center;
  border: 3px solid currentColor; padding: 22px 30px;
}
.stack-row__name {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 32px; line-height: 1;
}
.stack-row__desc { font-size: var(--text-body-sm); opacity: .78; }
.stack-row--accent { border-color: var(--mmgy-red); }
.stack-row--accent .stack-row__name { color: var(--mmgy-red); }
.stack-row--muted { opacity: .55; }
.stack-tag {
  font-family: var(--font-text); font-weight: 700; font-size: 18px;
  letter-spacing: .16em; text-transform: uppercase;
  background: var(--mmgy-red); color: var(--mmgy-white); padding: 6px 12px; margin-left: 14px;
}

/* ═══ M.6 · Hub & cycle diagrams ════════════════════════════════
   Two relationship diagrams. Deliberately markup rather than SVG: the
   labels wrap, stay selectable, and survive translation, none of which
   SVG <text> does well.

   HUB — one source feeding many channels.
     <div class="hub">
       <svg class="hub__lines" …>            spokes, drawn behind
       <div class="hub__centre">…</div>
       <div class="hub__node" style="left:..;top:..">…</div>
     </div>

   CYCLE — a repeating loop with a fixed centre.
     <div class="cycle">
       <div class="cycle__ring"></div>
       <div class="cycle__hub">…</div>
       <div class="cycle__node" style="left:..;top:..">…</div>
     </div>
   Nodes are positioned by the author, not computed: six boxes round a
   ring need optical judgement that an equal-angle formula won't give.  */

.hub { position: relative; width: 100%; }
/* width:100% is load-bearing. Every child is absolutely positioned, so the
   hub has no in-flow content — as a flex or grid item with `margin:auto`
   it shrink-to-fits to ZERO width and every left:% collapses onto the same
   point. Size it with max-width + justify-self, never with auto margins. */
.hub__lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.hub__lines line { stroke: var(--mmgy-red); stroke-width: 3; opacity: .4; }
.hub__centre {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 2;
  width: 300px; height: 300px; border-radius: 50%;
  background: var(--mmgy-red); color: var(--mmgy-white);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 30px;
}
.hub__centre strong {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 46px; line-height: .96; display: block;
}
.hub__centre span { font-size: 22px; line-height: 1.3; margin-top: 12px; opacity: .9; }
.hub__node {
  position: absolute; translate: -50% -50%; z-index: 2; width: 300px;
  background: var(--mmgy-white); color: var(--mmgy-ink);
  border: 3px solid var(--mmgy-ink); padding: 22px 24px; text-align: center;
}
.slide--ink .hub__node, .slide--stone .hub__node { background: var(--mmgy-white); }
.hub__node strong {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 34px; line-height: 1; display: block;
}
.hub__node span { font-size: 20px; line-height: 1.35; margin-top: 10px; display: block; opacity: .72; }

.cycle { position: relative; }
.cycle__ring {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  height: 86%; aspect-ratio: 1; border-radius: 50%;
  border: 3px dashed color-mix(in srgb, currentColor 30%, transparent);
}
.cycle__hub {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 2;
  width: 250px; height: 250px; border-radius: 50%;
  background: var(--mmgy-red); color: var(--mmgy-white);
  display: flex; align-items: center; justify-content: center; text-align: center;
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 52px; line-height: .95;
}
/* Positioned by edge (left/right/top/bottom), not centred on a point —
   six boxes round a ring are easier to balance by their nearest edge. */
.cycle__node {
  position: absolute; width: 380px; z-index: 2;
  border-top: 4px solid var(--mmgy-red); padding-top: 16px;
}
.cycle__node .n {
  font-family: var(--font-display); font-weight: 700; font-size: 32px;
  line-height: 1; color: var(--mmgy-red);
}
.cycle__node h4 {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 32px; line-height: 1; margin: 10px 0 8px;
}
.cycle__node p { font-size: 21px; line-height: 1.35; margin: 0; opacity: .78; }

/* ═══ M.7 · AI model marks ══════════════════════════════════════
   Official marks from each company's own assets, in mmgy/assets/models/.
   Third-party trademarks used to identify systems we measured — never
   place them near the MMGY logo or imply partnership.

   Optically balanced rather than pixel-matched: these have very different
   aspect ratios and a uniform box makes the round ones look small.
     <div class="model-row">
       <figure class="model"><img src="…/chatgpt.svg" alt="ChatGPT"><figcaption>ChatGPT</figcaption></figure>
     </div>
   Light backgrounds only — two of the six are near-black marks.        */
.model-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 44px 56px; }
.model { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 14px; width: 132px; }
.model img { height: 56px; width: auto; display: block; }
.model--sm img { height: 40px; }
.model--sm { width: 104px; gap: 10px; }
.model figcaption {
  font-family: var(--font-text); font-weight: 700; font-size: 19px;
  letter-spacing: .1em; text-transform: uppercase; text-align: center; opacity: .68;
}
.model--sm figcaption { font-size: 16px; }
/* Marks only. Use where the surrounding copy already names the models and
   a second set of labels would just repeat it. */
.model--xs { width: auto; gap: 0; }
.model--xs img { height: 34px; }
.model--xs figcaption { display: none; }

/* ═══ M.8 · Loop timeline ═══════════════════════════════════════
   A sequence that repeats. A ring diagram reads as decoration at slide
   scale and the labels fight the curve; a straight run with a return arm
   underneath says "these six, then again" far more directly.          */
.loop { position: relative; padding-bottom: 96px; }
.loop__track { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 0; position: relative; }
/* The rule runs dot-centre to dot-centre. Left at 0/right at 0 leaves a
   stub hanging past the last step with nothing to connect to. Override
   --loop-steps if the track isn't six wide. */
.loop__track::before {
  content: ""; position: absolute; top: 27px; height: 3px;
  left: 28px; right: calc(100% / var(--loop-steps, 6) - 28px);
  background: var(--mmgy-red);
}
.loop__step { position: relative; padding-right: 40px; }
.loop__dot {
  position: relative; z-index: 1; width: 56px; height: 56px; border-radius: 50%;
  background: var(--mmgy-red); color: var(--mmgy-white);
  font-family: var(--font-text); font-weight: 700; font-size: 24px;
  display: flex; align-items: center; justify-content: center;
}
.loop__step h4 {
  font-family: var(--font-display); font-weight: 700; text-transform: uppercase;
  font-size: 34px; line-height: 1; margin: 26px 0 12px;
}
.loop__step p { font-size: 21px; line-height: 1.4; margin: 0; opacity: .78; padding-right: 20px; }
/* The return arm: down from the last step, back along, up into the first. */
.loop__return { position: absolute; left: 0; right: 0; bottom: 0; height: 84px; }
.loop__return svg { width: 100%; height: 100%; overflow: visible; }
.loop__return path { fill: none; stroke: var(--mmgy-red); stroke-width: 3; stroke-dasharray: 9 8; }
.loop__return-label {
  position: absolute; left: 50%; bottom: 22px; translate: -50% 0;
  background: var(--mmgy-white); padding: 0 22px;
  font-family: var(--font-text); font-weight: 700; font-size: 21px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--mmgy-red);
}
.slide--stone .loop__return-label { background: var(--mmgy-stone); }
.slide--ink .loop__return-label { background: var(--mmgy-ink); }

/* ═══ N · Chips, pills, icons ═══════════════════════════════════ */
.chip {
  display: inline-flex; align-items: center; padding: 16px 28px;
  border: 3px solid currentColor; font-family: var(--font-text); font-weight: 700;
  font-size: 24px; letter-spacing: .1em; text-transform: uppercase;
  transition: background .25s, color .25s, border-color .25s;
}
.chip:hover { border-color: var(--mmgy-red); color: var(--mmgy-red); }
.chip.is-on { background: var(--mmgy-red); border-color: var(--mmgy-red); color: var(--mmgy-white); }
.chip-row { display: flex; flex-wrap: wrap; gap: 20px; }

.pill {
  display: inline-flex; align-items: center; gap: 12px; padding: 10px 22px;
  background: var(--mmgy-red); color: var(--mmgy-white);
  font-family: var(--font-text); font-weight: 700; font-size: 20px;
  letter-spacing: .16em; text-transform: uppercase;
}
.pill--line { background: none; color: inherit; border: 3px solid var(--mmgy-red); }

/* Icons: stroke-only, currentColor, sized by class. See mmgy-icons.js. */
.icon { width: 88px; height: 88px; display: block; flex: none; }
.icon--sm { width: 48px; height: 48px; }
.icon--lg { width: 140px; height: 140px; }
/* Only the WRAPPED svg fills its parent. `svg.icon` must not appear here:
   at (0,1,1) it would outrank .icon--sm/.icon--lg and the direct-svg form
   would always render at 100% of whatever contains it. */
.icon svg { width: 100%; height: 100%; display: block; }
svg.icon, .icon svg { fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.icon--red, .icon--red svg { color: var(--mmgy-red); }

/* Chapter dots (per-slide nav inside .slide-foot) */
.chapters { display: flex; gap: 20px; align-items: center; }
.chapters__dot {
  width: 18px; height: 18px; border-radius: 50%;
  background: transparent; border: 3px solid currentColor; opacity: .4;
  transition: opacity .25s, background .25s;
}
.chapters__dot:hover { opacity: .8; }
.chapters__dot.is-on { background: var(--mmgy-red); border-color: var(--mmgy-red); opacity: 1; }

/* ═══ PRINT ═════════════════════════════════════════════════════
   Reveal what fits, and only what fits. A slide is a fixed 1920×1080 box
   with overflow:hidden, so "show everything" would silently clip the tail
   of a tab set or a timeline — worse than showing one panel honestly.

   Rule of thumb when authoring: if a slide's whole point is four tab
   panels, the PDF gets one of them. Give the deck a print-friendly
   companion slide (a table, a 4-up grid) if the client will read it on
   paper.                                                                  */
@media print {
  /* Accordions genuinely fit — open every row. */
  .acc__body { grid-template-rows: 1fr !important; }

  /* Tabs and timeline details are stacked overlays. Print the selected one
     in flow; hide the rest rather than overflow the page. */
  .tabs__panel.is-on, .tl__detail.is-on {
    position: static !important; opacity: 1 !important; visibility: visible !important;
    translate: none !important;
  }
  .tabs__panel:not(.is-on), .tl__detail:not(.is-on) { display: none !important; }

  .tl[data-autobuild] .tl__node { opacity: 1 !important; translate: none !important; }
  .hot__card { opacity: 1 !important; visibility: visible !important; translate: none !important; }

  /* A reveal card's answer IS the slide. Print the back, not the prompt. */
  .rcard__back { clip-path: none !important; }
  .rcard__hint { display: none !important; }

  .is-filtered { opacity: 1 !important; }
  .hot__dot::after { animation: none !important; }
}

/* ══════════════════════════════════════════════════════════════
   O · DECK CHROME
   Lives outside <deck-stage>, so these are REAL viewport pixels,
   not canvas pixels. Never printed, never captured.
   ══════════════════════════════════════════════════════════════ */

.deck-progress {
  position: fixed; inset: 0 0 auto; height: 3px; z-index: 40;
  background: color-mix(in srgb, currentColor 12%, transparent);
  pointer-events: none;
}
.deck-progress__fill {
  display: block; height: 100%; background: var(--mmgy-red);
  transform-origin: left; transform: scaleX(0);
  transition: transform .5s cubic-bezier(.2,.7,.2,1);
}

.deck-ui {
  position: fixed; top: 18px; right: 18px; z-index: 41;
  display: flex; gap: 8px; opacity: .35; transition: opacity .25s;
}
.deck-ui:hover, .deck-ui:focus-within { opacity: 1; }
.deck-ui__btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding: 0 11px; cursor: pointer;
  background: var(--mmgy-ink); color: var(--mmgy-white); border: 0;
  font-family: var(--font-text); font-weight: 700; font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase;
}
.deck-ui__btn:hover { background: var(--mmgy-red); }
.deck-ui__btn:focus-visible { outline: 3px solid var(--mmgy-red); outline-offset: 2px; }
.deck-ui__btn svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }

.deck-help {
  position: fixed; inset: 0; z-index: 60; display: flex;
  align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--mmgy-ink) 78%, transparent);
}
.deck-help[hidden] { display: none; }
.deck-help__panel {
  background: var(--mmgy-white); color: var(--mmgy-ink);
  padding: 40px 48px 36px; max-width: 460px; width: calc(100% - 48px);
  border-top: 6px solid var(--mmgy-red);
  font-family: var(--font-text);
}
.deck-help__panel .t-eyebrow { font-size: 11px; margin: 0 0 10px; }
.deck-help__panel dl { display: grid; grid-template-columns: auto 1fr; gap: 12px 28px; margin: 22px 0 28px; font-size: 14px; }
.deck-help__panel dt { font-weight: 700; white-space: nowrap; }
.deck-help__panel dd { margin: 0; opacity: .75; }
.deck-help__close {
  background: var(--mmgy-ink); color: var(--mmgy-white); border: 0;
  padding: 12px 22px; font-family: var(--font-text); font-weight: 700;
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
}

/* ── Passcode gate ────────────────────────────────────────────────
   Two variants of one component:

     .deck-gate           centred panel on ink. The fallback, and what
                          index.html and the library use.
     .deck-gate--cover    the deck's own cover slide, with the form cut
                          into it on a diagonal. Built automatically for
                          any deck whose first slide has a full-bleed
                          image, so each deck gets its own gate for free.

   The gate lives on <body>, which is content-box, while the UA gives
   <button> border-box — which is what used to leave the input and the
   button different widths. Pin the whole component to border-box and
   size both controls off one height token so they cannot drift again. */
.deck-gate {
  --gate-control: 62px;
  position: fixed; inset: 0; z-index: 80;
  display: flex; align-items: center; justify-content: center;
  background: var(--mmgy-ink); color: var(--mmgy-white);
}
.deck-gate, .deck-gate *, .deck-gate *::before, .deck-gate *::after { box-sizing: border-box; }
.deck-gate__panel { width: min(420px, calc(100% - 48px)); font-family: var(--font-text); }
.deck-gate__panel.is-wrong { animation: gate-shake .4s; }
@keyframes gate-shake { 0%,100% { translate: 0 } 20% { translate: -9px } 40% { translate: 9px } 60% { translate: -5px } 80% { translate: 5px } }
.deck-gate__panel .t-eyebrow { font-size: 11px; margin: 0 0 12px; }
.deck-gate__panel h1 { font-size: 40px; margin: 0 0 28px; }
.deck-gate__panel input,
.deck-gate__panel button[type="submit"] {
  display: block; width: 100%; height: var(--gate-control);
  font-family: var(--font-text); border-radius: 0;
}
.deck-gate__panel input {
  padding: 0 18px; font-size: 16px; font-weight: 500;
  background: none; border: 3px solid currentColor; color: inherit;
}
.deck-gate__panel input:focus { outline: 0; border-color: var(--mmgy-red); }
.deck-gate__panel button[type="submit"] {
  margin-top: 14px; padding: 0; border: 0; text-align: center;
  background: var(--mmgy-red); color: var(--mmgy-white); font-weight: 700;
  font-size: 12px; letter-spacing: .18em; text-transform: uppercase;
}
.deck-gate__err { color: var(--mmgy-red); font-size: 13px; margin: 14px 0 0; }
body.is-gated deck-stage, body.is-gated .deck-ui, body.is-gated .deck-progress { visibility: hidden; }

/* ── Gate · cover variant ─────────────────────────────────────────
   The photo is the cover slide's own image, so unlocking can hand over
   to the real slide without a visible seam: the panel slides out, the
   photo settles onto the exact rect the stage occupies, and the cover
   replays its entrance underneath. The form appears to peel off the
   title slide rather than being replaced by it. */
.deck-gate--cover {
  --gate-panel: clamp(340px, 38vw, 620px);
  --gate-slant: clamp(48px, 6.5vw, 140px);
  display: block; overflow: hidden;
  /* The panel colour is the ground, and the photo is cut over the top of
     it — otherwise an opaque panel would simply hide the diagonal. On
     unlock this fades to ink so the stage's letterbox bars have something
     to arrive against. */
  background: var(--mmgy-stone); color: var(--mmgy-ink);
  transition: background-color .5s ease;
}
.deck-gate--cover.is-unlocking { background: var(--mmgy-ink); }
.deck-gate__media {
  position: absolute; left: 0; top: 0; height: 100%; z-index: 1;
  width: calc(100% - var(--gate-panel) + var(--gate-slant));
  clip-path: polygon(0 0, 100% 0, calc(100% - var(--gate-slant)) 100%, 0 100%);
  transition: left .85s cubic-bezier(.65,0,.2,1), top .85s cubic-bezier(.65,0,.2,1),
              width .85s cubic-bezier(.65,0,.2,1), height .85s cubic-bezier(.65,0,.2,1),
              clip-path .85s cubic-bezier(.65,0,.2,1);
}
.deck-gate__photo { width: 100%; height: 100%; object-fit: cover; display: block; }
.deck-gate__wash {
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--mmgy-ink) 90%, transparent) 0%,
    color-mix(in srgb, var(--mmgy-ink) 58%, transparent) 52%,
    transparent 100%);
}
.deck-gate__brand {
  position: absolute; left: clamp(40px, 6.6vw, 128px); top: 50%; translate: 0 -50%;
  width: min(56%, 900px); z-index: 2;
  transition: opacity .4s ease, translate .5s ease;
}
.deck-gate__logo { display: block; width: clamp(64px, 5.6vw, 104px); margin-bottom: clamp(28px, 3.4vw, 56px); }
.deck-gate__brand .t-eyebrow { font-size: clamp(11px, .82vw, 15px); opacity: .72; margin: 0; }
.deck-gate__title {
  font-size: clamp(38px, 4.4vw, 82px); line-height: .94; margin: clamp(14px, 1.5vw, 28px) 0 0;
  color: var(--mmgy-white);
}
.deck-gate--cover .deck-gate__panel {
  position: absolute; right: 0; top: 0; z-index: 2;
  width: var(--gate-panel); height: 100%; max-width: none;
  display: flex; flex-direction: column; justify-content: center;
  /* Clear the diagonal. The cut reaches furthest into the panel at the top
     of the form block, so budget most of the slant rather than half of it. */
  padding: 0 clamp(36px, 3.6vw, 80px) 0 calc(var(--gate-slant) * .72 + clamp(20px, 1.6vw, 36px));
  background: none; color: var(--mmgy-ink);
  transition: translate .6s cubic-bezier(.65,0,.2,1), opacity .45s ease;
}
.deck-gate--cover .deck-gate__panel h1 { font-size: clamp(30px, 2.4vw, 44px); }

.deck-gate.is-unlocking { pointer-events: none; }
.deck-gate--cover.is-unlocking .deck-gate__media { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
.deck-gate--cover.is-unlocking .deck-gate__panel { translate: 100% 0; opacity: 0; }
.deck-gate--cover.is-unlocking .deck-gate__brand { opacity: 0; translate: 0 calc(-50% - 18px); }
.deck-gate.is-gone { opacity: 0; transition: opacity .45s ease; }

@media (max-width: 900px) {
  .deck-gate--cover { --gate-panel: 100%; --gate-slant: 0px; }
  .deck-gate--cover .deck-gate__brand { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .deck-gate__media, .deck-gate__brand, .deck-gate--cover .deck-gate__panel,
  .deck-gate.is-gone { transition: none !important; }
  .deck-gate__panel.is-wrong { animation: none !important; }
}

.deck-expired {
  min-height: 100vh; display: flex; flex-direction: column; justify-content: center;
  gap: 20px; padding: 8vw; background: var(--mmgy-ink); color: var(--mmgy-white);
  font-family: var(--font-text);
}

@media print { .deck-progress, .deck-ui, .deck-help, .deck-gate { display: none !important; } }
@media (max-width: 640px) { .deck-ui { top: auto; bottom: 14px; right: 14px; opacity: 1; } }
