/* Qwipy — legal pages (Privacy Policy, Terms of Service).
   Additive only: does not modify any Framer-generated rule.
   Reuses the site's existing framer-text / framer-styles-preset-* classes
   for all typography; adds layout spacing plus a soft blurred-blob hero
   background (colors are the site's own existing pastel tokens — same
   technique as a reference design the user liked, no new palette). */

/* The site's copied <head> CSS declares `color-scheme: light dark` (a
   Framer UA-reset rule), but body/html have no background color of their
   own — the homepage never notices because its sections tile edge to
   edge. These hand-authored pages don't, so on a browser in dark mode
   the transparent gaps would otherwise reveal a black default canvas.
   Force the site's actual (light-only) background explicitly. */
body.qwipy-legal-page {
  background-color: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
}

.qwipy-legal-hero {
  position: relative;
  width: 100%;
  padding: 170px 30px 90px;
  display: flex;
  justify-content: center;
}

/* Page-level background layer — a sibling placed BEFORE <header> in the
   DOM (see the page markup), not nested inside .qwipy-legal-hero. That
   matters: the header sits above this in normal flow, so if the blobs
   lived inside the hero (which only starts after the header), the area
   behind the header/navbar stayed plain white. This starts at the very
   top of the page instead, with negative z-index so header and content
   still paint above it, and its own fade mask (isolated from
   .qwipy-legal-hero-content, so text opacity is never affected by it).
   Height is set by the inline script at the end of the page (measures
   header + hero at runtime) — content-driven height, not a guess. */
.qwipy-legal-page-bg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: -1;
  overflow: hidden;
  height: 650px;
  -webkit-mask-image: linear-gradient(to bottom, black 0%, black 42%, transparent 97%);
  mask-image: linear-gradient(to bottom, black 0%, black 42%, transparent 97%);
}

.qwipy-legal-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(100px);
  pointer-events: none;
  /* JS (see the inline script at the end of the page) nudges each blob's
     transform a few px toward the cursor for a slow, ambient parallax —
     this transition is what makes that feel like a drift rather than a
     jump when the target position updates. Opacity/filter share this
     same timing family (see the :hover rule below) rather than a second
     curve, so the "wake up" reads as part of the same drift, not a
     separate effect layered on top. */
  transition: transform 1.1s cubic-bezier(0.16, 0.8, 0.3, 1), opacity 0.6s ease, filter 0.6s ease;
  will-change: transform;
}

/* Subtle "wake up" while the visitor's cursor is actually in the hero —
   pairs with the mousemove-driven drift in qwipy-legal-parallax.js so the
   background feels responsive, not just decorative. Pure CSS, so it's
   automatically inert under prefers-reduced-motion (the media query
   below already sets transition:none on these elements). */
.qwipy-legal-hero:hover .qwipy-legal-blob {
  opacity: 0.75;
  filter: blur(100px) brightness(1.05);
}

@media (prefers-reduced-motion: reduce) {
  .qwipy-legal-blob {
    transition: none;
  }
}

/* Green-led palette — the brand's actual primary color is the bright
   lime green used everywhere on the homepage (hero, badges), so that
   leads here too, with the mint and soft-yellow accents already used by
   the Process cards for support. No pink/red — those never appear
   anywhere else on the site. */
