/* ==========================================================================
   controls.css - shared rules for interactive controls: minimum target
   size, and what a disabled control looks like. One file for every page.

   Apple's HIG puts the minimum control at 44x44pt on touch; on a pointer
   device the equivalent guideline is 28x28. The site already met 44 in two
   places - the hamburger is exactly 44x44 and the drawer links carry a 48px
   min-height - so every miss was an oversight rather than a decision.

   WHY A SHARED FILE. Every page has its own inline <style>, so these rules
   would otherwise be pasted eight times. This repo already has a ticket open
   about two copies of one string drifting apart (RDDW-26); eight copies of a
   rule would be the same mistake on purpose. One file, linked last in <head>
   so it wins on source order over the page's own <style>.

   WHY TWO BREAKPOINTS RATHER THAN 44 EVERYWHERE. Forcing 44 on desktop grew
   the fixed header from 73px to 85px, because the CONTACT button and language
   toggle are 26 and 31px there. That matters beyond looks: anchor scrolling is
   tuned against the bar height (scroll-padding-top: 90px, RDDW-17), so a
   taller bar silently retunes every anchor on the site. 28 on desktop meets
   the desktop guideline and fits inside the bar as it already is.

   WHAT IS DELIBERATELY NOT HERE: links inside a sentence. WCAG 2.5.8 exempts
   a target "in a sentence or [whose] size is otherwise constrained by the
   line-height of non-target text", and it is the right exemption - a word in
   a paragraph cannot be 44px tall without wrecking the paragraph. So the
   privacy link in the consent copy, the unity.com link inside a tech
   description, and the addresses inside body text stay as they are. The
   measuring script encodes the same exemption, so it is a documented decision
   rather than a gap.
   ========================================================================== */

/* ==========================================================================
   Colour scheme (RDDW-25).

   The site is a committed dark design that never told the browser so. With
   color-scheme unset the computed value is `normal`, and everything the
   browser draws ITSELF falls back to its light defaults: autofill styling on
   the email fields, native form-control chrome, date and select popups, and
   the default scrollbar wherever the custom one does not reach.

   `dark`, not `light dark`: there is no light theme to switch to, so claiming
   both would be a promise the stylesheet cannot keep -- and it would let a
   browser in light mode paint these controls pale against a near-black page.

   HERE rather than in each page's <style>, because this file already loads on
   all eight pages and every symptom is control chrome, which is what this file
   is for. It also loads last, so it wins without !important.

   Separate from the theme-color meta tag the pages already set: that colours
   the mobile browser's chrome AROUND the page. Which is why the most visible
   symptom was already covered, and this one was easy to miss.
   ========================================================================== */
:root {
  color-scheme: dark;
}

/* ==========================================================================
   Skip link and main landmark (RDDW-45).

   On every page the first tab stop used to be the logo, so a keyboard or
   screen-reader user walked the whole navigation before reaching content,
   on every page, every time -- WCAG 2.0 SC 2.4.1, Level A. The link is the
   first element in <body> on all eight pages and lands on
   <main id="main-content" tabindex="-1">.

   Hidden by moving it above the viewport rather than with display:none, so
   it stays in the tab order; it drops into view on focus. Positioned with
   inset-inline-start, not left: a physical offset would put it off-screen
   in the wrong direction under dir="rtl".

   z-index above the fixed/sticky nav (100) and the modal overlay.
   ========================================================================== */
