/* State layer.
 *
 * The canvas version wrote these states straight into element.style from the
 * scroll handler. They are CSS classes now, so the script only toggles a flag
 * and the look stays in the stylesheet.
 */

/* ------------------------------------------------------------------ hidden */
/* Most elements on this page get their display from a generated class, and a
   class beats the UA stylesheet's [hidden] { display: none }. Without this,
   setting .hidden = true silently does nothing — which is why every crypt
   stage rendered at once and why leaving the crypt appeared to do nothing. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------- gold buttons */
/* base.css sets `a:hover { color: var(--gold-ink-lit) }` — specificity (0,0,1,1), which
   outranks the (0,0,1,0) class that gives these buttons their dark label. So
   every gold button turned gold-on-gold on hover and its text disappeared.
   A class + pseudo-class selector is (0,0,2,0) and wins it back. */
.o-page-6:hover,
.header-cta:hover,
.o-heroinner-10:hover,
.o-heroinner-24:hover,
.o-kitsumi-15:hover,
.o-rps-5:hover,
.o-rps-12:hover,
.o-support-6:hover,
.o-contact-6:hover {
  color: var(--ink-on-gold);
}

/* ------------------------------------------------------------------ header */
#site-header {
  transition: padding .3s ease, background .3s ease, border-color .3s ease;
}
#site-header.is-stuck {
  padding: 9px 28px;
  background: var(--bg0a0812f2);
  border-bottom-color: var(--line2a2442);
}

/* Theme button, links and call to action sit in one row on the right. On
   desktop this reproduces the single <nav> the design had. */
.header-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}
.nav-toggle { display: none; }

/* --------------------------------------------------------------- nav links */
[data-nav] {
  border-bottom: 2px solid transparent;
  transition: color .25s, border-color .25s;
}
[data-nav].is-active {
  color: var(--gold-ink-lit);
  border-bottom-color: var(--gold);
}

/* --------------------------------------------------------------------- faq */
.faq-tab { position: relative; }
.faq-tab-pill {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  border: 1px solid var(--gold);
  background: var(--bg1c1533);
  box-shadow: 0 0 22px #c9982f33;
  opacity: 0;
  transition: opacity .25s;
}
.faq-tab[aria-selected="true"] .faq-tab-pill { opacity: 1; }
.faq-tab-label { position: relative; }
.faq-tab[aria-selected="true"] .faq-tab-label { color: var(--gold-ink-lit); }

.faq-sign { transition: transform .35s cubic-bezier(.2,.8,.2,1), border-color .3s, color .3s; }
.faq-q[aria-expanded="true"] .faq-sign { border-color: var(--gold-lit); color: var(--gold-ink-lit); }
.faq-a { animation: answerIn .45s cubic-bezier(.2,.8,.2,1); }

/* ------------------------------------------------------------------- toast */
.toast {
  position: fixed;
  /* pinned to both gutters and centred by auto margins, so a phone gets the
     full width while wider screens keep the same centred, 520px-capped card */
  left: 16px;
  right: 16px;
  margin: 0 auto;
  width: fit-content;
  bottom: 28px;
  z-index: 90;
  max-width: 520px;
  border: 1px solid var(--gold);
  background: var(--bg0e0c18f2);
  box-shadow: 0 20px 60px var(--shadow-000);
  padding: 16px 20px;
  border-radius: 16px;
  animation: toastIn .4s cubic-bezier(.2,.8,.2,1);
}
.toast-kicker {
  font-family: 'Cinzel', serif;
  font-size: 12px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gold-ink-lit);
  margin-bottom: 6px;
}
.toast-text {
  font-size: 17px;
  line-height: 1.5;
  color: var(--inkece8f2);
  text-wrap: pretty;
}

/* ------------------------------------------------------------ performance */
/* will-change was set permanently on nine parallax elements, so nine
   compositor layers were pinned for the life of the page whether or not
   anything moved. The hint is handed back only while a scroll or a pointer
   sweep is actually in progress. */
html.is-moving [data-parallax] { will-change: transform; }

/* Anything whose section is off-screen stops ticking. The page declares ~135
   infinite animations; without this, the ones in sections nobody is looking at
   still burn a frame budget. Petals and fireflies are fixed to the viewport,
   so they are never idled this way — only the whole tab going away stops them. */
.anim-idle,
.anim-idle *,
html.page-hidden #fx-petals *,
html.page-hidden #fx-fireflies * {
  animation-play-state: paused !important;
}

/* ------------------------------------------------------------------- crypt */
/* The chamber stacked its blocks flush against each other. */
.crypt-stack > * + * { margin-top: 22px; }

/* Solved stages read as done rather than as inputs waiting for you. */
#crypt input[disabled] {
  opacity: .75;
  cursor: default;
  border-color: var(--ink4ea36a80);
  color: var(--inkb6b0c6);
}

.crypt-exit {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line-4a4463);
  background: var(--bg0a0812cc);
  color: var(--inkc4bfd2);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
  transition: color .25s, border-color .25s, background .25s;
}
.crypt-exit:hover { color: var(--gold-ink-lit); border-color: var(--gold); background: var(--bg1c1533); }

.crypt-hint {
  margin: 18px 0 0;
  font-family: 'Cinzel', serif;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink726d85);
}

/* Only offered once all nine stages are done. */
.quest-reset {
  margin-top: 10px;
  font-family: 'Cinzel', serif;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  background: none;
  border: 1px solid var(--line-4a4463);
  color: var(--ink8e88a2);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  transition: color .25s, border-color .25s;
}
.quest-reset:hover { color: var(--gold-ink-lit); border-color: var(--gold); }

/* ----------------------------------------------------- quest toggle + panel */
/* The folded-away tracker is the only sign a quest is running, so the mark
   breathes and catches now and then — a rune remembering it is there, not a
   notification badge demanding attention. */
@keyframes questBreathe {
  0%, 100% { box-shadow: 0 14px 40px var(--shadow-000), 0 0 0 #c9982f00; }
  50%      { box-shadow: 0 14px 40px var(--shadow-000), 0 0 18px #c9982f66; }
}
/* mostly still, with a brief double catch of light — the timing the site's own
   squareBlink and eyes keyframes already use */
@keyframes questCatch {
  0%, 86%   { opacity: .82; transform: scale(1) rotate(0deg); }
  90%       { opacity: 1;   transform: scale(1.18) rotate(18deg); }
  93%       { opacity: .78; transform: scale(1) rotate(0deg); }
  96%       { opacity: 1;   transform: scale(1.1) rotate(-10deg); }
  100%      { opacity: .82; transform: scale(1) rotate(0deg); }
}
/* a ring that leaves the mark and fades, like a dropped stone */
@keyframes questRipple {
  0%   { transform: scale(1); opacity: .5; }
  70%  { transform: scale(1.75); opacity: 0; }
  100% { transform: scale(1.75); opacity: 0; }
}

#quest-toggle button {
  position: relative;
  display: grid;
  place-items: center;
  line-height: 1;
  /* the glow breathes on one cycle, the glyph catches on a longer one, so the
     two never settle into a pattern */
  animation: questBreathe 6s ease-in-out infinite,
             questCatch 9s ease-in-out infinite;
  transition: transform .35s cubic-bezier(.2,.8,.2,1), background .25s, color .25s;
}
#quest-toggle button::before {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  animation: questRipple 6s ease-in-out infinite;
  pointer-events: none;
}
#quest-toggle button:hover,
#quest-toggle button:focus-visible {
  transform: scale(1.12) rotate(-12deg);
}