.qwipy-legal-blob-a {
  width: 620px;
  height: 620px;
  top: -124px;
  left: -120px;
  background: var(--token-fcbb46ec-ce7b-4477-a350-ed69a949fbcc, #dbf2a5);
  opacity: 0.6;
}

.qwipy-legal-blob-b {
  width: 560px;
  height: 560px;
  top: -64px;
  right: -160px;
  background: var(--token-6bd109d2-1e50-4eef-8647-ad9177b426de, #dbf5f0);
  opacity: 0.6;
}

/* This one's job is to cover the top-center gap between blob-a (hugs
   left) and blob-b (hugs right) — at wide viewports (1800px+) those two
   fixed-size blobs don't reach far enough toward the middle, leaving a
   pale/white patch right behind the heading. Centered with `left: 50%` +
   `margin-left` (not `transform`, which the parallax script below owns
   exclusively — a transform set here would just get overwritten). */
.qwipy-legal-blob-c {
  width: 900px;
  height: 900px;
  top: -224px;
  left: 50%;
  margin-left: -450px;
  background: var(--token-cff1c173-a71c-4968-b687-34c315e13ef5, #ffe7a9);
  opacity: 0.4;
}

.qwipy-legal-hero-content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1100px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.qwipy-legal-content h1 {
  margin-bottom: 6px;
}

.qwipy-legal-updated {
  opacity: 0.6;
}

/* Quick-facts strip under the intro — a scannable, colorful summary
   using the site's existing pill/badge language (same border + radius
   as the "Add to Chrome" button), standing in for the personality a
   wall of boxed cards below would otherwise have to carry alone. */
.qwipy-legal-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 6px;
}

.qwipy-legal-chip {
  display: inline-flex;
  align-items: center;
  padding: 9px 16px;
  border-radius: 100px;
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  background: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  transition: transform 0.2s cubic-bezier(0.16, 0.8, 0.3, 1), box-shadow 0.2s ease;
}

.qwipy-legal-chip:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 16px rgba(29, 29, 29, 0.12);
}

.qwipy-legal-chip:active {
  transform: translateY(0) scale(0.97);
}

/* Contact-page chips only (.qwipy-legal-chip is shared with plain
   informational <span> badges on /privacy/ and /terms/, e.g. "No data
   selling" — those stay inert). These three are real <button>s: clicking
   one drops a starter template into the message field below and tags the
   category onto the email subject (see the inline script at the bottom
   of contact/index.html — this page's form logic is inlined there, not
   loaded from an external file). The base
   class already gives them the hover lift/shadow, so this only adds what
   a plain <span> never needed — cursor, a focus ring for keyboard users,
   and a filled "selected" state so it's obvious which topic is active. */
.qwipy-contact-chip {
  cursor: pointer;
}

.qwipy-contact-chip:focus-visible {
  outline: 2px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  outline-offset: 2px;
}

.qwipy-contact-chip[aria-pressed="true"] {
  background: var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  color: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
}

.qwipy-legal-main {
  width: 100%;
  padding: 0 30px 140px;
  display: flex;
  justify-content: center;
}

/* Sidebar TOC + editorial content column, instead of stacking every
   section in its own bordered box (which read as repeated template
   cards rather than a designed document). This is the same pattern
   serious product docs/legal pages use — a sticky "on this page" nav
   next to clean typographic sections separated by hairline dividers. */
.qwipy-legal-layout {
  width: 100%;
  max-width: 1100px;
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 64px;
  align-items: start;
}

.qwipy-legal-toc {
  position: sticky;
  top: 130px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.qwipy-legal-toc-label {
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.45;
  margin-bottom: 4px;
}

.qwipy-legal-toc-link {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 14px;
  line-height: 1.3em;
  opacity: 0.7;
  transition: opacity 0.15s ease, transform 0.15s cubic-bezier(0.16, 0.8, 0.3, 1);
}

.qwipy-legal-toc-link:hover {
  opacity: 1;
  transform: translateX(3px);
}

.qwipy-legal-toc-num {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 500;
  transition: transform 0.15s cubic-bezier(0.16, 0.8, 0.3, 1);
}

.qwipy-legal-toc-link:hover .qwipy-legal-toc-num {
  transform: scale(1.15);
}

.qwipy-legal-content {
  width: 100%;
  max-width: 720px;
  display: flex;
  flex-direction: column;
}

.qwipy-legal-content a {
  color: var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.qwipy-legal-section {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 40px 0;
  border-bottom: 1px solid rgba(29, 29, 29, 0.12);
  scroll-margin-top: 130px;
}

.qwipy-legal-section:first-child {
  padding-top: 0;
}

.qwipy-legal-section:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.qwipy-legal-section-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
}

.qwipy-legal-section h2 {
  --framer-font-size: 26px !important;
  --framer-line-height: 1.2em !important;
}

.qwipy-legal-section ul {
  margin: 0;
  padding-left: 22px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

@media (max-width: 1299px) {
  .qwipy-legal-hero {
    padding: 160px 30px 50px;
  }

  .qwipy-legal-layout {
    grid-template-columns: 170px 1fr;
    gap: 40px;
  }
}

@media (max-width: 900px) {
  .qwipy-legal-layout {
    grid-template-columns: 1fr;
  }

  .qwipy-legal-toc {
    display: none;
  }
}

@media (max-width: 809px) {
  .qwipy-legal-hero {
    padding: 140px 20px 40px;
  }

  .qwipy-legal-blob-a,
  .qwipy-legal-blob-b,
  .qwipy-legal-blob-c {
    width: 320px;
    height: 320px;
  }

  .qwipy-legal-blob-c {
    margin-left: -160px;
    top: -10px;
  }

  .qwipy-legal-section {
    padding: 30px 0;
  }
}

/* Compact footer for legal pages — copyright + nav links only, no CTA
   block or badge. The homepage's own footer (full marketing CTA) is
   untouched; this is a lighter-weight alternative just for these pages,
   since reusing the full footer verbatim made them enormous on mobile. */
.qwipy-legal-footer {
  width: 100%;
  padding: 36px 30px;
  display: flex;
  justify-content: center;
}

.qwipy-legal-footer .framer-text {
  color: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff) !important;
}

.qwipy-legal-footer-inner {
  width: 100%;
  max-width: 1200px;
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}

.qwipy-legal-footer-nav {
  display: flex;
  align-items: center;
  gap: 30px;
}

@media (max-width: 809px) {
  .qwipy-legal-footer {
    padding: 30px 20px;
  }

  .qwipy-legal-footer-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .qwipy-legal-footer-nav {
    gap: 20px;
  }
}

/* Contact page form — genuinely new UI (the codebase had zero existing
   <form>/<input> patterns anywhere to extend), so this borrows the site's
   established visual language instead of inventing a new one: the chip's
   border/radius/font for the inputs, and the homepage "Add to Chrome"
   CTA's own inset box-shadow recipe for the submit button. Reuses
   .qwipy-legal-main/.qwipy-legal-hero/.qwipy-legal-page-bg wholesale —
   this file only adds the form-specific pieces. */
.qwipy-contact-layout {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

.qwipy-contact-form {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.qwipy-contact-field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qwipy-contact-label {
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  opacity: 0.6;
}

.qwipy-contact-input {
  width: 100%;
  padding: 14px 18px;
  border-radius: 14px;
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  background: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 15px;
  color: var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  transition: box-shadow 0.2s ease;
}

.qwipy-contact-textarea {
  resize: vertical;
  min-height: 140px;
  font-family: inherit;
}

.qwipy-contact-input:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(29, 29, 29, 0.08);
}

.qwipy-contact-submit {
  align-self: flex-start;
  padding: 14px 26px;
  border-radius: 100px;
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  background: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
  box-shadow: rgba(29, 29, 29, 0.15) 0px -5px 0px 0px inset;
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 15px;
  font-weight: 500;
  color: var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  cursor: pointer;
  transition: transform 0.2s cubic-bezier(0.16, 0.8, 0.3, 1), box-shadow 0.2s ease;
}

.qwipy-contact-submit:hover {
  transform: translateY(-2px);
}

.qwipy-contact-submit:active {
  transform: translateY(0) scale(0.97);
}

.qwipy-contact-hint {
  opacity: 0.55;
  font-size: 13px;
}

.qwipy-contact-email-link {
  color: inherit;
  text-decoration: underline;
}

/* How It Works — step cards. The homepage's own Process section and
   "What Qwipy does?" cards already use this exact hover recipe (baked
   into every page's shared <head> as #qwipy-card-hover, scoped to
   Framer's own auto-generated hash classes) — reimplemented here under
   a plain semantic class since those hash classes don't exist on this
   hand-authored page. Scoped to /how-it-works/ only: .qwipy-legal-section
   stays a plain hairline-divided block everywhere else (privacy/terms),
   which is intentional there (see that rule's own comment) — a step-by-
   step product walkthrough is a much better fit for the card treatment
   than dense legal text is. */
.qwipy-howitworks-card {
  transition: transform 380ms cubic-bezier(.22, .68, 0, 1),
              box-shadow 380ms cubic-bezier(.22, .68, 0, 1);
  transform-origin: center center;
  will-change: transform;
}

.qwipy-howitworks-card:hover {
  transform: scale(1.035);
  box-shadow: 0 30px 60px -24px rgba(13, 13, 13, .4);
  z-index: 5;
  position: relative;
}

@media (prefers-reduced-motion: reduce) {
  .qwipy-howitworks-card {
    transition: none;
  }
  .qwipy-howitworks-card:hover {
    transform: none;
  }
}

/* Compound selector (0,3,0) so this reliably wins over
   .qwipy-legal-section's own :first-child/:last-child padding/border
   resets (0,2,0) without touching their effect on privacy/terms, which
   never carry this second class. Border/radius/padding match the
   Process section's own step cards. */
.qwipy-legal-section.qwipy-howitworks-card {
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  border-radius: 20px;
  padding: 40px;
  margin-bottom: 24px;
}

.qwipy-legal-section.qwipy-howitworks-card:first-child {
  padding-top: 40px;
}

.qwipy-legal-section.qwipy-howitworks-card:last-child {
  border-bottom: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  padding-bottom: 40px;
}

/* 36px reads fine as a small inline marker against a hairline divider
   (its role on privacy/terms) but needs more visual weight sitting
   inside a full bordered card next to a heading — enlarged here only,
   same underlying .qwipy-legal-section-number rule set otherwise. */
.qwipy-howitworks-card .qwipy-legal-section-number {
  width: 44px;
  height: 44px;
  font-size: 14px;
}

@media (max-width: 809px) {
  .qwipy-legal-section.qwipy-howitworks-card {
    padding: 28px;
  }
  /* Without this, the unconditional :first-child rule above (same
     specificity, but declared outside this media query and only
     setting padding-top) still wins the cascade and leaves the first
     card's top padding at 40px here — everything else shrinks to 28px
     but the first card doesn't match. */
  .qwipy-legal-section.qwipy-howitworks-card:first-child {
    padding-top: 28px;
  }
  .qwipy-howitworks-card .qwipy-legal-section-number {
    width: 38px;
    height: 38px;
    font-size: 13px;
  }
}

/* Keyboard-shortcuts recap, below the step cards — reuses the exact
   translateY-lift hover already live on .qwipy-legal-chip/
   .qwipy-contact-submit, just on a wider two-line badge. */
.qwipy-howitworks-shortcuts {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 8px;
}

.qwipy-howitworks-shortcuts-label {
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.45;
}

.qwipy-howitworks-shortcuts-list {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

.qwipy-shortcut-badge {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 18px;
  border-radius: 14px;
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  background: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
  min-width: 220px;
  transition: transform 0.2s cubic-bezier(0.16, 0.8, 0.3, 1), box-shadow 0.2s ease;
}

.qwipy-shortcut-badge:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 16px rgba(29, 29, 29, 0.12);
}

.qwipy-shortcut-badge:active {
  transform: translateY(0) scale(0.97);
}

/* Individual keycap chips (one per key) instead of a single "Alt + Shift
   + F" text pill — matches how Apple's own System Settings > Keyboard
   Shortcuts documents a combo: separate small keys shown side by side.
   Plain readable labels ("Alt", not "⌥") deliberately, not Mac-only
   symbol glyphs — this exact shortcut is identical on Windows too, and
   ⌥/⇧ mean nothing to someone looking at a PC keyboard. */
.qwipy-shortcut-keys {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 4px;
}

.qwipy-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 7px;
  border-radius: 7px;
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  background: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
  /* A short solid shadow along the bottom edge only (not blurred) reads
     as a raised physical keycap rather than a flat pill. */
  box-shadow: 0 1.5px 0 rgba(29, 29, 29, 0.3);
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.qwipy-key-plus {
  font-size: 12px;
  opacity: 0.35;
}

.qwipy-shortcut-desc {
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 13px;
  opacity: 0.65;
}

@media (prefers-reduced-motion: reduce) {
  .qwipy-shortcut-badge {
    transition: none;
  }
  .qwipy-shortcut-badge:hover,
  .qwipy-shortcut-badge:active {
    transform: none;
  }
}

@media (max-width: 809px) {
  .qwipy-shortcut-badge {
    min-width: 0;
    flex: 1 1 100%;
  }
}

/* Full keyboard-shortcuts reference table — one row per shortcut, each
   showing the Mac and Windows key combo side by side (reusing the same
   .qwipy-key keycap chips as the badges above) plus whether it's bound
   by default. Not given the card-hover lift/scale treatment used
   elsewhere on this page — these rows aren't clickable, and that
   animation is reserved for things that are (per this site's own
   cursor/card philosophy: motion announces "you can act on this").

   At tablet width and up this becomes a bento-style grid (inspired by
   MagicUI's Bento Grid, adapted to this plain-CSS site): the 4 shortcuts
   that are on by default form a clean 2x2, while the 2 exceptions — the
   one shipped unbound, and the one built-in/non-customizable composer
   shortcut (Cmd+M/Ctrl+M — the closest thing this table has to a
   flagship feature) — each span the full width via
   .qwipy-shortcut-row--wide below it. Deliberately not 5 even cards in a
   2-column grid: that leaves an unpaired card with an empty cell beside
   it, which reads as a broken/misaligned grid rather than a deliberate
   asymmetry. .qwipy-shortcut-row--hero additionally tints just the
   composer row so it still reads as the standout of the two wide cards.
   Unlike MagicUI's cards, no description is ever hidden behind hover —
   this is reference content people need at a glance, and touch devices
   have no hover at all — so hover here stays a plain background tint,
   never the lift/reveal motion. */
.qwipy-shortcuts-table {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

.qwipy-shortcut-row {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px 22px;
  border-radius: 16px;
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  background: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
  transition: background-color 0.2s ease;
}

@media (min-width: 810px) {
  .qwipy-shortcuts-table {
    grid-template-columns: repeat(2, 1fr);
    align-items: start;
  }

  .qwipy-shortcut-row--wide {
    grid-column: 1 / -1;
  }

  .qwipy-shortcut-row--hero {
    background: rgba(251, 235, 234, 0.35);
  }

  .qwipy-shortcut-row--hero .qwipy-shortcut-title {
    font-size: 17px;
  }

  .qwipy-shortcut-row:hover {
    background: rgba(29, 29, 29, 0.03);
  }

  .qwipy-shortcut-row--hero:hover {
    background: rgba(251, 235, 234, 0.55);
  }
}

@media (prefers-reduced-motion: reduce) {
  .qwipy-shortcut-row {
    transition: none;
  }
}

.qwipy-shortcut-row-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.qwipy-shortcut-title {
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 15px;
  font-weight: 600;
}

.qwipy-shortcut-status {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 100px;
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}

.qwipy-shortcut-status--on {
  background: rgba(52, 168, 83, 0.14);
  color: rgb(25, 100, 55);
}

.qwipy-shortcut-status--off {
  background: rgba(29, 29, 29, 0.06);
  opacity: 0.7;
}

.qwipy-shortcut-platforms {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
}

.qwipy-shortcut-platform {
  display: flex;
  align-items: center;
  gap: 8px;
}

.qwipy-shortcut-platform-label {
  display: inline-flex;
  align-items: center;
  opacity: 0.45;
  min-width: 20px;
}

.qwipy-platform-icon {
  display: block;
}

@media (max-width: 809px) {
  .qwipy-shortcut-row {
    padding: 16px 18px;
  }
}

/* Troubleshooting / common-questions accordions — native <details>/
   <summary>, no JS needed. A standard down-chevron (rotating 180° when
   open) replaces the browser default triangle marker, matching
   conventional accordion affordance instead of a +/× toggle. */
.qwipy-faq {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.qwipy-faq-item {
  border: 1px solid var(--token-2f7038ac-bbf8-44f5-ae13-dbd500870086, #1d1d1d);
  border-radius: 14px;
  padding: 0 20px;
  background: var(--token-9fc38d7a-a3f6-4f38-9b69-d5eb5696eb0d, #fff);
}

.qwipy-faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 0;
  font-family: "Uncut Sans Variable Variable", "Uncut Sans Variable Variable Placeholder", sans-serif;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.qwipy-faq-item summary::-webkit-details-marker {
  display: none;
}

.qwipy-faq-chevron {
  flex-shrink: 0;
  opacity: 0.4;
  transition: transform 0.2s cubic-bezier(0.16, 0.8, 0.3, 1);
}

/* [open] as a fallback (so the icon is still correct with JS disabled,
   since <details> still works natively then) — but the JS-driven open
   in qwipy-added-sections.js flips .qwipy-faq-item--expanded instead,
   at the moment each animation actually starts, not when the [open]
   attribute itself changes (which happens at the END of a close
   animation, not the start — see initFaqAccordion). Matching the two
   selectors keeps both paths correct. */
.qwipy-faq-item[open] .qwipy-faq-chevron,
.qwipy-faq-item.qwipy-faq-item--expanded .qwipy-faq-chevron {
  transform: rotate(180deg);
}

/* Answers are built from the same p() paragraphs used everywhere else on
   this page (own framer-text preset, own font-size) — this wrapper only
   handles the open/close animation and dimming; font-size/line-height
   set here wouldn't reach past the paragraphs' own more specific preset
   class anyway. opacity does apply regardless (it composites the whole
   subtree).

   height/opacity are driven by explicit inline styles from JS
   (initFaqAccordion in qwipy-added-sections.js), not a WAAPI animation
   or a [open]-attribute-conditional rule — this environment's animation
   *completion* timing (WAAPI's `finish` event, same underlying clock as
   requestAnimationFrame) turned out not to fire reliably, the same
   documented issue rAF already has elsewhere in this codebase. A plain
   CSS transition on explicit height/opacity writes, sequenced with
   ordinary setTimeout, sidesteps that entirely — matches how the
   dynamic navbar's own transform transition is already built. No
   padding-bottom here: it's on the last paragraph's margin instead (see
   below), so the whole trailing space is inside the animated height box
   and genuinely collapses to nothing when closed, not just visually
   hidden behind it. */
.qwipy-faq-answer {
  height: 0;
  opacity: 0;
  overflow: hidden;
  transition: height 0.26s cubic-bezier(0.16, 0.8, 0.3, 1), opacity 0.2s ease;
}

.qwipy-faq-answer p:last-child {
  margin-bottom: 18px;
}

/* Fallback for when initFaqAccordion() doesn't run at all — reduced-
   motion visitors (its own guard skips attaching the JS entirely there)
   and anyone with JS disabled. Without this, native <details> would
   still toggle the [open] attribute on click, but the answer would stay
   visually collapsed forever, since the animated base state above hides
   it unconditionally. This makes plain native toggling work correctly,
   just without the custom animation. */
.qwipy-faq-item[open] .qwipy-faq-answer {
  height: auto;
  opacity: 0.75;
}

@media (prefers-reduced-motion: reduce) {
  .qwipy-faq-answer {
    transition: none;
  }
  .qwipy-faq-chevron {
    transition: none;
  }
}