.skip-link {
  position: fixed;
  top: -200px;
  inset-inline-start: 16px;
  z-index: 10000;
  padding: 12px 18px;
  background: var(--accent-red, #E8534A);
  color: #fff;
  font-family: var(--font-body, 'DM Sans', sans-serif);
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  border-radius: 8px;
  text-decoration: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  transition: top 0.15s;
}
.skip-link:focus,
.skip-link:focus-visible {
  top: 16px;
  outline: 3px solid #fff;
  outline-offset: 2px;
}
/* The landmark takes programmatic focus only; no ring on the whole page. */
#main-content:focus { outline: none; }

/* ==========================================================================
   A Latin name inside Hebrew prose (RDDW-52).

   "© 2026 RDD-Labs. Color Drain וכל הנכסים... רכוש RDD-Labs." arrived on both
   handsets with the trailing brand broken into "-RDD" and "Labs." across the
   line end. <bdi> is what keeps the name a single run inside the RTL
   paragraph; this rule adds the other half, because a hyphen is a line-break
   opportunity and the bidi algorithm cannot help with where a line ends.

   Only for names short enough that refusing to break them cannot overflow a
   375px phone. A long Latin phrase in Hebrew prose gets <bdi> alone.
   ========================================================================== */
.ltr-name { white-space: nowrap; }

/* ==========================================================================
   A table wider than the phone (RDDW-53).

   /cookies has five columns whose min-content width is about 490px. No phone
   is that wide, and the browser's answer was to widen the LAYOUT VIEWPORT
   rather than the table -- 510px on a 392px screen -- so the whole policy
   rendered at roughly 0.77x, smaller type than every other page, with the
   duration and category columns off to the right. The page the consent banner
   links to was the one page on the site that looked broken. /privacy has the
   same defect 22px deep: its four-column table measures 377px in a 335px
   column, and the retention column is the one that goes.

   So the table pans and the page does not. tabindex makes the scroller
   reachable by keyboard, because a region a mouse can pan and a keyboard
   cannot is a new accessibility problem in place of the old one, and the
   role+label give it a name when a screen reader lands on it.

   .table-hint appears only on the narrow screens where the overflow happens:
   a table that scrolls is invisible until you try, and the column that leaves
   the viewport is the one telling you how long the data is kept.

   main takes an explicit width so the next wide element cannot do it again.
   ========================================================================== */
main { width: 100%; }
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-bottom: 14px; }
.table-scroll > table { margin-bottom: 0; }
.table-scroll:focus-visible { outline: 2px solid var(--accent-red, #E8534A); outline-offset: 3px; }
.table-hint { display: none; font-size: 12px; color: var(--text-muted, #4A4860); margin: -6px 0 14px; }
@media (max-width: 600px) { .table-hint.can-pan { display: block; } }

/* ==========================================================================
   Hebrew typography (RDDW-43).

   Under dir="rtl" the page is set in Rubik (display) and Heebo (body), the
   two faces declared in fonts/fonts.css that actually contain Hebrew. The
   override is on the variables every page already reads, under both naming
   schemes (--font-display/--font-body on the studio and legal pages,
   --fd/--fb on the game page), so no per-page rule needs touching. Latin
   runs inside Hebrew text pick up the same face, which is what removes the
   two-typeface seam on mixed lines.

   The wordmarks are the exception: "RDD Labs", "COLOR DRAIN" and the footer
   brand are logos, not prose, and a logo does not change typeface with the
   page language. They stay in Syne in both directions.

   TRACKING. The letter-spacing values across the site were chosen for Syne
   and DM Sans setting English. Hebrew letterforms do not have the optical
   relationships that make negative tracking work on Latin display type --
   -1px on the hero h1 was closing counters on the largest Hebrew text on
   the site -- and positive tracking is not a Hebrew convention either. So
   under RTL every element returns to `normal` (the correct Hebrew default,
   not `0`, which some faces treat differently). !important because a
   dozen of the values live in inline style attributes. The Latin-only
   wordmarks keep their designed tracking through the same exception list.
   ========================================================================== */
html[dir="rtl"] {
  --font-display: 'Rubik', 'Heebo', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  --font-body: 'Heebo', 'Rubik', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  --fd: 'Rubik', 'Heebo', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  --fb: 'Heebo', 'Rubik', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
}
html[dir="rtl"] .nav-logo-text,
html[dir="rtl"] .top-logo,
html[dir="rtl"] .hero-title,
html[dir="rtl"] .ht-c,
html[dir="rtl"] .ht-d,
html[dir="rtl"] .footer-brand-name,
html[dir="rtl"] .brand,
html[dir="rtl"] .phone-title-word {
  font-family: 'Syne', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
}
html[dir="rtl"] *:not(.nav-logo-text):not(.top-logo):not(.hero-title):not(.ht-c):not(.ht-d):not(.footer-brand-name):not(.brand):not(.phone-title-word):not(.top-beta) {
  letter-spacing: normal !important;
}

/* The legal-page template (privacy, terms, cookies, accessibility) uses
   physical margins and left-aligned tables; these mirror it under RTL
   (RDDW-34). Scoped to .page-wrap so the two big pages, which carry their
   own [dir="rtl"] rules, are untouched. */
html[dir="rtl"] .page-wrap ul, html[dir="rtl"] .page-wrap ol { padding-left: 0; padding-right: 20px; }
html[dir="rtl"] .page-wrap .section-title span { margin-right: 0; margin-left: 10px; }
html[dir="rtl"] .page-wrap th, html[dir="rtl"] .page-wrap td { text-align: right; }
/* Identifiers such as _ga or __cf_bm start with punctuation, which the bidi
   algorithm otherwise hangs on the wrong side of the surrounding Hebrew. */
html[dir="rtl"] .page-wrap code { direction: ltr; unicode-bidi: isolate; }

/* The arrow on every "back" link is decoration, so it is generated content
   with empty alt text and a screen reader does not announce it (RDDW-9).
   The plain declaration is the fallback for browsers that do not parse the
   alt-text form; they keep the previous behaviour. The same glyph serves
   both languages, as the strings did before. */
.nav-back::before, .back-link::before { content: "← "; }
@supports (content: "x" / "y") {
  .nav-back::before, .back-link::before { content: "← " / ""; }
}

/* Controls that live inside the fixed bars. Their height feeds the header
   height, so they are sized per breakpoint. */
nav > a.nav-logo,
nav > a.nav-back,
header.top-bar > a.top-logo,
header.top-bar > a.top-by,
body > a.brand,
.lang-toggle,
nav > button.nav-cta {
  display: inline-flex;
  align-items: center;
}

/* Everything else: not in a fixed bar, so growing it costs nothing but the
   spacing it was missing. */
.faq-question,
.faq-q,
.footer-col a,
.footer-top .fc a,
footer .footer-links > a,
footer .footer-inner > a.footer-link,
body > div.links > a,
.browser-card > a,
table.facts td > a,
.featured-info > a,
.page-wrap .section > ul > li > a,
.contact-box p > a,
a.contact-email {
  display: inline-flex;
  align-items: center;
}

/* Footer columns stack, so they want the full width to stay tappable. */
.footer-col a,
.footer-top .fc a,
footer .footer-inner > a.footer-link {
  display: flex;
  margin-bottom: 0;
}

/* ---------------------------------------------------------------- TOUCH -- */
@media (max-width: 900px) {
  nav > a.nav-logo,
  nav > a.nav-back,
  header.top-bar > a.top-logo,
  header.top-bar > a.top-by,
  body > a.brand,
  .lang-toggle,
  nav > button.nav-cta,
  .faq-question,
  .faq-q,
  .footer-col a,
  .footer-top .fc a,
  footer .footer-links > a,
  footer .footer-inner > a.footer-link,
  body > div.links > a,
  .browser-card > a,
  table.facts td > a,
  .featured-info > a,
  .page-wrap .section > ul > li > a,
  .contact-box p > a,
  a.contact-email {
    min-height: 44px;
  }

  /* Width counts as much as height: these were 33px and 42px across. */
  footer .footer-links > a,
  table.facts td > a,
  body > div.links > a {
    min-width: 44px;
    justify-content: center;
    padding-left: 10px;
    padding-right: 10px;
  }

  /* Square icon buttons, sized rather than min-sized because the page sets
     an explicit width and height on them. */
  .footer-socials a {
    width: 44px;
    height: 44px;
  }

  /* RDDW-55: the display above is an ASSIGNMENT, not a floor, and this file
     loads last -- so `header.top-bar > a.top-by { display: inline-flex }` was
     quietly overriding the game page's own `@media (max-width:600px)
     { .top-by { display:none } }` and putting "by RDD-Labs" back on every
     phone. Nothing looked wrong: the line simply sat there taking 63px out of
     a 360px header, which squeezed the only call to action next to it down to
     55px and broke its label across two lines.

     So the tap-target rule stops resurrecting an element the page has
     deliberately hidden. Same shape as the .lang-toggle warning below: adding
     a selector to the blocks above means checking what the pages already set
     for it, in both directions. */
  @media (max-width: 600px) {
    header.top-bar > a.top-by { display: none; }
  }

  /* Was 28x30 in the corner: the hardest control on the page to hit. The
     offsets keep the glyph exactly where it was while the target grows around
     it - the old centre sat 34px from the right and 31px from the top, and
     12 + 22 and 9 + 22 put it back in the same place. */
  .modal-close {
    min-width: 44px;
    min-height: 44px;
    top: 9px;
    right: 12px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

/* -------------------------------------------------------------- POINTER --
   CAREFUL: this file loads last, so a min-height here BEATS a larger one set
   by a page. That is not a floor, it is an assignment. .lang-toggle is
   deliberately absent below for exactly that reason -- 404.html sets its own
   44px, and listing it here silently cut that to 28. It is 31px on the other
   pages, which already clears 28, so it needs nothing from this block.
   Anything added here must be checked against what the pages already set. */
@media (min-width: 901px) {
  nav > a.nav-logo,
  nav > a.nav-back,
  header.top-bar > a.top-logo,
  header.top-bar > a.top-by,
  body > a.brand,
  nav > button.nav-cta,
  nav .nav-links a,
  .faq-question,
  .faq-q,
  .footer-col a,
  .footer-top .fc a,
  footer .footer-links > a,
  footer .footer-inner > a.footer-link,
  body > div.links > a,
  .browser-card > a,
  table.facts td > a,
  .featured-info > a,
  .page-wrap .section > ul > li > a,
  .contact-box p > a,
  a.contact-email {
    min-height: 28px;
    min-width: 28px;
  }
  nav .nav-links a {
    display: inline-flex;
    align-items: center;
  }
}

/* The hero PLAY control is an anchor now (RDDW-21), so it needs to lay out
   like the button it looks like, at every size. */
.phone-play-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  text-decoration: none;
}

/* ==========================================================================
   Disabled controls look disabled, in one place.

   RDDW-22: the launch-updates button used to imitate the disabled state with
   style.opacity while staying clickable for the whole request, so a
   double-click sent two signups. The button is genuinely disabled now, and the
   dimming belongs to the state rather than to the handler -- otherwise the two
   can disagree again, which is exactly how that bug read as fixed.
   ========================================================================== */
button:disabled,
.btn-primary:disabled,
.beta-btn:disabled,
.modal-submit:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

/* ==========================================================================
   Motion off (RDDW-24).

   WCAG 2.2.2: content that moves automatically, runs longer than five
   seconds and sits beside other content needs a way to pause, stop or hide
   it. The site already honours prefers-reduced-motion and has a lite mode
   for weak devices, so the person left out is the one who has not set the
   system preference, or cannot, and just wants this page to hold still.

   NOT html.lite. That class also strips glows, backdrop filters and the
   noise film -- it is a performance mode, and someone asking for stillness
   did not ask for a different design. This block touches animation only.

   TRANSITIONS ARE DELIBERATELY LEFT ALONE. WCAG 2.2.2 is about content that
   moves BY ITSELF; a hover state or a banner sliding in answers something
   the visitor just did. Killing those would make the page feel broken
   without making it any calmer.

   Ends animations rather than freezing them mid-frame: iteration-count 1
   with a ~0 duration lands every loop on its final keyframe. Freezing with
   animation-play-state would have been the smaller change, but applying it
   before first paint would strand the entry animations at frame 0, with the
   content invisible -- which is why .anim/.anim-target are forced to their
   end state here, exactly as lite mode already does.
   ========================================================================== */
html.motion-off *,
html.motion-off *::before,
html.motion-off *::after {
  animation-duration: 0.01ms !important;
  animation-delay: 0s !important;
  animation-iteration-count: 1 !important;
}
html.motion-off .anim-target,
html.motion-off .anim {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* ==========================================================================
   Frozen brand gradients (RDDW-32).

   The wordmarks, the gradient buttons and the phone screen are gradients
   sized 200-400% that rely on gradientFlow to sweep every colour past the
   element. Stop the animation and the element shows only the slice under
   it at that instant -- the dark red corner, on a near-black page.

   Three things stop the animation, and until this rule existed only one of
   them was corrected. Lite mode had the background-size override inline in
   the two big pages; prefers-reduced-motion and the site's own motion-off
   toggle had nothing, so the visitor who asked for less motion was handed a
   broken brand for it. The lite block's comment even claimed reduced motion
   got the same treatment. It did not.

   ONE RULE, HERE, for all three states, so the next state cannot be fixed
   on one path and missed on the other two. This file loads last on all
   eight pages, which also reaches the six secondary pages that never set
   html.lite at all and yet carry the same 300%-sized logo subtitle.

   The selector list is the union of every gradient element on every page;
   a selector that does not exist on a page costs nothing. !important is
   needed on purpose: the base rules and one inline style set the 300%
   size, and this override has to beat the inline one.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .nav-logo-sub, .hero-h1 .gradient-text, .btn-primary, .btn-beta,
  .phone-screen, .line-divider, .stat-block-value, span[style*="gradientFlow"],
  .top-logo, .top-join, .ht-d, .beta-btn, .beta2-box::before, .footer-brand-name,
  .code {
    background-size: 100% 100% !important;
  }
}
html.motion-off .nav-logo-sub, html.motion-off .hero-h1 .gradient-text,
html.motion-off .btn-primary, html.motion-off .btn-beta, html.motion-off .phone-screen,
html.motion-off .line-divider, html.motion-off .stat-block-value,
html.motion-off span[style*="gradientFlow"],
html.motion-off .top-logo, html.motion-off .top-join, html.motion-off .ht-d,
html.motion-off .beta-btn, html.motion-off .beta2-box::before, html.motion-off .footer-brand-name,
html.motion-off .code,
html.lite .nav-logo-sub, html.lite .hero-h1 .gradient-text,
html.lite .btn-primary, html.lite .btn-beta, html.lite .phone-screen,
html.lite .line-divider, html.lite .stat-block-value,
html.lite span[style*="gradientFlow"],
html.lite .top-logo, html.lite .top-join, html.lite .ht-d,
html.lite .beta-btn, html.lite .beta2-box::before, html.lite .footer-brand-name,
html.lite .code {
  background-size: 100% 100% !important;
}

/* ==========================================================================
   Load-bearing wordmarks on Samsung Internet (RDDW-31).

   Measured on a Galaxy A04 running Samsung Internet 30 with dark mode on:
   the browser rewrites every BACKGROUND paint darker (#FFFFFF painted as
   #1f1f1f) while text colour is preserved or brightened. background-clip:
   text glyphs are painted as a background, so "DRAIN", the COLOR DRAIN
   logo, "mobile games" and the logo subtitle came out at 1.5:1 contrast --
   half the product name illegible -- while the plain white words beside
   them were crisp. Chrome on the same page paints exactly what the CSS
   declares. color-scheme: dark is already declared and does not stop it.

   So on that browser the words that carry meaning are painted as TEXT,
   in a solid brand colour, and the gradient is dropped for them. The
   class is set from the user agent before first paint (see each page's
   head script); every other browser keeps the animated gradient, which
   is the ticket's own acceptance test for the Mi 9T Pro.

   Gradient BUTTONS are left alone on purpose: their label is already real
   white text and stays legible on the darkened gradient.

   Colours are the brand accents, hard-coded because the two big pages
   name their variables differently (--accent-red vs --red). Contrast on
   the #08080C ground: coral 5.5:1, yellow 12.5:1 (the subtitle is 10px,
   so it takes the brighter one). Both clear WCAG AA before force-dark,
   and force-dark only ever brightens text.
   ========================================================================== */
html.force-dark .hero-h1 .gradient-text,
html.force-dark .stat-block-value,
html.force-dark .featured-title .drain-text,
html.force-dark .ht-d,
html.force-dark .top-logo,
html.force-dark .footer-brand-name {
  background: none !important;
  animation: none !important;
  color: #E8534A !important;
  -webkit-text-fill-color: #E8534A !important;
}
html.force-dark .nav-logo-sub {
  background: none !important;
  animation: none !important;
  color: #F5C842 !important;
  -webkit-text-fill-color: #F5C842 !important;
}

/* ==========================================================================
   The rest of Samsung Internet dark mode (RDDW-50).

   RDDW-31 fixed the wordmarks it listed. The QA night of 13 Sep 2026, same
   Galaxy A04, found everything it had not touched: the hero mockup's
   "DRAIN", the footer brand subtitle, the cream mockup screen and the
   diorama both inverted to near-black, every gradient CTA painted
   maroon -> navy, and the 404 numeral. Chrome on the Mi 9T Pro renders all
   of it as designed, which is why none of this is visible in development.

   The first fix tried `color-scheme: only light`, the per-element opt-out
   Chromium documents. Samsung Internet 30 ignores it: measured on the A04
   with the rule applied and computed, a `rgb(0,255,0)` background rendered
   as rgb(0,124,0), a solid coral as rgb(121,0,0), the cream screen at
   rgb(32,20,16). What the same measurement showed it leaves alone: text
   colour, borders, and <canvas> pixels. So there are three treatments now,
   and none of them is a background.

   1. A solid text colour -- the RDDW-31 recipe -- for words that must stay
      legible: the mockup "DRAIN", the footer subtitle, and the 404 numeral
      as its fallback (#D4403A measures 4.0:1 on cream, 3.6:1 on the darkened
      screen; the 10px subtitle takes the brighter yellow at 12.5:1).

   2. A coral OUTLINE for the gradient buttons: 2px border and label in the
      brand colour on a transparent ground. A border survives force-dark
      exactly; a solid coral background would not (see above). box-sizing is
      border-box on every page, so the 44px targets keep their height.

   3. A <canvas>, painted by js/force-dark-paint.js, for the three things
      whose colours are the whole point: the cream phone screen with its
      words, cube and PLAY pill, the diorama cube, and the four-colour 404
      numeral. The script adds `.fd-painted` once the canvas is in place and
      the rules below make the CSS-painted original transparent underneath --
      still in the DOM, still read out, the PLAY link still focusable (its
      focus ring is an outline, which force-dark keeps). No script, no
      canvas: treatment 1 stays in charge and the page is legible.

   scripts/check-force-dark.mjs keeps the inventory honest: it fails if a
   background-clip: text element ships without a solid-colour rule, and it
   no longer accepts the opt-out as a treatment, because it is not one.
   ========================================================================== */
html.force-dark .btn-primary,
html.force-dark .btn-beta,
html.force-dark .top-join,
html.force-dark .beta-btn,
html.force-dark a.btn:not(.btn-ghost) {
  background: none !important;
  animation: none !important;
  box-shadow: none !important;
  border: 2px solid #E8534A !important;
  color: #E8534A !important;
  -webkit-text-fill-color: #E8534A !important;
}
/* The shimmer sweeps are a lighter gradient, i.e. another background. */
html.force-dark .btn-primary::after,
html.force-dark .btn-beta::after,
html.force-dark .top-join::after,
html.force-dark .beta-btn::before,
html.force-dark .phone-play-btn::after {
  display: none !important;
}
html.force-dark .phone-title-drain {
  background: none !important;
  animation: none !important;
  color: #D4403A !important;
  -webkit-text-fill-color: #D4403A !important;
}
html.force-dark .footer-brand-sub {
  background: none !important;
  animation: none !important;
  color: #F5C842 !important;
  -webkit-text-fill-color: #F5C842 !important;
}
html.force-dark .code {
  background: none !important;
  animation: none !important;
  color: #E8534A !important;
  -webkit-text-fill-color: #E8534A !important;
}

/* Once the canvas is in place (treatment 3), the original goes transparent.
   The mockup's children are lifted above the canvas so the PLAY link stays
   on top and clickable; only its paint is removed, not the element. */
html.force-dark .phone-screen.fd-painted > * { position: relative; z-index: 1; }
html.force-dark .phone-screen.fd-painted > canvas { position: absolute; z-index: 0; }
html.force-dark .phone-screen.fd-painted .phone-title-word {
  color: transparent !important;
  -webkit-text-fill-color: transparent !important;
  background: none !important;
}
html.force-dark .phone-screen.fd-painted svg { visibility: hidden; }
html.force-dark .phone-screen.fd-painted .phone-play-btn {
  background: none !important;
  box-shadow: none !important;
  color: transparent !important;
  -webkit-text-fill-color: transparent !important;
}
html.force-dark .featured-visual.fd-painted svg { visibility: hidden; }
html.force-dark .code.fd-painted {
  color: transparent !important;
  -webkit-text-fill-color: transparent !important;
}

.motion-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 0 14px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-muted, #8A8A94);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.motion-toggle:hover {
  color: var(--text-primary, #fff);
  border-color: var(--text-secondary, #B5B5BD);
  background: rgba(255, 255, 255, 0.08);
}
.motion-toggle-icon { font-size: 11px; line-height: 1; }

/* The home page control sits above the marquee band it governs, right-aligned
   so it reads as a control on that band rather than as content in it. */
.marquee-control {
  max-width: 1240px;
  margin: 0 auto 10px;
  padding: 0 40px;
  display: flex;
  justify-content: flex-end;
}
@media (max-width: 900px) {
  .marquee-control { padding: 0 16px; }
}