/* The panel is a surface you read, so it answers the cursor rather than
   animating on its own. */
#quest-tracker > div {
  transition: border-color .3s, box-shadow .3s, transform .3s cubic-bezier(.2,.8,.2,1);
}
#quest-tracker > div:hover {
  border-color: var(--gold-lit);
  box-shadow: 0 26px 74px var(--shadow-000), 0 0 26px #c9982f33;
  transform: translateY(-2px);
}

/* ------------------------------------------------------------------- quest */
/* Two small controls the quest script creates rather than ships as markup:
   the footer progress badge and the mute switch in the tracker. */
.quest-badge {
  font-family: 'Cinzel', serif;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gold-ink);
  border: 1px solid #c9982f4d;
  border-radius: 999px;
  padding: 4px 10px;
  animation: flagPulse 6s ease-in-out infinite;
}
/* ------------------------------------------------------------------ sound */
/* The canvas played hover, tap, theme and FAQ cues for every visitor and had
   no control anywhere in its markup. Same cues, plus a way to stop them. */
.sound-toggle {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line2a2442);
  background: none;
  color: var(--inkc4bfd2);
  cursor: pointer;
  margin-right: 6px;
  transition: color .25s, border-color .25s;
}
.sound-toggle svg { width: 15px; height: 15px; }
.sound-toggle:hover { color: var(--gold-ink-lit); border-color: var(--gold); }
.sound-toggle[aria-pressed="false"] { color: var(--ink726d85); }

/* ------------------------------------------------------------------ mobile */
/* The nav was a flex row that wrapped: on a 375px screen it took four lines and
   a fixed header 253px tall — a third of the viewport, permanently. Below this
   width the links collapse into a drawer and the bar keeps the two things worth
   a tap on arrival: the theme switch and Get Kitsumi. */
@media (max-width: 1040px) {
  #site-header,
  #site-header.is-stuck { padding-left: 16px; padding-right: 16px; }

  /* base.css offsets anchor jumps by the desktop header height */
  html { scroll-padding-top: 72px; }

  .nav-toggle {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    margin-left: 2px;
    border: 1px solid var(--line2a2442);
    border-radius: 10px;
    background: none;
    color: var(--inkc4bfd2);
    cursor: pointer;
    transition: color .25s, border-color .25s;
  }
  .nav-toggle svg { width: 20px; height: 20px; }
  .nav-toggle:hover { color: var(--gold-ink-lit); border-color: var(--gold); }
  #site-header.nav-open .nav-toggle { color: var(--gold-ink-lit); border-color: var(--gold); }

  .header-cta { font-size: 11px; padding: 10px 13px; margin-left: 4px; }

  /* the drawer hangs off the fixed header rather than pushing the page down */
  #site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    padding: 6px 16px 16px;
    background: var(--bg0a0812f7);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--line2a2442);
    box-shadow: 0 24px 60px var(--shadow000a);
  }
  #site-header.nav-open #site-nav { display: flex; }

  #site-nav [data-nav] {
    padding: 13px 4px;
    font-size: 18px;
    line-height: 1.25;
    white-space: normal;
    border-bottom: 1px solid var(--lineffffff0d);
    border-left: 2px solid transparent;
  }
  /* the desktop underline would sit under a full-width row; mark the active
     link down the side instead */
  #site-nav [data-nav].is-active {
    border-bottom-color: var(--lineffffff0d);
    border-left-color: var(--gold);
    padding-left: 12px;
  }
}

@media (max-width: 400px) {
  /* the wordmark is the first thing to go; the mark still carries the brand */
  .o-siteheader-3 { display: none; }
}

/* Touch targets: the design sized these for a cursor. border-box so the 44px
   counts the padding rather than adding to it. */
@media (pointer: coarse) {
  #site-nav [data-nav],
  .faq-tab {
    box-sizing: border-box;
    min-height: 44px;
  }
  .faq-tab { display: inline-flex; align-items: center; }
}

/* The design ships a lot of decorative layers that carry no meaning; keep them
   out of the accessibility tree and off the print sheet. */
@media print {
  #fx-petals, #fx-fireflies, [data-marquee] { display: none !important; }
}

/* ── quest navigation ────────────────────────────────────────────────────
   The canvas carried a hint for each stage and never showed one, so the
   tracker told you where you were but not what to do. The stage you are on
   now states it, is marked down its left edge, and the ones behind you
   recede. */
.quest-hint {
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--inkb6b0c6);
  text-wrap: pretty;
}
[data-quest-stages] > div {
  padding-left: 8px;
  border-left: 2px solid transparent;
  transition: border-color .3s, opacity .3s;
}
[data-quest-stages] > div.is-now {
  border-left-color: var(--gold);
}
[data-quest-stages] > div.is-done {
  opacity: .55;
}

/* ── the descent rose and its petals ─────────────────────────────────────
   Driven by initDescentBloom: the flower free-spins when stirred and springs
   back when pushed, and these fall from it and get caught in whatever whirl
   the cursor is making. The layer is clipped by the section itself. */
.bloom-petals {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}
.bloom-petals i {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  border-radius: 60% 40% 55% 45% / 65% 60% 40% 35%;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .bloom-petals { display: none; }
}

/* ── the third hero card ─────────────────────────────────────────────────
   Rook, Paper, Scissors! is the flagship and keeps the filled gold pill; the
   newcomer takes an outlined one, so the row reads as a hierarchy rather than
   three things shouting equally. */
.hero-pill-new {
  font-family: 'Cinzel', serif;
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold-ink-lit);
  border: 1px solid var(--gold);
  border-radius: 999px;
  padding: 2px 9px;
  margin-right: 8px;
}

/* Three cards need a little less minimum than two did, or the row breaks to
   2 + 1 well before it has to. */
@media (min-width: 900px) {
  .o-heroinner-12 > div { min-width: 240px; }
}

/* ── the star chain: navigation between stages ───────────────────────────
   The canvas tracker was a scoreboard — it told you which of the nine you had
   cleared and never how to get back to one. Nine marks, one per stage, sitting
   above the list: filled behind you, lit where you are, outlined ahead, and a
   bare dot for the three the quest never announces. */
.quest-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2px;
  margin: 2px 0 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--lineffffff12);
}
.quest-nav-star {
  flex: 1;
  min-width: 0;
  height: 26px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--ink7b7498);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: color .2s, background-color .2s, transform .2s;
}
.quest-nav-star:hover:not(:disabled) {
  background: var(--lineffffff12);
  color: var(--gold-ink-lit);
  transform: translateY(-2px);
}
.quest-nav-star:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 1px; }
.quest-nav-star.is-done { color: var(--gold-ink); }
.quest-nav-star.is-now {
  color: var(--gold-ink-lit);
  animation: questBreathe 2.4s ease-in-out infinite;
}
.quest-nav-star.is-locked {
  color: var(--ink3b3552);
  cursor: default;
  font-size: 16px;
}

/* the stage rows travel too, so the whole panel is one map */
[data-quest-stages] > div.is-travel { cursor: pointer; border-radius: 8px; }
[data-quest-stages] > div.is-travel:hover { background: var(--lineffffff0a); }
[data-quest-stages] > div.is-travel:focus-visible { outline: 2px solid var(--gold-ink); outline-offset: 2px; }

/* where you were sent, so the page does not just silently stop somewhere */
.quest-ping {
  animation: questPing 1.6s ease-out 1;
  border-radius: 10px;
}
@keyframes questPing {
  0%, 100% { box-shadow: 0 0 0 0 #c9982f00; }
  18%, 62% { box-shadow: 0 0 0 6px #c9982f33, 0 0 26px #c9982f55; }
}

/* ── the hero on a phone ─────────────────────────────────────────────────
   The hero is a full-bleed gold sunrise whose bright core sits at the *bottom*
   of the section. The canvas sized it for a desktop window: 105px of padding
   top and bottom, a 22px lede, and a card cluster that wraps to a column. On a
   375×812 phone that came to 1702px — two and a bit screens of scrolling
   before the glow the section is built around ever arrives. This brings it to
   roughly one and a quarter. */
@media (max-width: 720px) {
  /* the header is fixed and 71px tall here, so this is the floor */
  .o-top-1 { padding: 86px 0 60px; min-height: 0; }
  .o-top-8 { margin-top: 26px; }
  .o-heroinner-7 { font-size: 17px; margin-top: 18px; }
  .o-heroinner-9 { margin-top: 24px; }

  /* Three cards stacked is 600px of hero. They are peers, so they become a
     snap row instead — the next one peeks in at the edge, which is its own
     invitation to swipe. */
  .o-heroinner-12 {
    flex-wrap: nowrap;
    justify-content: flex-start;
    align-items: stretch;
    margin: 30px -28px 0;
    padding: 0 28px 4px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .o-heroinner-12::-webkit-scrollbar { display: none; }
  .o-heroinner-12 > * {
    flex: 0 0 85%;
    min-width: 0;
    max-width: 85%;
    scroll-snap-align: center;
  }
}

/* ── the three that were genuinely too faint ─────────────────────────────
   Most of the canvas's dim greys are decoration — separators, a ✦, the chrome
   of a mocked-up video player — and dimming those is the point. These three
   carry something: the Japanese demo line, the instruction at the bottom of
   the descent, and the one piece of mock chrome big enough to read as text.
   var(--line-4a4463) on var(--bg-0a0812) is 2.2:1 and var(--ink726d85) is 4.0:1; both are below AA. */
.o-kitsumi-49 { color: var(--ink9a94b2); }   /* 4.0 -> 5.6:1 */
.o-page-60    { color: var(--ink8a83a6); }   /* 2.2 -> 4.7:1 */
.o-kitsumi-24 { color: var(--ink6d6789); }   /* 2.2 -> 3.5:1, decorative but legible */

/* ── III · LeoNote ───────────────────────────────────────────────────────
   The section shell is the Rook, Paper, Scissors! one — same two-column head,
   same three cards underneath — so the third product reads as a peer of the
   first two rather than a bolt-on. Only the chrome of the mock is new. */
.leo-sect { padding-top: clamp(28px, 4vw, 52px); overflow: hidden; }
.leo-wash {
  position: absolute;
  left: 50%;
  top: 0;
  width: min(900px, 92vw);
  height: 62%;
  transform: translateX(-50%);
  pointer-events: none;
  background: radial-gradient(closest-side, #c9982f16, transparent 72%);
}
.leo-rule { height: 1px; flex: 1; background: linear-gradient(90deg, #c9982f66, var(--lineffffff14) 30%, transparent); }
.leo-pill {
  font-family: 'Cinzel', serif;
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--gold-ink-lit);
  border: 1px solid var(--gold);
  border-radius: 999px;
  padding: 4px 11px;
}

/* the mock: a graph view with the note it belongs to underneath */
.leo-mock {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--line2a2442);
  border-radius: 18px;
  background: linear-gradient(var(--bg15121f), var(--bg0d0b16));
  box-shadow: 0 30px 80px var(--shadow0009);
  transform-style: preserve-3d;
  transition: transform .18s ease-out, border-color .35s;
}
.leo-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line211c33);
  background: var(--bg0f0c1a);
}
.leo-icon { width: 20px; height: 20px; border-radius: 5px; flex-shrink: 0; }
.leo-path {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--ink8e88a2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.leo-dots { margin-left: auto; display: flex; gap: 5px; flex-shrink: 0; }
.leo-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--bg2f2a44); }

.leo-graph { position: relative; display: block; width: 100%; height: auto; }
.leo-node { animation: beacon 3.6s ease-in-out infinite; transform-origin: 246px 128px; }
.leo-halo { opacity: .5; animation: leoHalo 3.6s ease-in-out infinite; transform-origin: 246px 128px; }
@keyframes leoHalo {
  0%, 100% { transform: scale(1); opacity: .5; }
  50%      { transform: scale(1.9); opacity: 0; }
}
.leo-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  fill: var(--gold-ink-lit);
  letter-spacing: .04em;
}
.leo-sub {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  fill: var(--ink8e88a2);
  letter-spacing: .04em;
}

.leo-line {
  position: relative;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.6;
  color: var(--inkb6b0c6);
  padding: 13px 16px 15px;
  border-top: 1px solid var(--line211c33);
  background: var(--bg0b0914);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.leo-h { color: var(--gold-ink); }
.leo-link { color: var(--inka78bfa); }          /* LeoNote's own link violet */
.leo-caret {
  display: inline-block;
  width: 7px;
  height: 14px;
  margin-left: 3px;
  vertical-align: -2px;
  background: var(--gold-lit);
  animation: blink 1.1s step-end infinite;
}

/* ── the four steps on a phone ───────────────────────────────────────────
   Watch / Understand / Learn / Remember is a three-column grid: a 68px number
   gutter, a 200px title column and the copy. At 375px the first two eat the
   row and the third resolves to 0px wide, so every paragraph wrapped one
   character per line and each step stood 343px tall. One column instead. */
@media (max-width: 720px) {
  .o-kitsumi-37 {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: 7px;
    padding: 17px 18px 19px 20px;
  }
  .o-kitsumi-39 { margin-bottom: 1px; }
}

/* ── the quest panel is an object, not a sheet ───────────────────────────
   Everything else on the page with [data-panel] tilts toward the cursor. The
   tracker is injected long after init() has run, so it never got wired; it
   does now, and it is the one panel that most deserves it. */
#quest-tracker .q-2 {
  transform-style: preserve-3d;
  transition: transform .18s ease-out, border-color .35s, box-shadow .35s;
}
#quest-tracker .q-2::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 18px;
  pointer-events: none;
  opacity: var(--glow, 0);
  transition: opacity .35s;
  background: radial-gradient(220px 220px at var(--mx, 50%) var(--my, 50%), #c9982f26, transparent 70%);
}
#quest-tracker .q-2 { position: relative; }
#quest-tracker .q-2:hover { box-shadow: 0 30px 80px var(--shadow-000), 0 0 30px #c9982f22; }

/* The header's icon buttons and the footer's link row were sized for a cursor;
   on a touch screen they are 30px and 34px tall. Grown here rather than in the
   base rules so the desktop proportions are untouched. */
@media (pointer: coarse) {
  .o-siteheader-5,
  .sound-toggle { width: 40px; height: 40px; }
  footer nav a.o-page-22 {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* ── the tracker in the light theme ──────────────────────────────────────
   quest.css is not themed — the crypt and the balcony are the same rooms in
   either theme — but the tracker is page furniture, not a room, so it follows
   the page. Written here rather than in quest.css because this is the file
   that already knows about themes. */
html[data-theme="light"] #quest-tracker .q-2,
html:has([data-theme="light"]) #quest-tracker .q-2 {
  background: #fffdf8f5;
  box-shadow: 0 24px 70px #2a1f0e26;
}
html[data-theme="light"] #quest-tracker .q-2:hover,
html:has([data-theme="light"]) #quest-tracker .q-2:hover {
  box-shadow: 0 30px 80px #2a1f0e2e, 0 0 30px #c9982f33;
}
html[data-theme="light"] #quest-toggle .q-14,
html:has([data-theme="light"]) #quest-toggle .q-14 {
  background: #fffdf8f0;
  color: var(--gold-ink-lit);
  box-shadow: 0 14px 40px #2a1f0e2b;
}

/* ── the reds, over parchment ────────────────────────────────────────────
   The petals and the vine roses are painted for a near-black sky: a deep
   carmine that fades to #3a060c. Against parchment the dark end reads as a
   smudge rather than a flower, so in the light theme they are lifted — the
   same reds, a little more light and a little more chroma in them. */
html[data-theme="light"] #fx-petals > div,
html:has([data-theme="light"]) #fx-petals > div,
html[data-theme="light"] .bloom-petals i,
html:has([data-theme="light"]) .bloom-petals i,
html[data-theme="light"] #vine-left,
html:has([data-theme="light"]) #vine-left,
html[data-theme="light"] #vine-right,
html:has([data-theme="light"]) #vine-right,
html[data-theme="light"] [data-vine],
html:has([data-theme="light"]) [data-vine],
html[data-theme="light"] #descent-bloom,
html:has([data-theme="light"]) #descent-bloom,
html[data-theme="light"] .o-about-2,
html:has([data-theme="light"]) .o-about-2 {
  filter: brightness(1.24) saturate(1.2);
}

/* ── the two edges, on a touch screen ────────────────────────────────────
   The balcony is reached by pulling up when the page is already at the top,
   which on a phone is the browser's own pull-to-refresh gesture — so the page
   reloaded instead. overscroll-behavior stops that. And while either scene is
   open it covers the viewport, so the drag belongs to the scene rather than to
   the document underneath it. */
html { overscroll-behavior-y: contain; }
#quest-host [data-dawn],
#quest-host [data-dig] { touch-action: none; }

/* the gesture is not the one the desktop copy describes, so on touch it gets
   said out loud, once per scene */
.quest-gesture {
  position: fixed;
  /* left:50% + translateX(-50%) would shrink-wrap against the right half of
     the viewport and come out 188px wide on a phone; left+right+auto margins
     give it the whole width to centre in */
  left: 16px;
  right: 16px;
  bottom: 22px;
  z-index: 200;
  width: auto;
  max-width: 340px;
  margin: 0 auto;
  box-sizing: border-box;
  padding: 12px 16px;
  border: 1px solid #c9982f;
  border-radius: 14px;
  background: #0b0914f2;
  backdrop-filter: blur(8px);
  box-shadow: 0 18px 50px #000b;
  color: #ece8f2;
  font-size: 14px;
  line-height: 1.4;
  text-align: center;
  pointer-events: none;
  animation: gestureIn .4s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes gestureIn {
  0%   { transform: translateY(26px); opacity: 0; }
  100% { transform: none; opacity: 1; }
}
.quest-gesture b {
  display: block;
  margin-bottom: 3px;
  font-family: 'Cinzel', serif;
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #e8b84b;
}
.quest-gesture.is-out { animation: gestureIn .35s ease reverse both; }

/* the ribbon's dark hairline read as a crack between the hero and the gold */
.o-top-10 { border-top: 0; }

/* ── the three runes, before they are taken (a candle-like golden flicker) ──────────────────────────────
   A slow shimmer through rose, azure and verdigris: enough to catch an eye
   that is looking, not enough to shout. Gone once the rune is taken. */
@keyframes runeMyth {
  0%, 100% { filter: drop-shadow(0 0 4px #e8b84b) drop-shadow(0 0 10px #e8b84b55); }
  8%       { filter: drop-shadow(0 0 7px #ffd98a) drop-shadow(0 0 16px #e8b84b99); }
  11%      { filter: drop-shadow(0 0 3px #c9982f) drop-shadow(0 0 6px #c9982f44); }
  14%      { filter: drop-shadow(0 0 8px #fff0c2) drop-shadow(0 0 18px #e8b84baa); }
  40%      { filter: drop-shadow(0 0 5px #e8b84b) drop-shadow(0 0 12px #e8b84b66); }
  63%      { filter: drop-shadow(0 0 3px #c9982f) drop-shadow(0 0 8px #c9982f44); }
  66%      { filter: drop-shadow(0 0 7px #ffd98a) drop-shadow(0 0 15px #e8b84b88); }
}
.rune:not(.is-taken) { animation: runeMyth 4.8s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .rune:not(.is-taken) { animation: none; filter: drop-shadow(0 0 6px #e8b84b); }
}

/* ── the RPS board, as a little play ─────────────────────────────────────
   One 12s loop, riding on the 6s one the canvas gave the rook and scissors.
   Early on a sheet of paper plaps down and squashes both pieces; the
   scissors snip their way out and the halves fall away. Every time the rook
   steps in (27% and 77% here), the scissors clap back at it. */
.o-rps-24 { transform-origin: 50% calc(50% + 36px); animation: rpsSquash 12s ease-out infinite; }
@keyframes rpsSquash {
  0%, 3.9%, 17%, 100% { transform: none; }
  4.5%            { transform: scale(1.1, .7); }
  5.6%, 14.4%     { transform: scale(1.05, .8); }
  15.4%           { transform: scale(.96, 1.08); }
}

/* each piece of the scissors is a blade and the opposite ring, hinged on the
   pivot, so closing the blades also pulls the rings together */
.o-rps-27 .sc-a, .o-rps-27 .sc-b { transform-box: view-box; transform-origin: 30px 33px; }
.o-rps-27 .sc-a { animation: scA 12s ease-in-out infinite; }
.o-rps-27 .sc-b { animation: scB 12s ease-in-out infinite; }
@keyframes scA {
  0%, 11.4%, 12.4%, 13.2%, 14.2%, 15%, 16%, 27.6%, 28.6%, 29.6%, 30.6%,
  45%, 46.4%, 77.6%, 78.6%, 79.6%, 80.6%, 100% { transform: rotate(0deg); }
  11.9%, 13.7%, 15.5%, 28.1%, 30.1%, 45.7%, 78.1%, 80.1% { transform: rotate(-22deg); }
}
@keyframes scB {
  0%, 11.4%, 12.4%, 13.2%, 14.2%, 15%, 16%, 27.6%, 28.6%, 29.6%, 30.6%,
  45%, 46.4%, 77.6%, 78.6%, 79.6%, 80.6%, 100% { transform: rotate(0deg); }
  11.9%, 13.7%, 15.5%, 28.1%, 30.1%, 45.7%, 78.1%, 80.1% { transform: rotate(22deg); }
}

/* the sheet: falls, lands on the squashed pieces, and splits down the middle */
.rps-paper {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 240px;
  height: 40px;
  margin: -54px 0 0 -120px;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  animation: paperDrop 12s cubic-bezier(.55,0,.8,.2) infinite;
}
.rps-paper { filter: drop-shadow(0 12px 14px #000a); }
/* two halves of one sheet, cut along a matching zigzag so they read as a
   single page until the scissors go through */
.rps-paper i {
  position: absolute;
  top: 0;
  height: 100%;
  background:
    repeating-linear-gradient(#0000 0 9px, #8fb8ff38 9px 10px),
    linear-gradient(172deg, #fdf9ef, #ece3cf 58%, #d8cdb4);
}
.rps-paper i:first-child {
  left: 0; width: 120px; border-radius: 3px 0 0 3px;
  clip-path: polygon(0 0, 120px 0, 115px 20%, 120px 40%, 114px 60%, 120px 80%, 116px 100%, 0 100%);
  animation: paperL 12s cubic-bezier(.3,.1,.6,1) infinite;
}
.rps-paper i:last-child {
  left: 112px; width: 127px;   /* 1px overlap hides the seam */ border-radius: 0 3px 3px 0;
  clip-path: polygon(7px 0, 127px 0, 127px 100%, 3px 100%, 7px 80%, 1px 60%, 7px 40%, 2px 20%);
  animation: paperR 12s cubic-bezier(.3,.1,.6,1) infinite;
}
/* a leaf's fall: it swings side to side on the way down, then slaps flat */
@keyframes paperDrop {
  0%, .4%       { transform: translate(-30px, -250px) rotate(-14deg); opacity: 0; }
  .8%           { opacity: 1; }
  2%            { transform: translate(26px, -165px) rotate(11deg); }
  3.2%          { transform: translate(-16px, -82px) rotate(-7deg); }
  4.2%          { transform: translate(5px, -18px) rotate(2deg); }
  4.6%          { transform: translate(0, 0) scaleY(.68); }
  5.2%          { transform: translateY(-6px) scaleY(1.06); }
  5.8%, 14.4%   { transform: none; opacity: 1; }
  21%           { opacity: 1; }
  22.5%, 100%   { transform: none; opacity: 0; }
}
/* cut through: each half kicks outward, then tumbles away */
@keyframes paperL {
  0%, 15.2%     { transform: none; }
  16.4%         { transform: translate(-26px, -8px) rotate(-7deg); }
  19%           { transform: translate(-58px, 34px) rotate(-28deg) scaleX(.92); }
  22.5%, 100%   { transform: translate(-82px, 96px) rotate(-52deg) scaleX(.8); }
}
@keyframes paperR {
  0%, 15.2%     { transform: none; }
  16.4%         { transform: translate(26px, -8px) rotate(7deg); }
  19%           { transform: translate(58px, 34px) rotate(28deg) scaleX(.92); }
  22.5%, 100%   { transform: translate(82px, 96px) rotate(52deg) scaleX(.8); }
}

/* the impact: dust kicked out both sides, the board jolts, and a gold slit
   flashes down the sheet where the scissors cut */
.rps-paper::before, .rps-paper::after { content: ''; position: absolute; pointer-events: none; }
.rps-paper::before {
  left: -30px; right: -30px; bottom: -16px; height: 30px;
  background: radial-gradient(40% 60% at 12% 60%, #d8cfbd99, transparent 70%),
              radial-gradient(40% 60% at 88% 60%, #d8cfbd99, transparent 70%);
  filter: blur(3px);
  opacity: 0;
  animation: paperDust 12s ease-out infinite;
}
@keyframes paperDust {
  0%, 4.4%   { opacity: 0; transform: scaleX(.4); }
  5%         { opacity: 1; transform: scaleX(1); }
  9%, 100%   { opacity: 0; transform: scaleX(1.5) translateY(-8px); }
}
.rps-paper::after {
  left: calc(50% - 1px); top: -8px; bottom: -8px; width: 2px; z-index: 1;
  background: #ffe9a8;
  box-shadow: 0 0 12px 3px #e8b84b;
  opacity: 0;
  animation: paperSlit 12s linear infinite;
}
@keyframes paperSlit {
  0%, 11.8%  { opacity: 0; transform: scaleY(0); }
  13.6%      { opacity: .8; transform: scaleY(.6); }
  15.2%      { opacity: 1; transform: scaleY(1); }
  16.4%, 100% { opacity: 0; transform: scaleY(1); }
}
.o-rps-16 .o-rps-18 { animation: boardJolt 12s ease-out infinite; }
@keyframes boardJolt {
  0%, 4.4%, 7%, 100% { transform: none; }
  4.8%  { transform: translate(-3px, 4px); }
  5.4%  { transform: translate(3px, -2px); }
  6.2%  { transform: translate(-1px, 1px); }
}

/* ── phones: contact, footer, the rune rose, cheaper atmosphere ──────────
   The contact card's two auto-fit columns wanted 280px each plus 60px of
   padding, so on a phone the socials grid overflowed and the card clipped
   it. One column, full-width buttons, socials in a single list. The footer's
   four flex rows wrapped wherever they fell; here they stack and centre. */
@media (max-width: 720px) {
  .o-contact-1 { grid-template-columns: minmax(0, 1fr); padding: 28px 20px; }
  .o-contact-1 .o-kitsumi-14 { display: grid; gap: 10px; }
  .o-contact-6, .o-contact-7, .o-contact-8 { text-align: center; }
  .o-contact-9 { grid-template-columns: minmax(0, 1fr); gap: 0; font-size: 17px; }
  .o-contact-10 { padding: 13px 6px; }

  .o-page-8 { padding: 40px 20px 24px; }
  .o-page-17 { flex-direction: column; align-items: center; text-align: center; gap: 22px; }
  .o-page-18 { flex-direction: column; align-items: center; gap: 10px; }
  .o-page-20 { max-width: 300px; }
  .o-page-21 { justify-content: center; gap: 4px 18px; max-width: 340px; }
  .o-page-21 + .o-page-21 { border-top: 1px solid var(--line2a2442); padding-top: 16px; }
  .o-page-24 { display: none; }
  .o-page-25 { flex-direction: column; text-align: center; gap: 8px; margin-top: 24px; }

  /* the rune rose sat in a vine sized clamp(0px, 34vw - 200px, ...) - zero
     wide on a phone, so stage one could not be finished there */
  .o-kitsumi-3 { width: 96px; top: -8px; right: -6px; }

  /* the feature cards put a mockup beside the copy; at phone width that
     squeezed the copy, so the mockup drops under it */
  .o-kitsumi-46, .o-kitsumi-70 { grid-template-columns: minmax(0, 1fr); gap: 18px; }

  /* the header is solid here; two blurred, animated glows in the footer
     re-sample every frame */
  .o-page-7 { background: var(--bg0a0812f5); }
  .o-page-12, .o-page-13 { filter: none; animation: none; }
}

/* ── tilted panels keep their corners ────────────────────────────────────
   A panel's cursor glow is a square layer under overflow:hidden. Once the
   tilt gives the panel a 3D transform, Chrome composites the glow on its own
   and stops clipping it to the rounded corner, so a square of light showed
   past the curve wherever the cursor was. The glows take the panel's radius;
   the panels with no outer shadow to lose are also clipped outright, which
   catches the sheens as well. */
.panel-glow, .o-contact-2, .o-kitsumi-20, .o-kitsumi-35, .o-kitsumi-45,
.o-rps-17, .o-support-13, .o-support-5, .o-work-6 { border-radius: inherit; }
.o-work-5, .o-kitsumi-34, .o-kitsumi-44, .o-kitsumi-59, .o-kitsumi-69,
.o-rps-33 { clip-path: inset(0 round 18px); }
.o-faq-7, .o-support-12 { clip-path: inset(0 round 20px); }

/* ── the monthly goal under Support ─────────────────────────────────── */
.goal { margin-top: 22px; max-width: 520px; }
.goal-row { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; margin-bottom: 8px; }
.goal-label { font-family: 'Cinzel', serif; font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--gold-ink); }
.goal-sum { font-size: 17px; color: var(--inkece8f2); }
.goal-track { height: 8px; border-radius: 999px; background: var(--line2a2442); overflow: hidden; }
.goal-fill { width: 0; min-width: 8px; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #a8761c, var(--gold), #f6d98a); box-shadow: 0 0 14px #e8b84b66; transition: width 1.2s cubic-bezier(.2,.8,.2,1); }

/* Images and drawings are decoration, not text: a drag or Ctrl+A painted the
   whole descent scene in the selection colour. */
img, svg, .o-page-28, .o-page-28 * { -webkit-user-select: none; user-select: none; -webkit-user-drag: none; }

/* ── Fennek OS: the Leonote layout, a desert desktop in the frame ───── */
.fen-logo { width: 20px; height: 20px; border-radius: 5px; flex-shrink: 0; background: linear-gradient(135deg, #ffcf6b, #d9893f); }
.fen-tag { font-family: 'Cinzel', serif; font-size: 7px; letter-spacing: .14em; fill: #e8b84b; }
.fen-sun { animation: beacon 6s ease-in-out infinite; }
.fen-shield { animation: beacon 3.6s ease-in-out infinite; }

/* ── ?layout=compact: the page as an overview first, detail on request ──
   The "What I make" strip replaces the hero cards and the Work section; each
   product section shows its pitch and preview, and folds its feature cards
   behind a "More about" button (initCompact in site.js). */
.products { display: none; }
html[data-layout="compact"] .products { display: block; padding-top: clamp(36px, 5vw, 64px); }
.products-title { font-family: 'Cinzel', serif; font-weight: 600; font-size: clamp(28px, 3.6vw, 46px); margin: 0 0 22px; }
html[data-layout="compact"] .o-heroinner-12,
html[data-layout="compact"] #work,
html[data-layout="compact"] footer a[href="#work"],
html[data-layout="compact"] footer a[href="#work"] + .o-page-24,
html[data-layout="compact"] [data-faq-tab="medieval"],
html[data-layout="compact"] [data-faq-tab="youtube"] { display: none; }
html[data-layout="compact"] section:not(.is-open) > * > :is(.o-kitsumi-34, .o-kitsumi-43, .o-kitsumi-68, .o-rps-32) { display: none; }
.more-toggle {
  display: inline-flex; align-items: center; gap: 10px; margin: 6px 0 4px;
  font-family: 'Cinzel', serif; font-size: 13px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gold-ink-lit); background: none; border: 1px solid var(--line66607f);
  border-radius: 10px; padding: 13px 22px; cursor: pointer; transition: border-color .3s, color .3s;
}
.more-toggle:hover { border-color: var(--gold); }
.more-toggle::after { content: '↓'; transition: transform .3s; }
.is-open > * > .more-toggle::after { transform: rotate(180deg); }

/* ── compact, continued: About + Support, contact, the support cards ──── */
.compact-only { display: none; }
html[data-layout="compact"] .compact-only { display: block; }
html[data-layout="compact"] .about-support {
  margin-top: clamp(40px, 5vw, 64px); padding-top: clamp(28px, 4vw, 44px);
  border-top: 1px solid var(--line2a2442);
}

/* support cards: a clear ask, what it is, and a button that says where it goes */
html[data-layout="compact"] .o-support-3 { gap: 22px; }
html[data-layout="compact"] .o-support-4,
html[data-layout="compact"] .o-support-12 { display: flex; flex-direction: column; border-radius: 20px; }
html[data-layout="compact"] .o-support-12 { border-color: #f96854; }
html[data-layout="compact"] .o-support-12 .o-support-8 path,
html[data-layout="compact"] .o-support-12 .o-support-8 circle { stroke: #ff8a76; }
html[data-layout="compact"] .o-support-12 .o-support-8 circle { fill: #ff8a76; }
html[data-layout="compact"] .o-support-14 { color: #ff9d8c; }
.support-perks { list-style: none; margin: 16px 0 22px; padding: 0; display: grid; gap: 7px; font-size: 16px; color: var(--inkb6b0c6); }
.support-perks li::before { content: '✦'; margin-right: 10px; font-size: 11px; color: var(--gold-ink); }
.o-support-12 .support-perks li::before { color: #ff8a76; }
.support-cta {
  margin-top: auto; align-self: flex-start;
  font-family: 'Cinzel', serif; font-size: 13px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  padding: 14px 22px; border-radius: 10px; background: var(--gold); color: var(--ink-on-gold);
  transition: transform .3s cubic-bezier(.2,.8,.2,1), box-shadow .3s;
}
.o-support-12 .support-cta { background: #f96854; color: #fff; }
.o-support-4:hover .support-cta, .o-support-12:hover .support-cta { transform: translateX(4px); box-shadow: 0 10px 30px #0006; }

/* contact: the socials become tiles with a coloured mark per platform */
html[data-layout="compact"] .o-contact-9 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr)); gap: 10px; }
html[data-layout="compact"] .o-contact-10 {
  display: grid; grid-template-columns: 34px 1fr auto; grid-template-rows: auto auto; column-gap: 12px; align-items: center;
  border: 1px solid var(--line2a2442); border-radius: 12px; padding: 12px 14px; background: var(--lineffffff05);
}
html[data-layout="compact"] .o-contact-10:hover { padding-left: 14px; border-color: var(--gold); }
html[data-layout="compact"] .o-contact-10::before {
  grid-row: 1 / 3; width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;
  font: 700 15px/1 'EB Garamond', serif; color: #fff; background: #3a3350; content: '•';
}
html[data-layout="compact"] .o-contact-10 > span:first-child { font-size: 17px; }
html[data-layout="compact"] .o-contact-11 { grid-column: 2; font-size: 14px; gap: 6px; }
html[data-layout="compact"] .o-contact-12 { grid-column: 3; grid-row: 1 / 3; }
html[data-layout="compact"] .o-contact-10[href*="youtube"]::before   { content: '▶'; background: #e62e2e; font-size: 12px; }
html[data-layout="compact"] .o-contact-10[href*="twitch"]::before    { content: 'T'; background: #8a4fff; }
html[data-layout="compact"] .o-contact-10[href*="x.com"]::before     { content: 'X'; background: #111; border: 1px solid #444; }
html[data-layout="compact"] .o-contact-10[href*="instagram"]::before { content: '◎'; background: linear-gradient(135deg, #feda75, #d62976 55%, #4f5bd5); }
html[data-layout="compact"] .o-contact-10[href*="github"]::before    { content: '⌥'; background: #2b2f36; }
html[data-layout="compact"] .o-contact-10[href*="discord"]::before   { content: '✦'; background: #5865f2; }
html[data-layout="compact"] .o-contact-10[href*="linktr"]::before    { content: '✳'; background: #2fb35a; }
html[data-layout="compact"] .o-contact-5 { margin-bottom: 22px; }
html[data-layout="compact"] .o-contact-1 .o-kitsumi-14 { display: flex; flex-wrap: wrap; gap: 10px; }

/* ── ?btn= button experiments (default: the current look) ─────────────── */
html[data-btn] :is(.o-heroinner-10, .o-heroinner-11, .o-rps-12, .o-rps-13, .o-kitsumi-15, .o-kitsumi-16,
  .o-contact-6, .o-contact-7, .o-contact-8, .header-cta, .more-toggle, .support-cta) { transition: all .3s cubic-bezier(.2,.8,.2,1); }
/* pill: fully rounded */
html[data-btn="pill"] :is(.o-heroinner-10, .o-heroinner-11, .o-rps-12, .o-rps-13, .o-kitsumi-15, .o-kitsumi-16,
  .o-contact-6, .o-contact-7, .o-contact-8, .more-toggle, .support-cta) { border-radius: 999px; padding-left: 28px; padding-right: 28px; }
/* sharp: square corners, a heavier frame, like a stamped plate */
html[data-btn="sharp"] :is(.o-heroinner-10, .o-heroinner-11, .o-rps-12, .o-rps-13, .o-kitsumi-15, .o-kitsumi-16,
  .o-contact-6, .o-contact-7, .o-contact-8, .header-cta, .more-toggle, .support-cta) { border-radius: 2px; }
html[data-btn="sharp"] :is(.o-heroinner-10, .o-rps-12, .o-kitsumi-15, .o-contact-6, .header-cta, .support-cta) { box-shadow: inset 0 0 0 1px #0004, 4px 4px 0 #c9982f55; }
html[data-btn="sharp"] :is(.o-heroinner-10, .o-rps-12, .o-kitsumi-15, .o-contact-6, .header-cta):hover { transform: translate(-2px, -2px); box-shadow: inset 0 0 0 1px #0004, 6px 6px 0 #c9982f77; }
/* outline: gold becomes a line, filled only on hover */
html[data-btn="outline"] :is(.o-heroinner-10, .o-rps-12, .o-kitsumi-15, .o-contact-6, .header-cta, .support-cta) {
  background: transparent; color: var(--gold-ink-lit); border: 1px solid var(--gold); box-shadow: none;
}
html[data-btn="outline"] :is(.o-heroinner-10, .o-rps-12, .o-kitsumi-15, .o-contact-6, .header-cta):hover { background: var(--gold); color: var(--ink-on-gold); }
/* glow: a lit metal gradient and a halo */
html[data-btn="glow"] :is(.o-heroinner-10, .o-rps-12, .o-kitsumi-15, .o-contact-6, .header-cta, .support-cta) {
  background: linear-gradient(180deg, #f6d98a, #e8b84b 45%, #b8862a); box-shadow: 0 0 0 1px #f6d98a66, 0 8px 30px #e8b84b55, inset 0 1px 0 #fff8;
}
html[data-btn="glow"] :is(.o-heroinner-10, .o-rps-12, .o-kitsumi-15, .o-contact-6, .header-cta):hover { box-shadow: 0 0 0 1px #f6d98a, 0 10px 44px #e8b84b99, inset 0 1px 0 #fff; transform: translateY(-2px); }
html[data-btn="glow"] :is(.o-heroinner-11, .o-rps-13, .o-kitsumi-16, .o-contact-7, .o-contact-8, .more-toggle) { box-shadow: inset 0 0 18px #e8b84b14; }
html[data-layout="compact"] .about-support .o-support-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: end; }
html[data-layout="compact"] .about-support .o-work-2 { font-size: clamp(28px, 3.4vw, 44px); grid-column: 1 / -1; }
@media (max-width: 720px) { html[data-layout="compact"] .about-support .o-support-2 { grid-template-columns: minmax(0, 1fr); } }
/* support buttons: compact again, an icon each, sitting on the card's last line */
html[data-layout="compact"] .o-support-11 { margin-bottom: 16px; }
html[data-layout="compact"] .support-cta { display: inline-flex; align-items: center; gap: 9px; padding: 10px 18px 10px 14px; font-size: 12px; }
.support-cta-icon { width: 17px; height: 17px; flex-shrink: 0; }
html[data-btn] .o-support-12 .support-cta { background: linear-gradient(180deg, #ff8a76, #f96854 55%, #d9473a); color: #fff; box-shadow: 0 0 0 1px #ff8a7666, 0 8px 26px #f9685444, inset 0 1px 0 #fff6; border: 0; }

/* contact badges: each platform's mark, white on its colour */
html[data-layout="compact"] .o-contact-10[href*="youtube"]::before { content: ""; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M9 7.2v9.6l7.8-4.8z'/%3E%3C/svg%3E") center/20px no-repeat #e62e2e; }
html[data-layout="compact"] .o-contact-10[href*="twitch"]::before { content: ""; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath fill-rule='evenodd' d='M5 3 3.5 6.5V19H8v2.5h2.5L13 19h3.5L21 14.5V3Zm14 10.6L16.6 16H12l-2.5 2.4V16H6.4V5H19Z'/%3E%3Cpath d='M11 7.5h2v5h-2zm4.5 0h2v5h-2z'/%3E%3C/svg%3E") center/20px no-repeat #8a4fff; }
html[data-layout="compact"] .o-contact-10[href*="x.com"]::before { content: ""; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M4 4h4.7l3.9 5.4L17.4 4h2.4l-6.1 7 6.5 9h-4.7l-4.2-5.8L6.1 20H3.7l6.6-7.6z'/%3E%3C/svg%3E") center/20px no-repeat #111; }
html[data-layout="compact"] .o-contact-10[href*="instagram"]::before { content: ""; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Crect x='3.5' y='3.5' width='17' height='17' rx='5' fill='none' stroke='white' stroke-width='2'/%3E%3Ccircle cx='12' cy='12' r='4' fill='none' stroke='white' stroke-width='2'/%3E%3Ccircle cx='17.3' cy='6.7' r='1.3'/%3E%3C/svg%3E") center/20px no-repeat, linear-gradient(135deg,#feda75,#d62976 55%,#4f5bd5); }
html[data-layout="compact"] .o-contact-10[href*="github"]::before { content: ""; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M12 2a10 10 0 0 0-3.2 19.5c.5.1.7-.2.7-.5v-1.7c-2.8.6-3.4-1.3-3.4-1.3-.5-1.2-1.1-1.5-1.1-1.5-.9-.6.1-.6.1-.6 1 .1 1.5 1 1.5 1 .9 1.6 2.4 1.1 3 .8.1-.7.4-1.1.6-1.4-2.2-.2-4.6-1.1-4.6-5 0-1.1.4-2 1-2.7-.1-.3-.4-1.3.1-2.7 0 0 .8-.3 2.8 1a9.6 9.6 0 0 1 5 0c1.9-1.3 2.8-1 2.8-1 .5 1.4.2 2.4.1 2.7.6.7 1 1.6 1 2.7 0 3.9-2.3 4.7-4.6 5 .4.3.7.9.7 1.9V21c0 .3.2.6.7.5A10 10 0 0 0 12 2Z'/%3E%3C/svg%3E") center/20px no-repeat #2b2f36; }
html[data-layout="compact"] .o-contact-10[href*="discord"]::before { content: ""; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M19.3 5.3A16.4 16.4 0 0 0 15.4 4l-.5 1a14.8 14.8 0 0 0-5.8 0L8.6 4a16.4 16.4 0 0 0-3.9 1.3C2.2 9 1.6 12.6 1.9 16.2a16.3 16.3 0 0 0 4.8 2.4l1-1.6a10 10 0 0 1-1.6-.8l.4-.3a11.6 11.6 0 0 0 9.9 0l.4.3a10 10 0 0 1-1.6.8l1 1.6a16.3 16.3 0 0 0 4.8-2.4c.4-4.2-.6-7.8-2.7-10.9ZM8.7 14.3c-.9 0-1.7-.8-1.7-1.9s.7-1.9 1.7-1.9 1.7.9 1.7 1.9-.8 1.9-1.7 1.9Zm6.6 0c-.9 0-1.7-.8-1.7-1.9s.7-1.9 1.7-1.9 1.7.9 1.7 1.9-.7 1.9-1.7 1.9Z'/%3E%3C/svg%3E") center/20px no-repeat #5865f2; }
html[data-layout="compact"] .o-contact-10[href*="linktr"]::before { content: ""; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M11 2h2v5.2l3.7-3.7 1.4 1.4-3.7 3.7H20v2h-5.6l3.7 3.7-1.4 1.4L12 11l-4.7 4.7-1.4-1.4 3.7-3.7H4v-2h5.6L5.9 4.9l1.4-1.4L11 7.2zm0 12h2v8h-2z'/%3E%3C/svg%3E") center/20px no-repeat #2fb35a; }
html[data-layout="compact"] .o-contact-10[href*="mailto"]::before { content: ""; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath fill-rule='evenodd' d='M3 6.5A1.5 1.5 0 0 1 4.5 5h15A1.5 1.5 0 0 1 21 6.5v11a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 3 17.5ZM5 7.6V17h14V7.6l-7 5.2z'/%3E%3C/svg%3E") center/20px no-repeat #ea4335; }
html[data-layout="compact"] .classic-only { display: none; }
html[data-layout="compact"] .o-contact-10[href^="mailto"] .o-contact-12 { font-size: 15px; }
/* project Discord links: just the mark */
.disc-btn { display: inline-grid; place-items: center; padding-left: 14px !important; padding-right: 14px !important; }
.disc-icon { width: 22px; height: 22px; display: block; color: #8b94ff; transition: color .3s; }
.disc-btn:hover .disc-icon { color: #fff; }
.support-tag { margin-left: 4px; font-family: 'Cinzel', serif; font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: #7fd6a0; border: 1px solid #7fd6a066; border-radius: 999px; padding: 3px 9px; }
html[data-layout="compact"] .support-tag { display: inline-block; }

/* product cards: a mark before each name */
.prod-name { display: flex; align-items: center; gap: 10px; }
.prod-icon { width: 30px; height: 30px; flex-shrink: 0; filter: drop-shadow(0 2px 6px #0007); transition: transform .4s cubic-bezier(.2,.8,.2,1); }
.o-work-5:hover .prod-icon { transform: rotate(-8deg) scale(1.12); }
/* contact tiles, tightened: icon, then name over handle as one block, the
   arrow pinned to the right edge */
html[data-layout="compact"] .o-contact-10 {
  position: relative; grid-template-columns: 38px minmax(0, 1fr); grid-template-rows: auto auto;
  align-content: center; column-gap: 14px; row-gap: 2px; min-height: 0; padding: 12px 40px 12px 12px; line-height: 1.2;
}
html[data-layout="compact"] .o-contact-10::before { width: 38px; height: 38px; border-radius: 10px; align-self: center; }
html[data-layout="compact"] .o-contact-10 > span:first-child { grid-column: 2; align-self: end; font-size: 17px; line-height: 1.2; }
html[data-layout="compact"] .o-contact-11 { grid-column: 2; align-self: start; font-size: 14px; line-height: 1.25; color: var(--inka6a0b8, #a6a0b8); }
html[data-layout="compact"] .o-contact-12 {
  position: absolute; right: 16px; top: 50%; transform: translateY(-50%); font-size: 14px; opacity: .7; transition: opacity .25s, transform .3s;
}
html[data-layout="compact"] .o-contact-10:hover .o-contact-12 { opacity: 1; transform: translate(3px, -50%); }
html[data-layout="compact"] .o-contact-10:hover { background: var(--lineffffff08); }
/* the opened RPS cards sat tight under the button; give them room */
html[data-layout="compact"] #rps.is-open .o-rps-32 { margin-top: clamp(24px, 3vw, 40px); }
html[data-layout="compact"] #rps .more-toggle { margin-top: 18px; }

/* phone fixes: the Ko-fi tag ran under the "Most helpful" badge, the goal
   row broke its label in two, and the motto stranded its last word */
html[data-layout="compact"] .o-support-4 .o-support-7 { flex-wrap: wrap; row-gap: 8px; padding-right: 118px; }
.goal-label { white-space: nowrap; }
@media (max-width: 720px) {
  .goal-row { flex-direction: column; align-items: flex-start; gap: 4px; }
  html[data-layout="compact"] .o-support-4 .o-support-7 { padding-right: 0; margin-top: 26px; }
}
.o-heroinner-1 { text-wrap: balance; }
