/* ══════════════════════════════════════════════════════════════
   SunoSync — page-level styles.
   Only what Counter does not already provide: the sticky nav shell,
   the tree listing, step numbering and the two payment tiles.
   Anything that could be a Counter component is a Counter component.
   ══════════════════════════════════════════════════════════════ */

body { background: var(--paper); }

/* Nav — the kit's .topbar floating inside a sticky rail */
.nav-rail { position: sticky; top: 0; z-index: 40; padding: 16px 0; background: transparent; }
.nav-rail .page { display: block; }
.nav-rail .topbar { max-width: 100%; }
.nav-actions { display: flex; align-items: center; gap: 8px; }

/* The cabinet and the admin open straight onto their first band, so its 96px
   of air reads as a hole between the pill and the heading rather than as the
   distance between two sections. Half of it still separates them. */
.nav-rail + main.band { padding-top: 48px; }
@media (max-width: 620px) { .nav-rail + main.band { padding-top: 28px; } }

/* ---------- the phone nav ----------
   Three rows of navigation above the fold is most of a small screen, so on a
   phone the links and the actions travel together behind one button. The
   collapse is `display: contents` everywhere else: the wrapper exists in the
   markup but the bar is laid out exactly as it was before it. */
.nav-collapse { display: contents; }
.nav-burger { display: none; }

@media (max-width: 720px) {
  .topbar { flex-wrap: wrap; align-items: center; gap: 0 12px;
    padding: 10px 14px; border-radius: var(--r-card); }

  .nav-burger { display: inline-flex; align-items: center; justify-content: center;
    margin-left: auto; width: 44px; height: 44px; padding: 0; flex: none;
    border: 1px solid var(--line); border-radius: var(--r-pill);
    background: var(--paper-2); color: var(--ink-1); cursor: pointer; }
  .nav-burger:hover { background: var(--paper-3, var(--paper-2)); }

  /* Three bars that fold into a cross — the state of the panel is on the
     button, so the icon reads the same attribute the panel does. */
  .nav-burger-bars { position: relative; }
  .nav-burger-bars,
  .nav-burger-bars::before,
  .nav-burger-bars::after { display: block; width: 18px; height: 2px;
    border-radius: 2px; background: currentColor;
    transition: transform .2s var(--ease-out), background-color .12s linear; }
  .nav-burger-bars::before, .nav-burger-bars::after { content: ""; position: absolute; left: 0; }
  .nav-burger-bars::before { top: -6px; }
  .nav-burger-bars::after { top: 6px; }
  .nav-burger[aria-expanded="true"] .nav-burger-bars { background: transparent; }
  .nav-burger[aria-expanded="true"] .nav-burger-bars::before { transform: translateY(6px) rotate(45deg); }
  .nav-burger[aria-expanded="true"] .nav-burger-bars::after { transform: translateY(-6px) rotate(-45deg); }

  /* max-height rather than height: the panel holds a handful of links and the
     two buttons, and a ceiling well above that animates without measuring. */
  .nav-collapse { display: block; order: 3; width: 100%; overflow: hidden;
    max-height: 0; opacity: 0;
    transition: max-height .26s var(--ease-out), opacity .16s var(--ease-out); }
  .topbar.is-open .nav-collapse { max-height: 420px; opacity: 1; }

  .nav-collapse .navlinks { display: flex; flex-direction: column; align-items: stretch;
    width: auto; gap: 2px; margin: 10px 0 0; padding-top: 10px;
    border-top: 1px solid var(--line-soft); }
  /* The pill still has room to sit in, but the label starts where the
     wordmark above it does. */
  .nav-collapse .navlinks a { padding: 12px; margin-inline: -12px; font-size: 17px; }

  .nav-collapse .nav-actions { flex-wrap: wrap; gap: 10px; margin-top: 10px;
    padding-top: 12px; border-top: 1px solid var(--line-soft); }
  /* The two buttons split the width; the theme switch keeps its own. */
  .nav-collapse .nav-actions .btn { flex: 1 1 120px; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .nav-collapse, .nav-burger-bars,
  .nav-burger-bars::before, .nav-burger-bars::after { transition: none; }
}

/* Bands alternate paper and void; .invert comes from the kit */
.band.invert { border-top: 0; }
.band-tight { padding: 64px 0; }

/* Hero */
.masthead .cta { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 32px; }
.masthead .under {
  margin-top: 18px; font-family: var(--t-mono); font-size: 13.8px; color: var(--ink-3);
}

/* Catalogue screenshots — one frame, two themes, a curtain between them.
   aspect-ratio holds the height before the images load, so the band never
   jumps; the middle column keeps a 2000px shot from stretching the page.

   The figure is a row — label, frame, label — because the clip that hides half
   of the light shot would swallow anything sitting beside the picture. So the
   clip belongs to the frame, and the labels stand outside it in the gutters. */
.ba {
  display: grid; margin: 0 auto;
  /* max-content is the floor, not 0: a plain 1fr gutter is flexible enough to
     be squeezed to nothing by the picture, which clips the word off the page
     between roughly 900px and 1240px. */
  grid-template-columns:
    minmax(max-content, 1fr) minmax(0, 980px) minmax(max-content, 1fr);
  align-items: center; gap: 0 16px;
}
.ba-frame {
  position: relative; grid-column: 2;
  aspect-ratio: 2000 / 1250; border-radius: var(--r-card);
  overflow: hidden; border: 1px solid var(--line); background: var(--paper-2);
  touch-action: pan-y;
}
.ba img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.ba-over { position: absolute; inset: 0; clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
.ba-line {
  position: absolute; top: 0; bottom: 0; left: var(--pos);
  width: 2px; margin-left: -1px; background: var(--ink-inv); opacity: .9;
}
.ba-line i {
  position: absolute; top: 50%; left: 50%; translate: -50% -50%;
  width: 38px; height: 38px; border-radius: 999px;
  background: var(--ink-inv); box-shadow: 0 2px 10px rgb(0 0 0 / .35);
}
/* Two chevrons drawn with borders — no icon file for a 12px hint. */
.ba-line i::before, .ba-line i::after {
  content: ""; position: absolute; top: 50%; width: 6px; height: 6px;
  border: 2px solid var(--ink-1); border-width: 2px 2px 0 0;
}
.ba-line i::before { left: 11px; translate: 0 -50%; rotate: -135deg; }
.ba-line i::after { right: 11px; translate: 0 -50%; rotate: 45deg; }
/* Standing on the page instead of over the picture, the labels no longer need
   a scrim to stay legible — they take the page's own muted ink. */
.ba-tag {
  font-family: var(--t-mono); font-size: 11.5px; letter-spacing: .06em;
  color: var(--ink-3); white-space: nowrap;
}
.ba-l { grid-column: 1; justify-self: end; }
.ba-r { grid-column: 3; justify-self: start; }
/* The range is the control: invisible, but it owns focus, keyboard and drag. */
.ba-range {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: ew-resize; appearance: none; background: none;
}
.ba-range:focus-visible { outline: none; }
/* The ring is drawn on the curtain, which sits *before* the input in the
   markup — `~` only looks forward, so this was written as a sibling rule and
   had never once matched. With the outline suppressed above it, that left the
   slider with no visible focus at all. :has() does not care about order. */
.ba-frame:has(.ba-range:focus-visible) .ba-line { box-shadow: 0 0 0 3px var(--flare); }
@media (prefers-reduced-motion: reduce) { .ba-frame { touch-action: auto; } }

/* Narrow enough and the gutters cannot hold a word. The labels drop under the
   picture, each staying on the side whose theme it names. */
@media (max-width: 900px) {
  .ba { grid-template-columns: 1fr 1fr; gap: 10px 16px; }
  .ba-frame { grid-column: 1 / -1; grid-row: 1; }
  .ba-l { grid-column: 1; grid-row: 2; justify-self: start; }
  .ba-r { grid-column: 2; grid-row: 2; justify-self: end; }
}

/* Steps — numbered without a list marker, mono ordinals */
.steps-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 32px; }
.steps-list li { display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 20px; }
.steps-list .n {
  font-family: var(--t-mono); font-size: 13.8px; color: var(--ink-3);
  padding-top: 6px; letter-spacing: .08em;
}
.steps-list h3 { margin: 0 0 8px; font-size: 25px; font-weight: 500; letter-spacing: -0.018em; }
.steps-list p { margin: 0; color: var(--ink-2); font-size: 17.3px; line-height: 1.55; max-width: 62ch; }

/* FAQ — six disclosures, hairline-separated, no box around any of them.

   `<details>` and not a scripted accordion: it opens with no JavaScript on the
   page, a screen reader announces it as a button and its state without any
   wiring, and the browser's own find-in-page reaches the text inside a closed
   one. The only thing this file adds is the look.

   Nothing here sets a colour that `.invert` does not already re-point, so the
   block reads correctly in the dark band it sits in and would read correctly
   in a light one without a second rule. */
.faq-list details { border-top: 1px solid var(--line-soft); }
/* Two rules forty pixels apart for one boundary: the head draws the site's
   usual line under its words, and the list draws its own above the first
   question. The list keeps its — that is the line the questions hang from —
   and the head gives its up. The head's padding and margin stay, so nothing
   moves except the rule itself. */
#faq .section-head { border-bottom: 0; }
.faq-list details:last-child { border-bottom: 1px solid var(--line-soft); }
.faq-list summary {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 22px 0; cursor: pointer;
  font-size: 21px; font-weight: 500; letter-spacing: -0.015em; line-height: 1.3;
}
/* Two spellings for one triangle: Safari draws its marker through the
   ::-webkit- pseudo-element and everything else through ::marker. Leaving
   either in place puts a second arrow beside the chevron. */
.faq-list summary { list-style: none; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::marker { content: ""; }
.faq-list summary:focus-visible { outline: 2px solid var(--line-firm); outline-offset: 4px; }
.faq-list .chev {
  width: 18px; height: 18px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
  color: var(--ink-3); transition: transform .18s ease;
}
.faq-list details[open] .chev { transform: rotate(180deg); }
.faq-list .faq-a {
  margin: 0; padding: 0 0 24px; max-width: 68ch;
  color: var(--ink-2); font-size: 17.3px; line-height: 1.6;
}
@media (prefers-reduced-motion: reduce) { .faq-list .chev { transition: none; } }
@media (max-width: 620px) {
  .faq-list summary { font-size: 18.5px; padding: 18px 0; gap: 16px; }
}

/* Payment tiles on /pro — two ways to pay, described, not just labelled */
/* ---------- checkout ----------
   The reason on the left, the form on the right. Somebody deciding whether to
   pay and somebody who has already decided need different things on the screen,
   and putting them in one column made the second group scroll past the first.

   The form itself reads top to bottom: who you are, how you want to pay, the
   button. It was two panels with a button each and the email above them
   belonging to neither — nothing said which button would use the address. */
/* The sticky rail covers whatever an anchor lands on, and #checkout is now the
   target of every Get Pro: without this the form's first field starts under the
   bar. Measured: the rail ends at 98px, so this clears it with air to spare
   rather than butting the first field against its edge. */
#checkout { scroll-margin-top: 112px; }
.checkout-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: clamp(32px, 5vw, 80px); align-items: start; }

.checkout-info h2 { margin: 10px 0 14px; font-size: clamp(28px, 3.2vw, 44px); line-height: 1.08;
  letter-spacing: -.03em; }
.checkout-info .lede { margin: 0 0 34px; max-width: 54ch; }
.checkout-info h3 { margin: 0 0 14px; font-size: 13.8px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .14em; color: var(--ink-3); }

.got { list-style: none; margin: 0 0 34px; padding: 0; display: grid; gap: 11px; }
.got li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 12px;
  align-items: start; font-size: 16.6px; line-height: 1.45; }
.got .tick { width: 22px; height: 22px; margin-top: 1px; fill: none; stroke: var(--flare);
  stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round; }

.how-min { margin: 0; padding: 0 0 0 22px; display: grid; gap: 10px;
  font-size: 16.1px; line-height: 1.5; color: var(--ink-2); }
.how-min li::marker { color: var(--ink-3); font-variant-numeric: tabular-nums; }
/* Browser addresses in a step. Chrome refuses to navigate to chrome:// from a
   page, so these are not links — white is the whole affordance: type it. */
.how-min code.addr { color: var(--ink-1); }
/* The file you drag. White and heavier than the prose so the eye finds it
   before reading the sentence. */
.how-min code.file { color: var(--ink-1); font-weight: 700; }

/* In the checkout column the two lists trade places and weights: how it runs
   leads and carries the page's own ink, what lands on the disk follows it a
   step back. Scoped rather than changed at the source, because .how-min is
   install.html's list too — and there the grey prose is exactly what makes its
   white <code> addresses read as "type this". */
.checkout-info .how-min { margin: 0 0 34px; color: var(--ink-1); }
.checkout-info .got { margin-bottom: 0; }
.checkout-info .got li { color: var(--ink-2); }

/* The arithmetic of waiting.
   Months rather than money: Suno's subscription prices are theirs to quote,
   and the delay is the part that lands anyway. This is the argument the page
   makes, so it is a table you can read across a room rather than a footnote
   set in the body size. */
.cost-why { margin: 0 0 18px; font-size: 16.6px; line-height: 1.5; color: var(--ink-2);
  max-width: 54ch; }

.cost-box { border: 1px solid var(--line); border-radius: var(--r-card, 24px);
  background: var(--paper-2); padding: clamp(20px, 2.2vw, 30px); margin: 0 0 32px; }
.cost { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }

/* Every column carries its own padding, so the highlighted one has room on both
   sides. With padding only on the right, the next heading started flush against
   the tint and looked like it had been cropped by it. */
.cost th, .cost td { text-align: left; padding: 16px 18px; }
.cost th:first-child, .cost td:first-child { padding-left: 0; }
.cost th:last-child, .cost td:last-child { padding-right: 0; }
.cost tbody tr { border-top: 1px solid var(--line-soft); }

.cost thead th { font-size: 12.4px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .1em; color: var(--ink-3); padding-top: 14px; padding-bottom: 14px;
  vertical-align: bottom; line-height: 1.25; white-space: nowrap; }
.cost thead th span { display: block; margin-top: 4px; font-size: 11.5px;
  letter-spacing: .04em; text-transform: none; font-weight: 400; opacity: .7; }

.cost tbody th { font-size: 16.6px; font-weight: 500; letter-spacing: -.01em;
  color: var(--ink-2); white-space: nowrap; }
/* The waits are the point, so they are the largest thing in the table. */
.cost tbody td { font-size: clamp(19px, 1.8vw, 26px); font-weight: 400;
  letter-spacing: -.025em; color: var(--ink-1); white-space: nowrap; }

/* One column is not a wait at all. A soft wash and a hairline down each side
   mark it as a column rather than a highlighter stroke across the rows. */
.cost th:nth-child(2), .cost td:nth-child(2) {
  background: color-mix(in oklab, var(--flare) 11%, transparent);
  box-shadow: inset 1px 0 0 color-mix(in oklab, var(--flare) 26%, transparent),
              inset -1px 0 0 color-mix(in oklab, var(--flare) 26%, transparent);
}
.cost thead th:nth-child(2) { color: var(--flare); border-radius: 14px 14px 0 0;
  box-shadow: inset 1px 1px 0 color-mix(in oklab, var(--flare) 26%, transparent),
              inset -1px 0 0 color-mix(in oklab, var(--flare) 26%, transparent); }
.cost tbody tr:last-child td:nth-child(2) { border-radius: 0 0 14px 14px;
  box-shadow: inset 1px -1px 0 color-mix(in oklab, var(--flare) 26%, transparent),
              inset -1px 0 0 color-mix(in oklab, var(--flare) 26%, transparent); }
.cost .now { color: var(--flare); font-weight: 500; }

.cost-note { margin: 0 0 34px; font-size: 15.4px; line-height: 1.55; color: var(--ink-3);
  max-width: 56ch; }

@media (max-width: 620px) {
  .cost-box { padding: 0; background: none; border: 0; }
  .cost, .cost tbody, .cost tr, .cost th, .cost td { display: block; width: auto; }
  .cost thead { display: none; }

  .cost tbody tr { border: 1px solid var(--line); border-radius: 20px;
    background: var(--paper-2); padding: 16px 18px; margin-bottom: 12px; }
  .cost tbody tr:last-child { margin-bottom: 0; }

  .cost tbody th { font-size: 17.5px; padding: 0 0 10px;
    border-bottom: 1px solid var(--line-soft); margin-bottom: 6px; }

  /* The tint, the hairlines down each side and the rounded ends belong to a
     column. Stacked into cards there is no column left to mark, and the insets
     that survived read as a stray box drawn around one line. */
  .cost tbody td, .cost tbody td:nth-child(2),
  .cost tbody tr:last-child td:nth-child(2) { display: flex; align-items: baseline;
    justify-content: space-between; gap: 16px; padding: 8px 0; background: none;
    border-radius: 0; box-shadow: none; font-size: 19px; }
  /* The wait is the value, so it keeps the room: the label holds its width and
     a long wait wraps instead of running past the card. */
  .cost tbody td { white-space: normal; text-align: right; }
  .cost tbody td::before { content: attr(data-label); font-size: 13.8px; font-weight: 500;
    color: var(--ink-3); flex: none; text-align: left; }
  /* The one line that is not a wait keeps the accent, label and all. */
  .cost tbody td.now { color: var(--flare); font-weight: 500; }
  .cost tbody td.now::before { color: var(--flare); opacity: .85; }
}

/* The form gets a surface of its own: on a busy section it is the thing you
   are meant to end up in. */
.checkout-pane { padding: clamp(22px, 2.4vw, 32px); border-radius: var(--r-card, 26px);
  background: var(--paper-2); border: 1px solid var(--line-soft); position: sticky; top: 24px; }
.checkout { display: flex; flex-direction: column; gap: 24px; }
.checkout .field > label { font-size: 16px; }

.methods { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: 12px; }
.methods legend { padding: 0; margin: 0 0 12px; font-size: 16px; font-weight: 500;
  color: var(--ink-2); }

/* `hidden` has to outrank the display rules on either side of it. The attribute
   is the whole of how checkout.js keeps a provider we hold no keys for off the
   page, and a class selector beats the browser's own [hidden] every time.

   .checkout-go is here for the same reason and was missed once: it is
   `display: flex`, so `submit.hidden = true` set the attribute and changed
   nothing, and choosing PayPal left both buttons standing. Whenever a rule in
   this file gives one of these a display, its [hidden] belongs on this line.

   .field is the fourth, and it got here without a rule of its own: it is a
   flex item of .checkout, and a flex container blockifies its children over
   the top of the browser's [hidden]. Hiding the address field for the
   maintenance notice set the attribute and left the field standing. */
.methods[hidden], .method[hidden], .checkout-go[hidden],
.field[hidden] { display: none; }

.method { display: flex; gap: 14px; padding: 16px 18px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 18px;
  background: var(--paper);
  transition: border-color .18s var(--ease-out), background .18s var(--ease-out); }
.method:hover { border-color: var(--line-firm); }
/* The chosen one carries the accent as an outline, not a fill: the one filled
   accent on this screen is the button that takes the money. */
.method:has(input:checked) { border-color: var(--flare);
  box-shadow: 0 0 0 1px var(--flare); background: var(--paper-3); }
.checkout .field > label, .methods legend { font-size: 15px; }
.checkout-go { width: 100%; display: flex; flex-direction: column; align-items: center;
  gap: 5px; height: auto; padding: 20px 24px; border-radius: 22px; line-height: 1.25; }
.checkout-go .go-main { font-size: clamp(18px, 1.7vw, 22px); font-weight: 600;
  letter-spacing: -.015em; }
.checkout-go .go-sub { font-size: 13.2px; font-weight: 400; opacity: .82; text-align: center; }

.method > input { flex: none; margin: 3px 0 0; width: 19px; height: 19px;
  accent-color: var(--flare); cursor: pointer; }
/* One keyed provider is not a choice, so it stops looking like one: the sole
   method keeps its card and loses the radio and the cursor that offers it. The
   input stays in the DOM, checked — it is what the form reads on submit, and
   what :has() above styles the card by. */
.methods.is-single .method { cursor: default; }
.methods.is-single .method:hover { border-color: var(--flare); }
.methods.is-single .method > input { display: none; }
.method-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.method-head { font-size: 19px; font-weight: 500; letter-spacing: -.015em; }
.method-note { font-size: 15.2px; line-height: 1.5; color: var(--ink-2); }
/* What this method will actually put on the statement, when that is not the
   dollar price on the button. Filled in by checkout.js from the API's answer,
   so it is authored hidden and stays hidden for every method that has none. */
.method-charge {
  align-self: flex-start; font-size: 14px; font-weight: 500;
  padding: 3px 9px; border-radius: 999px;
  background: var(--paper-2); border: 1px solid var(--line-soft); color: var(--ink-1);
}

.paylogos {
  list-style: none; margin: 4px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 14px 18px;
}
.paylogos li { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 54px; }
.paylogo {
  display: grid; place-items: center; width: 54px; height: 34px;
  background: #fff; border: 1px solid var(--line-soft); border-radius: 9px;
}
.paylogo-name {
  font-size: 11.5px; color: var(--ink-3); text-align: center; line-height: 1.2;
}
.checkout-go.is-loading { opacity: .7; cursor: wait; }

/* Where PayPal appends its own button, in place of .checkout-go. PayPal styles
   the button itself and will not take ours, so this only gives it the width and
   the same standing in the column — never a colour or a radius, which would be
   overridden anyway and would misrepresent the brand if it were not. */
.checkout-paypal { width: 100%; min-height: 52px; }
/* PayPal draws the button in a shadow root and keeps its own colour, wordmark
   and radius — none of which are ours to restyle. Width is: left alone the
   element sits at its intrinsic size and reads as a smaller, lesser button
   beside the one it replaces, when it is now the only way to pay. */
.checkout-paypal paypal-button { display: block; width: 100%; }

@media (max-width: 980px) {
  .checkout-split { grid-template-columns: minmax(0, 1fr); }
  .checkout-pane { position: static; }
}
@media (max-width: 620px) {
  .method { padding: 14px; }
  .got li { font-size: 15.6px; }
}


/* Checkout feedback — the kit's .banner, hidden until something happens */
#checkout-status[hidden] { display: none; }
#checkout-status { margin-top: 20px; }

/* The legal line under the pay button — the only place some buyers will ever
   meet these three pages. Held at the weight of the field hints above it, not
   the footnote grey: a line a buyer is deemed to have read has to be readable. */
.checkout-legal { margin: -6px 0 0; padding-top: 16px;
  border-top: 1px solid var(--line-soft);
  font-size: 13.2px; line-height: 1.55; color: var(--ink-3); text-align: center; }
.checkout-legal a { color: var(--ink-2); text-decoration: underline;
  text-decoration-color: var(--line-firm); text-underline-offset: 2px; }
.checkout-legal a:hover { color: var(--ink-1); }

@media (max-width: 720px) {
  .steps-list li { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .steps-list .n { padding-top: 0; }
}

/* ---------- single-link grab (masthead) ---------- */
/* ---------- single-link grab (masthead) ----------
   Two layers rather than two bars: the link box sits on top and the options
   sheet reaches up behind its rounded corners. That overlap is the whole
   effect — square the sheet off at the box's baseline and it reads as a
   second bar stacked underneath instead of one card.

   The three surfaces are the theme's own steps, so the order the mock sets in
   the dark — box darkest, free lightest, Pro between — mirrors itself in the
   light without a second palette to maintain. */
.grab{max-width:1180px;margin:32px auto 0}
.download-card{position:relative;text-align:left;
  --dl-pad:clamp(18px,2vw,28px);        /* edge inset and gap, the same number */
  --dl-lift:clamp(20px,2vw,30px);      /* how far the sheet reaches up */
  --dl-round:clamp(18px,1.8vw,24px)}

.url-form{position:relative;z-index:2;display:flex;align-items:center;
  gap:clamp(10px,1.3vw,20px);min-height:clamp(72px,5.8vw,88px);
  padding:clamp(10px,.8vw,13px);padding-left:calc(var(--dl-pad) - 1.5px);overflow:hidden;
  /* Four surfaces, not three: the page, then the box, then Pro, then free.
     Only the box needs a step the palette does not already name. */
  background:color-mix(in oklab,var(--paper) 55%,var(--paper-2));
  border:1.5px solid var(--paper-3);
  border-radius:calc(var(--dl-round) + 8px);
  transition:border-color .18s var(--ease-out)}
.url-form:focus-within{border-color:var(--ink-3)}
.url-form.is-invalid{border-color:var(--negative-ink,#e0524a)}
.url-form.is-busy{opacity:.7}

.url-input{flex:1;min-width:0;border:0;outline:0;background:none;font:inherit;color:inherit;
  padding:0 clamp(6px,1.2vw,24px) 0 0;font-size:clamp(16px,1.45vw,21px);letter-spacing:-.02em}
.url-input::placeholder{color:var(--ink-3);opacity:1}

.submit-button{position:relative;flex:none;display:inline-grid;place-items:center;overflow:hidden;
  width:clamp(122px,11vw,152px);height:clamp(44px,4.2vw,56px);padding:0 20px;border:0;
  border-radius:999px;background-image:var(--grad);color:#fff;cursor:pointer;font:inherit;
  font-size:clamp(15px,1.25vw,17.5px);font-weight:700;letter-spacing:-.02em;
  transition:transform .16s var(--ease-out),filter .16s var(--ease-out)}
.submit-button::after{content:"";position:absolute;inset:0;background:rgba(255,255,255,.12);
  opacity:0;transition:opacity .16s var(--ease-out)}
.submit-button:hover::after{opacity:1}
.submit-button:active{transform:scale(.975)}
.submit-button:disabled{cursor:wait;filter:saturate(.78)}

/* The sheet carries the Pro colour itself, so the free group can keep its
   rounded corner and the curve reveals the group behind it rather than the
   page. */
.options-row{position:relative;z-index:1;display:grid;
  grid-template-columns:auto minmax(0,1fr);margin-top:-1px;
  background:var(--paper-2);border-radius:0 0 var(--dl-round) var(--dl-round)}
.standard-options,.pro-options{position:relative;display:flex;align-items:center;min-width:0;
  min-height:clamp(36px,2.94vw,43px);padding:10px var(--dl-pad)}
/* Each column lifts its own colour behind the box, so the seam always lands
   where the columns split — no width has to be written down twice. */
.standard-options::before,.pro-options::before{content:"";position:absolute;left:0;right:0;
  top:calc(-1 * var(--dl-lift));height:var(--dl-lift);background:inherit}
.standard-options{gap:var(--dl-pad);flex-wrap:wrap;justify-content:flex-start;
  background:var(--paper-3);border-radius:0 0 var(--dl-round) var(--dl-round)}
.pro-options{gap:var(--dl-pad);justify-content:flex-start;background:var(--paper-2);
  border-radius:0 0 var(--dl-round) 0}

.choice{position:relative;display:inline-flex;align-items:center;gap:clamp(8px,.8vw,14px);
  min-width:0;cursor:pointer;user-select:none;white-space:nowrap;line-height:1;
  font-size:clamp(14px,1.05vw,15.5px)}
/* Drawn, not native: a disabled box is what Pro looks like here, and Chrome
   fades its own to about half — on a dark ground the square disappears. */
.choice-input{position:relative;flex:none;margin:0;appearance:none;cursor:pointer;
  width:clamp(16px,1.05vw,18px);height:clamp(16px,1.05vw,18px);
  border:1.6px solid var(--ink-3);border-radius:5px;background:none}
.choice-input:checked{background-image:var(--grad);border-color:transparent}
.choice-input:checked::after{content:"";position:absolute;left:34%;top:15%;width:24%;height:50%;
  border:solid #fff;border-width:0 2px 2px 0;transform:rotate(43deg)}
.choice-input:disabled{cursor:not-allowed}
/* Only a track that genuinely lacks the asset dims — that is information. */
.choice.is-off{opacity:.45;cursor:not-allowed}
.grab-size{font-size:.72em;color:var(--ink-3);font-variant-numeric:tabular-nums}

/* Read by a screen reader and by a crawler, drawn for nobody. `hidden` would
   have been shorter and wrong: display:none takes it out of the accessibility
   tree too, and the download card is labelled by this heading. */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
/* The column is this sentence and nothing else — the chip that used to sit
   beside it made the free card argue with the price section. */
.pro-note{flex:1 1 auto;min-width:0;margin:0;line-height:1.3;
  font-size:clamp(12px,.9vw,13.5px);color:var(--ink-2)}

.submit-button:focus-visible,.choice-input:focus-visible{
  outline:2px solid var(--flare);outline-offset:3px}

.download-card .status{margin:12px 0 0;padding:0 clamp(20px,2.6vw,40px);font-size:14px;
  color:var(--ink-3);opacity:0;transform:translateY(-3px);
  transition:opacity .14s var(--ease-out),transform .14s var(--ease-out)}
.download-card .status.is-visible{opacity:1;transform:none}
.download-card .status.is-error{color:var(--negative-ink,#e0524a)}

/* The Pro column drops under the free one before either has to squeeze. */
@media (max-width:900px){
  .options-row{grid-template-columns:minmax(0,1fr)}
  .standard-options{border-radius:0}
  .standard-options::before{background:var(--paper-3)}
  .pro-options{
    border-radius:0 0 var(--dl-round) var(--dl-round)}
  .pro-options::before{display:none}
}
@media (max-width:720px){
  .url-form{flex-direction:column;align-items:stretch;gap:14px;padding:18px}
  .url-input{padding:0;min-height:44px;font-size:19px}
  .submit-button{width:100%;height:52px;font-size:17px}
  .standard-options{gap:14px 20px}
  .choice{min-height:44px;font-size:15.5px}
  .choice-input{width:20px;height:20px}
}
@media (max-width:470px){
  .standard-options{display:grid;grid-template-columns:1fr 1fr;gap:8px 14px}
  .pro-options{flex-wrap:wrap;gap:12px 16px}
}
.grab-card{position:relative;display:flex;gap:18px;margin-top:20px;padding:18px;border-radius:22px;
  border:1px solid var(--line,#2a2a30);text-align:left}
.grab-cover{width:132px;height:132px;border-radius:14px;object-fit:cover;background:var(--paper-3,#eee);flex:none}
.grab-body{flex:1;min-width:0}
/* The corner is the badge's, so the title stops before it. */
.grab-body h3{margin:0 0 4px;padding-right:38px;font-size:19px;letter-spacing:-.01em}
.grab-meta{font-size:13px;opacity:.65;margin:0 0 8px}
.grab-styles{font-size:13px;opacity:.8;margin:0}
.grab-error{color:var(--negative-ink,#e0524a)}

/* One light, three states, drawn in the ink of the state it is in. */
.grab-state{position:absolute;top:14px;right:14px;display:grid;place-items:center;
  width:30px;height:30px;border-radius:999px;background:var(--paper-2);
  border:1px solid var(--line,#2a2a30);color:var(--ink-3)}
.grab-state svg{display:none;grid-area:1/1;width:16px;height:16px;fill:none;stroke:currentColor;
  stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
.grab-state[data-state="working"] .i-work{display:block;animation:grab-spin .9s linear infinite}
.grab-state[data-state="done"]{color:var(--positive);border-color:currentColor}
.grab-state[data-state="done"] .i-done{display:block}
.grab-state[data-state="fail"]{color:var(--negative-ink,#e0524a);border-color:currentColor}
.grab-state[data-state="fail"] .i-fail{display:block}
@keyframes grab-spin{to{transform:rotate(1turn)}}
@media (prefers-reduced-motion:reduce){.grab-state .i-work{animation-duration:3s}}
@media (max-width:640px){.grab-card{flex-direction:column}.grab-cover{width:100%;height:190px}}

/* ================= theme ==================================================
   counter.css defines the light palette on :root. Dark is the default here,
   so the tokens are re-pointed rather than the components restyled, and
   [data-theme="light"] puts the original values back. Values match the
   library viewer so both surfaces read as one product.
   ========================================================================= */
:root{
  --paper:#0d0d0f; --paper-2:#151518; --paper-3:#1e1e23;
  --void:#151518;  --void-2:#1e1e23;  --void-3:#26262d;
  --ink-1:#f2f2f4; --ink-2:#a8a8b3; --ink-3:#6f6f7c; --ink-4:#4a4a55;
  --ink-inv:#0d0d0f;
  --line:rgba(255,255,255,.13); --line-soft:rgba(255,255,255,.07); --line-firm:rgba(255,255,255,.3);
  --e-1:0 1px 2px rgba(0,0,0,.5); --e-2:0 8px 24px rgba(0,0,0,.55); --e-3:0 24px 64px rgba(0,0,0,.6);
  /* drop-shadow() takes a single shadow, so the elevation tokens above cannot
     serve it. This is --e-3's weight in the form a filter accepts. */
  --drop-3: drop-shadow(0 16px 26px rgb(0 0 0 / .6));
  --ring:0 0 0 2px var(--paper), 0 0 0 4px var(--ink-1);
  /* one accent, always a gradient */
  --grad:linear-gradient(100deg,#ff7a2f 0%,#f5384f 46%,#f51bee 100%);
  --grad-edge:linear-gradient(100deg,#ff7a2f,#f51bee);
  --flare:#f51bee; --flare-deep:#c614be; --flare-wash:rgba(245,27,238,.14); --halo:#ff7a2f;
  --flare-ink:#ff8ae8;
  color-scheme:dark;
}
:root[data-theme="light"]{
  --paper:#fff; --paper-2:oklch(96.5% 0 0); --paper-3:oklch(93% 0 0);
  --void:oklch(14% 0 0); --void-2:oklch(19% 0 0); --void-3:oklch(25% 0 0);
  --ink-1:oklch(16% 0 0); --ink-2:oklch(42% 0 0); --ink-3:oklch(58% 0 0); --ink-4:oklch(74% 0 0);
  --ink-inv:#fff;
  --line:oklch(16% 0 0 / .12); --line-soft:oklch(16% 0 0 / .07); --line-firm:oklch(16% 0 0 / .28);
  --e-1:0 1px 2px oklch(16% 0 0 / .06); --e-2:0 8px 24px oklch(16% 0 0 / .08); --e-3:0 24px 64px oklch(16% 0 0 / .14);
  --drop-3: drop-shadow(0 12px 20px oklch(16% 0 0 / .14));
  --flare-ink:var(--flare-deep);
  color-scheme:light;
}
html,body{background:var(--paper);color:var(--ink-1)}

/* accent surfaces become the gradient */
.btn-accent,.btn-primary{background-image:var(--grad);background-color:transparent;color:#fff;border-color:transparent}
.btn-accent:hover,.btn-primary:hover,.btn-accent.is-hover,.btn-primary.is-hover,
.btn-accent:active,.btn-primary:active,.btn-accent.is-active,.btn-primary.is-active,
.btn-accent:focus-visible,.btn-primary:focus-visible{
  background-image:var(--grad);background-color:transparent;background-origin:border-box}
.btn-accent:hover,.btn-primary:hover{filter:brightness(1.08)}
.btn-accent:active,.btn-primary:active{filter:brightness(.94)}
/* The gradient is sized to the padding box by default, so on anything with a
   border it repeats into that 1px ring and wraps the 100% stop (magenta) back
   against the left edge. Paint it over the border box instead.

   The origin is repeated in the state rule above, and that is not redundant.
   counter.css sets `.btn-accent:hover { background: … }` as a *shorthand*, and
   a shorthand resets every longhand it did not name — origin included. Two
   classes beat one, so on hover that rule wins over this one and the stripe
   comes back for exactly as long as a pointer is on the button. Anything added
   to the list below needs the same treatment wherever a state re-declares its
   background as a shorthand. */
.btn-accent,.btn-primary,.submit-button,.choice-input:checked,
.mark-glyph,.task-pro .task-ico,.badge.glow{background-origin:border-box}
/* The mark is the logo itself now — the gradient disc with the sync arrows,
   vector so it stays clean from a 20px header to a retina hero. !important
   because counter.css paints a radial gradient there for the library viewer. */
.mark-glyph{background-image:url("/assets/img/mark.svg")!important;background-size:100% 100%}
/* The home page carries the whole lockup instead of disc-plus-word: in the
   artwork the disc sits *inside* the name, between "Suno" and "Sync", so it is
   one drawing rather than two elements standing next to each other.
   It is inlined in the markup, not an <img>, because the lettering is painted
   with currentColor — an <img> can only read the operating system's scheme,
   and the theme toggle on this site would leave it behind. */
/* aspect-ratio is not decoration here: an inline <svg> with no width
   attribute defaults to width:100%, so the box came out far wider than the
   drawing and centred it, padding the header with dead space. Pinning the
   ratio makes width:auto resolve to height x ratio, the artwork's own. */
.mark-lockup{display:block;height:30px;width:auto;aspect-ratio:1858.29/307.43;color:var(--ink-1)}
@media (max-width:620px){.mark-lockup{height:26px}}
/* The base row runs on 13.8px mono, so the lockup steps down with it. */
.foot-base .mark-lockup{height:26px}
.masthead h1 em{background-image:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}

/* ---------- theme toggle ---------- */
/* A recessed track, and the selection is a chip in the page colour carrying
   normal ink — never an inverted glyph. The knob adds the slide a plain
   segmented control does not have.
   The arithmetic has to close exactly or the chip rides off the icon it backs:
   60x32, no border, 3px padding -> 54x26 content, which is precisely two 26px
   icons with a 2px gap, and one icon pitch is 26+2=28. */
.theme-toggle{position:relative;display:inline-flex;align-items:center;gap:2px;width:60px;height:32px;
  padding:3px;border-radius:999px;border:0;background:var(--paper-3);cursor:pointer;flex:none}
.theme-knob{position:absolute;top:3px;left:3px;width:26px;height:26px;border-radius:999px;
  background:var(--paper);transition:transform .22s var(--ease-out,cubic-bezier(.22,.61,.36,1))}
:root[data-theme="light"] .theme-knob{transform:translateX(28px)}
.theme-ico{position:relative;width:26px;height:26px;padding:5px;fill:none;stroke:currentColor;stroke-width:1.7;
  color:var(--ink-3);transition:color .2s,fill .2s,stroke .2s}
/* The chip sits under the icon for the theme you are in: moon while dark, sun
   while light. Whichever it backs is the one in full ink. */
.theme-ico.moon{fill:var(--ink-1);stroke:none}
:root[data-theme="light"] .theme-ico.moon{fill:var(--ink-3);stroke:none}
.theme-ico.sun{stroke:var(--ink-3);fill:none}
:root[data-theme="light"] .theme-ico.sun{stroke:var(--ink-1);fill:none}

/* ---------- the three tasks ---------- */
.tasks{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:26px 0 18px}
.task{display:flex;align-items:flex-start;gap:12px;padding:16px 18px;border-radius:18px;
  border:1px solid var(--line);background:var(--paper-2);text-decoration:none;color:inherit;
  transition:transform .18s var(--ease-out,cubic-bezier(.22,.61,.36,1)),border-color .18s}
.task:hover{transform:translateY(-4px);border-color:var(--line-firm)}
.task-ico{display:grid;place-items:center;width:34px;height:34px;border-radius:11px;flex:none;
  background:var(--paper-3);font-size:16px}
.task-pro .task-ico{background-image:var(--grad);color:#fff}
.task-body{display:flex;flex-direction:column;gap:3px;min-width:0}
.task-body b{font-size:15px;font-weight:600}
.task-body i{font-style:normal;font-size:13px;color:var(--ink-3);line-height:1.4}
@media (max-width:760px){.tasks{grid-template-columns:1fr}}

/* ---------- grab moved above the fold ---------- */
.grab-lead{max-width:none;margin:0 auto 34px}
.task-ico svg{width:17px;height:17px}
/* Only the recommended plan carries the accent; the others are surfaces. */
.plan-top-mute{background:var(--paper-3);color:var(--ink-1)}
.badge.glow{background-image:var(--grad);color:#fff}

/* Two plans, not three: keep the pair from stretching the width of the page. */
.plans-pair{max-width:860px;margin-inline:auto}

/* Desktop: the icon tile matches the height of the text beside it, so the card
   has the same gap on all four sides instead of a hole under a small square. */
@media (min-width: 761px){
  .task{padding:18px;gap:16px}
  .task-ico{width:40px;height:40px;border-radius:13px}
  .task-ico svg{width:21px;height:21px}
}

/* ══════════════════════════════════════════════════════════════
   Sign-in — one modal on a scrim, no nav rail and no footer.
   Signing in is the only thing on the screen, so nothing else is on it.
   ══════════════════════════════════════════════════════════════ */
.auth-scrim{min-height:100vh;display:grid;place-items:center;padding:24px;
  position:relative;background:var(--void);overflow:hidden}
.auth-scrim::before{content:"";position:absolute;inset:0;
  background:radial-gradient(90% 90% at 50% 0%,oklch(24% 0 0),oklch(14% 0 0))}
.auth-card{position:relative;width:100%;max-width:440px;background:var(--paper-2);
  border:1px solid var(--line-soft);border-radius:var(--r-media);
  box-shadow:var(--e-3);padding:28px}
.auth-head{display:flex;align-items:center;gap:12px;margin-bottom:22px}
.auth-head h1{margin:0;font-size:25.3px;font-weight:500;letter-spacing:-.02em}
.auth-head .mark-glyph{width:22px;height:22px;border-radius:999px;flex:none}
.auth-x{margin-left:auto;color:var(--ink-3);line-height:0;padding:6px;border-radius:999px}
.auth-x:hover{color:var(--ink-1);background:oklch(100% 0 0/.06)}
.auth-x svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round}
/* Google is white because that is the button people recognise, not because it
   is the accent — the accent stays on the one primary action below. */
.btn-google{background:#fff;color:#111;border:1px solid transparent;gap:10px}
/* The button is an <a>, and counter.css turns every anchor's text to --ink-1
   on hover — white in dark theme, on a button that stays white. Say the ink
   again here: two classes beat the element rule. */
.btn-google:hover{background:oklch(92% 0 0);color:#111}
.btn-google svg{width:18px;height:18px}
/* In light theme the sheet behind it is near-white, so a white button with a
   transparent border is a button with no edge at all. Dark theme needs none —
   there the card is the contrast. */
:root[data-theme="light"] .btn-google{border-color:var(--line-firm)}
.auth-or{display:flex;align-items:center;gap:14px;margin:20px 0;
  color:var(--ink-3);font-size:14px}
.auth-or::before,.auth-or::after{content:"";height:1px;flex:1;background:var(--line)}
.auth-legal{margin:22px 0 0;text-align:center;font-size:13px;color:var(--ink-4);line-height:1.5}
.auth-legal a{color:var(--ink-3);border-bottom:1px solid var(--line)}
.auth-note{margin:0 0 18px;font-size:15px;line-height:1.5;color:var(--ink-2)}
.auth-note b{color:var(--ink-1);font-weight:500}
/* The six digits: wide tracking so a typed code is checkable at a glance. */
.auth-code{font-family:var(--t-mono);font-size:26px;letter-spacing:.34em;text-align:center}
@media (max-width:480px){.auth-card{padding:22px}}

/* ---------- code field: Counter's .otp cells over one real input ---------- */
.otp{position:relative;justify-content:center;gap:8px}
.otp .otp-input{
  position:absolute;inset:0;width:100%;height:100%;
  opacity:0;border:0;background:none;font:inherit;
  letter-spacing:1em;text-align:center;cursor:text;
}
.otp .otp-input:focus{outline:none}
.otp span{background:var(--paper-2);border-color:var(--line);color:var(--ink-1);
  transition:border-color .18s var(--ease-out)}
.otp.is-error span{border-color:var(--negative);color:var(--negative)}
@media (max-width:480px){
  .otp{gap:6px}
  .otp span{width:44px;height:52px;font-size:21px}
}

/* ---------- our validation messages, never the browser's bubble ---------- */
.field-error{margin:7px 0 0;font-size:13.5px;line-height:1.45;color:var(--negative)}
.input.is-error{border-color:var(--negative)}

/* ---------- the code the cabinet gives out ---------- */
.code-give{margin:8px 0 34px;scroll-margin-top:118px}
.otp.is-static{pointer-events:none;justify-content:flex-start;flex:0 0 auto}
/* The two columns of .section-head, so the caption starts on the same line as
   every other sentence on the page. Collapses where those heads collapse. */
.code-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:20px 48px;align-items:center}
.code-keys{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
@media (max-width:1024px){.code-row{grid-template-columns:minmax(0,1fr)}}
/* The bar is the life of the digits, so it is exactly as wide as they are:
   six 52px cells and the five 8px gaps of the .otp rule above. Let it run the
   width of the row and it reads as a clock on the sentence beside them. */
.code-clock{display:flex;align-items:center;margin-top:14px;max-width:352px}
.code-bar{flex:1;height:3px;border-radius:999px;background:var(--paper-3);overflow:hidden}
.code-bar i{display:block;height:100%;width:100%;background-image:var(--grad);
  transform-origin:left;transition:transform 1s linear}
/* Same box as a digit cell — see .otp span in counter.css — so the row reads as
   one strip of controls and not as a button parked beside taller cells. */
.code-copy{display:grid;place-items:center;width:52px;height:60px;flex:0 0 auto;
  border:1px solid var(--line);border-radius:var(--r-input);background:var(--paper-2);
  color:var(--ink-2);cursor:pointer;
  transition:border-color .18s var(--ease-out),color .18s var(--ease-out)}
.code-copy:hover{border-color:var(--ink-1);color:var(--ink-1)}
.code-copy svg{width:19px;height:19px;grid-area:1/1}
.code-copy .i-done,.code-copy.is-done .i-copy{display:none}
.code-copy.is-done .i-done{display:block;color:var(--positive)}
.code-copy.is-done{border-color:var(--ink-1)}
.code-give.is-dead .otp span{opacity:.35}
.code-give.is-dead .code-clock,.code-give.is-dead .code-copy{display:none}
.code-again{margin-top:14px}
/* The sentence the digits need: when to use them and where they go. Set beside
   the cells, so it reads as the caption of the code and not as another step. */
.code-what{margin:0;max-width:46ch;
  font-size:16px;line-height:1.55;color:var(--ink-3)}
.code-what b{color:var(--ink-2);font-weight:500}
@media (max-width:480px){
  /* Cells shrink at this width — see the .otp rule above — so the bar and the
     copy button do too. */
  .code-clock{max-width:294px}
  .code-copy{width:44px;height:52px}
}

/* ---------- hero: copy and cards on the left, the flow on the right ---------- */
.hero-split { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,380px); gap: 48px; }
.hero-copy { min-width: 0; }
/* Two cards side by side; the hero column is narrower than the page, so the
   three-across default would squeeze them. */
.tasks { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
.task-slot { display: flex; flex-direction: column; }
.task-slot .task { height: 100%; }

/* Supported browsers, under the card they belong to. Not the avatar stack:
   overlapping four round marks by 12px turns them into one illegible blob. */
.browsers {
  list-style: none; display: flex; gap: 8px;
  margin: 10px 0 0; padding: 0 0 0 2px;
}
.browsers li {
  width: 26px; height: 26px; border-radius: 999px; overflow: hidden;
  box-shadow: 0 0 0 1px var(--line);
}
.browsers svg { width: 100%; height: 100%; display: block; }
@media (max-width: 620px) { .tasks { grid-template-columns: minmax(0, 1fr); } }

/* ---------- the stage: their cloud → your folder ----------
   A 9:16 frame, read as a screen rather than a diagram. Behind everything sits
   Suno's cloud, blurred out of focus, because that is where the library lives
   and not where you can reach it. Out of it come the records themselves —
   square artwork with the metadata that travels with it — flying towards the
   camera, and at the near end they tip over and drop into a Finder folder.
   Nothing here is scripted: six elements share one keyframe track with the
   phase shifted, so it costs a compositor and no JavaScript. */
.stage {
  position: sticky; top: 88px;
  width: 100%; max-width: 352px; margin-inline: auto;
  min-height: 520px; isolation: isolate;
  /* Not clipped. The cloud's 28px blur starts 16px from the top, so a clip
     cut it off in a straight line — invisible while there was a panel edge to
     hide behind, plain as day once the scene stood on the page. Nothing else
     reaches an edge: a cover spans the middle 43% of the width and never
     leaves the box vertically, so the glow was all the clip was still cutting. */
  /* The ribbon is measured in container units, so the stage has to be one. */
  container-type: size;
  perspective: 190cqw; perspective-origin: 50% 18%;
}

/* Suno's cloud, out of focus. The wordmark inside it is blurred less, so it is
   legible as a name and still plainly behind the glass. Its own container
   query unit sizes the word, because the frame is not the viewport. */
.stage-cloud {
  position: absolute; z-index: 0; left: 50%; top: 2.5%;
  width: 58cqw; translate: -50% 0; container-type: inline-size;
  display: grid; place-items: center;
  animation: cloud-drift 14s ease-in-out infinite alternate;
}
.stage-cloud svg { grid-area: 1 / 1; width: 100%; height: auto; display: block; }
.cloud-glow { filter: blur(28px); opacity: .62; }
.cloud-edge { filter: blur(4px); opacity: .55; }
.cloud-word {
  grid-area: 1 / 1; margin-top: -7%;
  font-size: 13.5cqw; font-weight: 700; letter-spacing: .17em; text-indent: .17em;
  color: rgb(255 255 255 / .62); filter: blur(1.4px);
  text-shadow: 0 2px 30px rgb(0 0 0 / .55);
}
@keyframes cloud-drift {
  from { transform: translate3d(-7px, 0, 0) scale(1) }
  to   { transform: translate3d(7px, -9px, 0) scale(1.04) }
}

/* The library on its way over.
 *
 * Fifteen covers share one keyframe track with the phase shifted by index, so
 * this costs a compositor and no JavaScript. Six are on screen at a time: a
 * card is only visible for part of its cycle and waits out the rest parked at
 * the top, which is what lets the pool be deeper than the panel.
 *
 * Everything spatial is in container units. The stage is fluid — a max width,
 * a sticky column, a mobile breakpoint — and a path in pixels lands in the
 * folder at exactly one size and overshoots at every other.
 */
.cov {
  position: absolute; z-index: 3; left: 50%; top: 6%;
  width: 43cqw; margin-left: calc(43cqw / -2);
  border-radius: 11px; overflow: hidden;
  box-shadow: var(--e-3), 0 0 0 1px var(--line-soft) inset;
  animation: cov-fly 12.9s linear infinite;
  animation-delay: calc(var(--n) * -.86s);
  opacity: 0; will-change: transform, opacity;
}
.cov img { display: block; width: 100%; height: auto; }

/* One line, one speed. Between the top and 42.7% there is deliberately no
   intermediate stop: two keyframes and a linear timing function give a descent
   that cannot stutter.
 *
 * Z never turns positive. A card that crosses the camera plane paints in front
 * of the folder however the z-indexes read, so everything arrives from behind
 * and tips away out of sight under the front flap.
 *
 * The card is invisible for the first fifth of its descent. Fading up any
 * earlier puts it level with the wordmark, and the covers look like they are
 * hatching out of the Suno logo. */
@keyframes cov-fly {
  0%     { opacity: 0; transform: translate3d(0, -3cqh, -363cqw) rotateX(-8deg) }
  11.7%  { opacity: 0 }
  16%    { opacity: 1 }
  42.7%  { opacity: 1; transform: translate3d(0, 54.5cqh, -71cqw) rotateX(-8deg) }
  48%    { opacity: .5; transform: translate3d(0, 60.5cqh, -59cqw) rotateX(30deg) }
  51.7%  { opacity: 0; transform: translate3d(0, 64.5cqh, -52cqw) rotateX(58deg) }
  /* Snapped back while invisible: the next turn starts from the top. */
  53.3%, 100% { opacity: 0; transform: translate3d(0, -3cqh, -363cqw) rotateX(-8deg) }
}



/* The floor the folder stands on, and the flash when something lands on it.
   One card lands every .86s — the cycle divided by the fifteen sharing it —
   and the offset is where in that beat the landing falls. */
.stage-floor {
  position: absolute; z-index: 0; left: 50%; bottom: 11%; width: 66%; height: 48px;
  translate: -50% 0; border-radius: 50%; pointer-events: none;
  background: radial-gradient(50% 50% at 50% 50%, rgb(120 190 255 / .55), transparent 72%);
  filter: blur(12px);
  opacity: .5;
}

/* The folder, drawn the way the Finder draws one. It sits above the records on
   purpose: what disappears behind the front flap has arrived, and that is the
   whole sentence this picture is making. */
.folder {
  position: absolute; z-index: 6; left: 50%; bottom: 8.5%; width: 57cqw;
  translate: -50% 0;
  filter: var(--drop-3);
}
.folder svg { width: 100%; height: auto; display: block; }
.fold-back  { fill: url(#fold-back-g); }
.fold-front { fill: url(#fold-front-g); }
.fold-lip   { fill: rgb(255 255 255 / .3); }

/* Both ends, named. Small, quiet, and the only text in the frame that is not
   travelling. */

@media (prefers-reduced-motion: reduce) {
  .stage-cloud { animation: none; }
  .stage-floor { opacity: .28; }
  /* Parked rather than removed: an empty panel would lose the picture.
     Sampled evenly off the same straight run the animation uses, from where a
     moving card first becomes visible — start at the path's own beginning and
     the top of the poster sits inside the wordmark. It stops short of the last
     position too, since a card held at the folder is simply hidden by it. */
  .cov:nth-of-type(1) { animation: none; opacity: 1; z-index: 3;
    transform: translate3d(0, 10.4cqh, -299cqw) rotateX(-8deg) }
  .cov:nth-of-type(2) { animation: none; opacity: 1; z-index: 4;
    transform: translate3d(0, 19.3cqh, -249cqw) rotateX(-8deg) }
  .cov:nth-of-type(3) { animation: none; opacity: 1; z-index: 5;
    transform: translate3d(0, 28.2cqh, -199cqw) rotateX(-8deg) }
  .cov:nth-of-type(4) { animation: none; opacity: 1; z-index: 6;
    transform: translate3d(0, 37.1cqh, -149cqw) rotateX(-8deg) }
  .cov:nth-of-type(5) { animation: none; opacity: 1; z-index: 7;
    transform: translate3d(0, 46cqh, -100cqw) rotateX(-8deg) }
  .cov:nth-of-type(n+6) { display: none }
}

@media (max-width: 980px) {
  .hero-split { grid-template-columns: 1fr; gap: 32px; }
  .stage { position: static; }
  .tasks { max-width: none; }
}

/* One panel, one stroke, three surfaces. Nothing is inset: the shelf runs to
   the panel's own edges and is clipped by its radius, so the lighter block
   fills the bottom-left corner instead of floating inside a margin. */

/* Free vs Pro — Counter's .plan, with ticks and crosses drawn as strokes. */
.plan-list svg { fill: none; stroke: currentColor; stroke-width: 2.1;
  stroke-linecap: round; stroke-linejoin: round; flex: none; }
.plan-list .cross { stroke-width: 1.9; }
.plan-body .price .per { font-size: 16px; color: var(--ink-3); letter-spacing: 0; }
.plan.featured .plan-body .price .per { color: oklch(100% 0 0 / .55); }
.plan.featured .plan-top { background-image: var(--grad); }
/* The one thing about Pro that is a limit rather than a feature. It is painted
   in the card's own accent instead of the muted grey this slot usually carries,
   and it sits by the price rather than as the last tick in the list, because a
   buyer who misses it discovers it as a refusal: the server binds the first
   Suno account a licence relays and answers a second with a 409. */
.plan.featured .plan-body .from-lock {
  background-image: var(--grad);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; font-weight: 600; letter-spacing: -.005em;
}
.plan-body .btn { margin-top: auto; width: 100%; }

/* Stands in for the Free CTA when the grabber is switched off: the same box,
   so the two cards keep their footing, but dashed and unlit — plainly a label
   rather than something to press. Shown by flags.css, never by this file. */
.plan-note { display: none; margin-top: auto; width: 100%; min-height: 44px;
  align-items: center; justify-content: center;
  border: 1px dashed var(--line-firm); border-radius: var(--r-pill);
  color: var(--ink-3); font-size: 17.3px; font-weight: 500;
  letter-spacing: -0.008em; }

/* Touch targets: Design.md asks for 44px, and 46px below 720. The chip has no
   box of its own now, so the room goes above and below the label. */
@media (max-width: 720px) {
  .browsers li { width: 30px; height: 30px; }
}

/* ---------- the download limits ----------
   The one place the accent covers a whole surface instead of a control.

   A scrim sits over the gradient. White on the raw orange end is about 2.9:1,
   which is not a contrast anyone should have to squint at; a fifth of black
   over the top keeps it unmistakably the same sunset and lets the small text
   clear 4:1. The hue is the point, the exact luminance is not. */
.band-deadline{position:relative;border-top:0;color:#fff;padding:clamp(40px,4.4vw,56px) 0;
  background-image:linear-gradient(rgba(28,6,0,.20),rgba(28,6,0,.20)),var(--grad)}
/* Inside it every ink token is white — the children go on reading their own
   variables and none of them has to know it is standing on the accent. */
.band-deadline{--ink-1:#fff;--ink-2:rgba(255,255,255,.90);--ink-3:rgba(255,255,255,.80);
  --line-soft:rgba(255,255,255,.22)}
/* The band is one screenful of argument, so it is kept short: a headline you
   read in one go, a sentence under it, what a download costs past the
   allowance, and the three cards. */
.deadline{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:clamp(22px,2.6vw,40px) clamp(28px,4vw,72px);align-items:start}
.deadline-side{display:flex;flex-direction:column;gap:clamp(16px,1.8vw,24px)}
.deadline-copy h2{margin:8px 0 12px;font-size:clamp(32px,4vw,58px);line-height:1.04;
  letter-spacing:-.035em;text-wrap:balance}
.deadline-copy .lede{margin:0;max-width:44ch}

/* The three allowances, one card each, across the foot of the band. Side by
   side they are compared rather than read down a list, and the cards are the
   kit's — only the surface is restated, because on the accent a paper card
   would be a hole punched in the gradient. Everything else, the radius, the
   padding and the hairline, comes from .card and from the band's own tokens. */
/* Whose plans the row below belongs to.  Free, Pro and Premier are our own
   words for our own plans too, so the row is captioned rather than left to be
   read as a price list of ours. */
.tiers-head{grid-column:1/-1;margin:clamp(4px,.8vw,10px) 0 -6px;
  font-size:15px;font-weight:600;color:var(--ink-1)}
.tiers{list-style:none;margin:0;padding:0;grid-column:1/-1;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.tiers .card{background:oklch(100% 0 0 / .10);padding:18px 20px;
  display:flex;flex-direction:column;gap:12px}

.tier-head{margin:0;display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.tier-head b{font-size:clamp(28px,2.6vw,38px);font-weight:400;letter-spacing:-.03em;
  line-height:1;font-variant-numeric:tabular-nums;color:var(--ink-1)}
/* The tier is the noun; the period it covers is the qualifier, and it waits
   at the foot of the card so every card ends on the same line. */
.tier-head em{font-style:normal;font-weight:600;font-size:16px;color:var(--ink-1)}
.tier-note{font-size:13.8px;color:var(--ink-3)}

/* The allowance, drawn as the thing it counts: one square is one track.
   Every card carries the same field — sixty places, twenty across, which is a
   month of Premier — and lights up the part its tier is given. One row is a
   month of Pro; Free never fills half a row and will not be given another.
   Same pitch, same left edge, three cards: the ratio is legible without
   anyone counting a single square, and the unlit places are the plain
   statement of what the tier does not get.
   No colour is available here to carry this: the band stands on the accent
   already, so the figure is built out of white and shape alone.
   The field is measured in columns, not pixels: twenty across the card at
   whatever the card happens to be, so it can never outgrow the box it is
   drawn in and the three fields stay the same size as each other. */
.tier-count{position:relative;--pv:clamp(11px,1vw,14px);
  width:min(240px,100%);height:calc(3 * var(--pv));margin-bottom:auto}
.tier-count::before,.tier-count::after{content:"";position:absolute;left:0;top:0}
.tier-count::before{width:100%;height:100%;background-size:5% var(--pv);
  background-image:radial-gradient(circle at 50% 50%,
    rgba(255,255,255,.26) 0 30%, transparent 31%)}
.tier-count::after{width:calc(var(--cols) * 5%);height:calc(var(--rows) * var(--pv));
  background-size:calc(100% / var(--cols)) var(--pv);
  background-image:radial-gradient(circle at 50% 50%,
    rgba(255,255,255,.95) 0 30%, transparent 31%)}
.tier-free{--cols:7;--rows:1}
.tier-pro{--cols:20;--rows:1}
.tier-premier{--cols:20;--rows:3}

.deadline-act{display:flex;flex-direction:column;align-items:center;gap:14px}
/* White on the gradient: the accent is the ground here, so the button cannot
   also be the accent. It is the only filled thing on this band. */
.btn-invert{background:#fff;color:#1a1a1a;border:0}
.btn-invert:hover{background:rgba(255,255,255,.9);color:#1a1a1a}
.btn-xl{font-size:clamp(17px,1.6vw,21px);font-weight:600;padding:clamp(16px,1.6vw,22px)
  clamp(26px,3vw,42px);border-radius:999px;letter-spacing:-.01em}

/* It sits under the sentence it is the evidence for now, and that column is an
   ordinary block rather than the flex one it used to live in — so the space
   above it is its own rather than inherited from a `gap`. inline-block so the
   underline is the width of the words and not of the column. */
.deadline-source{display:inline-block;margin-top:clamp(14px,1.4vw,20px);
  font-size:14.5px;color:#fff;text-decoration:underline;
  text-underline-offset:4px;text-decoration-thickness:1px;
  text-decoration-color:rgba(255,255,255,.5)}
.deadline-source:hover{text-decoration-color:#fff}

/* What Suno charges once the allowance is gone. A price list, not a card to
   buy from: it sits on the accent in the same white the rest of the band uses,
   with the rows separated by a hairline rather than boxed one by one. */
.extras{background:oklch(100% 0 0 / .10);border:1px solid var(--line-soft);
  border-radius:16px;padding:clamp(16px,1.6vw,22px)}
.extras-head{margin:0 0 12px;font-size:15px;font-weight:600;color:var(--ink-1);
  text-wrap:balance}
.extras-list{list-style:none;margin:0;padding:0}
.extras-list li{display:flex;align-items:baseline;justify-content:space-between;
  gap:16px;padding:9px 0;border-top:1px solid var(--line-soft)}
.extras-list li:first-child{border-top:0}
.extras-list span{font-size:15px;color:var(--ink-2)}
.extras-list b{font-size:clamp(17px,1.5vw,21px);font-weight:400;letter-spacing:-.02em;
  color:var(--ink-1);font-variant-numeric:tabular-nums}
.extras-note{margin:12px 0 0;font-size:13.5px;color:var(--ink-3)}

.countdown-clock{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(4px,.8vw,12px)}
.countdown .unit{display:flex;flex-direction:column;align-items:center;gap:4px}
.countdown .unit b{font-size:clamp(42px,5.6vw,84px);font-weight:400;line-height:.95;
  letter-spacing:-.05em;font-variant-numeric:tabular-nums;color:#fff}
.countdown .unit span{font-size:clamp(11px,.9vw,13px);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3)}
.countdown-said{margin:10px 0 0;font-size:14.5px;color:var(--ink-3);text-align:center}
/* Past the date the digits are all zero and the gradient reads as decoration. */
.countdown.is-past .unit b{color:rgba(255,255,255,.62)}

@media (max-width:900px){
  .deadline{grid-template-columns:minmax(0,1fr);gap:28px}
  .countdown-said{text-align:left}
  .deadline-side{gap:24px}
}
/* The field narrows with the card, so the three columns hold well past the
   point where a fixed grid of squares would have burst out of them. They give
   way on a phone, where twenty columns would be twenty specks. */
@media (max-width:1000px){
  .tiers{gap:12px}
  .tiers .card{padding:16px}
}
@media (max-width:720px){
  .tiers{grid-template-columns:minmax(0,1fr);gap:10px}
  .tiers .card{padding:16px 18px}
  .tier-count{margin-bottom:0}
}
/* A clock is read along one line: four boxes stacked two by two stop being a
   clock and become a table the eye has to reassemble, and on a phone that
   table pushed the button that follows it off the screen. Below 520 the
   digits give up their size rather than the row giving up its shape. */
@media (max-width:520px){
  .countdown-clock{gap:6px}
  .countdown .unit b{font-size:clamp(30px,9vw,44px)}
  .countdown .unit span{font-size:10px;letter-spacing:.06em;white-space:nowrap}
}

/* Signing in is a dialog, not a page, so the footer's entry is a button. It
   borrows the column's link styling rather than inventing a second look. */
.foot-link { border: 0; background: none; padding: 0; font: inherit; font-size: 16.1px;
  color: var(--ink-2); cursor: pointer; width: fit-content; text-align: left; }
.foot-link:hover { color: var(--ink-1); }

/* The browser marks and the one-line promise share a row under the cards. */
.hero-foot { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 16px; }
.hero-foot .under { margin: 0; }
.hero-foot .browsers { margin: 0; }
@media (max-width: 620px) { .hero-foot { gap: 10px; } }

/* ---------- sign-in, as a sheet over the page ---------- */
.sheet-scrim[hidden]{display:none}
/* The same trap as .methods above. .banner in counter.css sets display:flex, so
   signin.js writing loggedNote.hidden = true did nothing and the "no mail
   server" warning stood on the code step whether or not the code had been
   mailed. The attribute is the whole of how that note is governed. */
.banner[hidden]{display:none}
.sheet-scrim{position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:20px;
  background:oklch(8% 0 0 / .62);backdrop-filter:blur(3px)}
.sheet-card{position:relative;width:100%;max-width:440px;background:var(--paper-2);
  border:1px solid var(--line-soft);border-radius:var(--r-media);box-shadow:var(--e-3);
  padding:26px}
.sheet-head{display:flex;align-items:center;gap:12px;margin-bottom:18px}
.sheet-head h2{margin:0;font-size:25px;font-weight:500;letter-spacing:-.02em}
.sheet-head .mark-glyph{width:22px;height:22px;border-radius:999px;flex:none}
.sheet-x{margin-left:auto;background:none;border:0;color:var(--ink-3);cursor:pointer;
  padding:6px;border-radius:999px;line-height:0}
.sheet-x:hover{color:var(--ink-1);background:oklch(100% 0 0 / .06)}
.sheet-x svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;display:block}
.sheet-note{margin:0 0 16px;font-size:15px;line-height:1.5;color:var(--ink-2)}
.sheet-note b{color:var(--ink-1);font-weight:500}
.sheet-back{margin:14px 0 0;text-align:center;font-size:14px}
.sheet-back button{background:none;border:0;color:var(--ink-2);cursor:pointer;font:inherit}
.sheet-back button:hover{color:var(--ink-1)}
.sheet-legal{margin:20px 0 0;padding-top:16px;border-top:1px solid var(--line-soft);
  text-align:center;font-size:12.5px;color:var(--ink-4);line-height:1.5}
.sheet-legal a{color:var(--ink-3)}
@media (max-width:480px){.sheet-card{padding:20px}}

/* ---------- legal pages --------------------------------------------------- */
/* Terms, refunds and privacy share one narrow column. Headings sit close to
   the paragraph they open and far from the one they close, so the sections
   read as sections without any rules drawn between them. */
.legal { display:flex; flex-direction:column; gap:16px; max-width:68ch; margin-top:36px }
.legal h2 { font-size:22px; font-weight:600; letter-spacing:-.012em; margin:24px 0 -4px }
.legal h2:first-child { margin-top:0 }
.legal p { margin:0 }
.legal ul { margin:0; padding-left:22px; display:flex; flex-direction:column; gap:8px }
.legal li { font-size:18.4px; line-height:1.55 }
.legal-meta { font-family:var(--t-mono); font-size:13.5px; color:var(--ink-4);
  margin:14px 0 0; letter-spacing:.01em }
/* The kit's links carry no underline, which is fine in a nav and useless in a
   paragraph. Here a cross-reference to another policy has to look like one. */
.legal a { text-decoration:underline; text-decoration-color:var(--line-firm) }
.legal a:hover { text-decoration-color:currentColor }

/* ---------- footer -------------------------------------------------------- */
/* The kit draws a hairline above the footer. Here the band change already
   marks the edge, so the line only reads as a stray stripe. */
.foot { border-top: 0 }
/* Legal links in the base row: the same mono as the copyright beside them,
   because a link there is a sibling of that line, not a call to action. */
.foot-base a:not(.mark) { color:var(--ink-3); text-decoration:none }
.foot-base a:not(.mark):hover { color:var(--ink-1) }

/* Fourth column: install, then the channels where the app gets promoted. */
.foot-get b { margin-bottom: 10px }
.store-btn { display:inline-flex; align-items:center; gap:10px; width:fit-content;
  padding:9px 15px 9px 12px; border-radius:var(--r-pill); border:1px solid var(--line-firm);
  font-size:14.5px; font-weight:500; line-height:1.15; color:var(--ink-1); text-decoration:none;
  transition:background .18s var(--ease-out),border-color .18s var(--ease-out) }
.store-btn:hover { background:var(--paper-2); border-color:var(--ink-3); text-decoration:none }
.store-btn svg { width:20px; height:20px; flex:none }
.store-btn i { display:block; font-style:normal; font-size:11px; font-weight:500;
  letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3); margin-top:2px }

.socials { list-style:none; display:flex; gap:8px; margin:16px 0 0; padding:0 }
.socials a { display:grid; place-items:center; width:38px; height:38px; border-radius:999px;
  border:1px solid var(--line); color:var(--ink-2);
  transition:color .18s var(--ease-out),border-color .18s var(--ease-out) }
.socials a:hover { color:var(--ink-1); border-color:var(--line-firm) }
.socials svg { width:19px; height:19px }

@media (max-width:1024px){ .foot-cols{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:560px){ .foot-cols{grid-template-columns:minmax(0,1fr)} }


/* ---------- the cabinet's first screen ------------------------------------
   An account with no backups yet used to get an empty folder icon, which
   answers none of the questions someone has one second after signing in:
   what do I do, where do the files land, and what does the paid part buy.
   So the empty state is the instructions — three steps on the left, and the
   one thing that is not free on the right. */
/* The eyebrow over the heading is somebody's email address: one unbreakable
   word carrying .14em of letter-spacing, which walks straight out of the
   column on a phone. */
main.band .section-head .eyebrow { overflow-wrap: anywhere; }

.onboard { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 40px 48px; align-items: start; }
.onboard-steps { gap: 26px; }
.onboard-steps .btn { margin-top: 14px; }
/* Where the files end up is the sentence people came for, so it is not left
   inside a paragraph to be found. */
.onboard-steps .onboard-note { display: flex; align-items: flex-start; gap: 10px;
  margin: 12px 0 0; padding: 12px 14px; border-radius: var(--r-inner);
  background: var(--paper-2); font-size: 15.5px; line-height: 1.5; color: var(--ink-2); }
.onboard-steps .onboard-note svg { width: 18px; height: 18px; margin-top: 1px; flex: none; opacity: .7; }

/* The paid half, said once and plainly: a card, a price-shaped promise and
   one button that is bigger than anything else on the page. */
.onboard-pro { padding: 28px; border: 1px solid var(--line);
  border-radius: var(--r-card); background: var(--paper-2); position: sticky; top: 118px; }
.onboard-pro h3 { margin: 8px 0 0; font-size: 25px; font-weight: 500; letter-spacing: -0.018em; }
.onboard-pro p { margin: 10px 0 0; font-size: 16.7px; line-height: 1.55; color: var(--ink-2); }
.onboard-pro .btn-lg { width: 100%; margin-top: 22px; }
.onboard-free { display: block; margin-top: 14px; font-size: 15.5px; color: var(--ink-3);
  text-align: center; text-decoration: underline;
  text-decoration-color: var(--line-firm); }
.onboard-free:hover { color: var(--ink-1); text-decoration-color: currentColor; }

/* One column on a laptop's smaller sibling, and the sticky rail lets go: a
   card that follows the scroll of a page one screen tall is just in the way. */
@media (max-width: 900px) {
  .onboard { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .onboard-pro { position: static; }
}
@media (max-width: 520px) {
  .onboard-pro { padding: 22px; }
  .onboard-steps li { grid-template-columns: 32px minmax(0, 1fr); gap: 14px; }
}

/* The one card on the page that is the next step rather than a surface.
   `.task-pro` already tints only its icon, which is right for a second choice;
   this one carries the gradient outright, because a first visit that reads the
   headline has exactly one thing to do next and it was competing on equal
   terms with Pro. Text is set explicitly rather than inherited: the gradient
   is dark enough at the orange end that --ink-1 would not hold in light mode. */
/* The origin goes here rather than with the other gradient surfaces above:
   `.task` sets `background:` as a shorthand further down the file, and a
   shorthand resets the origin to padding-box. Same specificity, later rule. */
.task-accent{background-image:var(--grad);background-origin:border-box;
  border-color:transparent;color:#fff}
.task-accent:hover{border-color:transparent;filter:brightness(1.06)}
.task-accent .task-body b{color:#fff}
.task-accent .task-body i{color:rgba(255,255,255,.82)}
.task-accent .task-ico{background:rgba(255,255,255,.18);color:#fff}

/* ---------- install page: the store first, the zip after ---------- */
/* `.masthead .cta` is a wrapping flex row and already starts at the left; this
   only says so out loud, because these two blocks are read as a sequence and a
   later change to the row's justification must not silently centre them. */
.cta-left { justify-content: flex-start; }

/* The store button at the weight of a primary action. It keeps the footer's
   shape — a bordered pill with the browser mark — rather than taking the
   gradient: the gradient on this site means "the thing we are selling", and
   installing is free. */
.store-btn-lg { padding: 13px 22px 13px 18px; font-size: 16.5px; gap: 12px; }
.store-btn-lg svg { width: 24px; height: 24px; }
.store-btn-lg i { font-size: 11.5px; margin-top: 3px; }

/* The zip is a section, not a sibling of the store button, so its heading sits
   at section weight with room above it. */
.install-h2 { font-size: 21px; font-weight: 600; margin: 0 0 10px; }

/* The site-wide notice. .banner in counter.css carries the colours and the
   themes; these two rules only put the strip above everything else on the page
   and give its close button a hit area. */
.alert-strip { padding: 12px 0 0; }
.alert-close {
  border: 0; background: transparent; color: inherit; cursor: pointer;
  font-size: 20px; line-height: 1; padding: 4px 8px; border-radius: 8px;
}
.alert-close:hover { background: color-mix(in oklab, currentColor 12%, transparent); }

/* ---------- the cabinet's notices and the state of somebody's Pro ----------
   Two shapes, and the warning one carries the sentence this product owes
   everybody who pays for it: SunoSync reads Suno through an interface Suno
   does not publish. That belongs above the fold on the page people come back
   to, not folded into a footer nobody opens — so it is styled to be read
   rather than dismissed, and it is not dismissible. */
.notice { display: flex; gap: 14px; align-items: flex-start; margin: 0 0 24px;
  padding: 18px 20px; border-radius: var(--r-card); border: 1px solid var(--line);
  background: var(--paper-2); }
.notice svg { width: 20px; height: 20px; flex: none; margin-top: 2px; opacity: .85; }
.notice b { display: block; font-weight: 600; color: var(--ink-1); font-size: 15.5px; }
.notice p { margin: 8px 0 0; font-size: 15px; line-height: 1.6; color: var(--ink-2); }
.notice p + p { margin-top: 10px; }
/* Warm rather than red. The thing being described is a real risk and not an
   error, and an error colour on a page somebody opens every week stops being
   read by the third visit. */
.notice-warn { border-color: color-mix(in oklab, var(--warn, #d98324) 45%, var(--line));
  background: color-mix(in oklab, var(--warn, #d98324) 7%, var(--paper-2)); }
.notice-warn svg { color: var(--warn, #d98324); }
.notice-ok { border-color: color-mix(in oklab, var(--ok, #2f9e63) 40%, var(--line));
  background: color-mix(in oklab, var(--ok, #2f9e63) 6%, var(--paper-2)); }

/* The line that says what Pro is doing, with its one control at the far end —
   the same edge every other control on this page sits on. */
.pro-state { display: flex; align-items: center; justify-content: space-between;
  gap: 20px; margin: 0 0 28px; padding: 20px 22px;
  border: 1px solid var(--line); border-radius: var(--r-card); background: var(--paper-2); }
.pro-state h3 { margin: 6px 0 0; font-size: 20px; font-weight: 500; letter-spacing: -0.014em; }
.pro-state p { margin: 8px 0 0; font-size: 15px; line-height: 1.55; color: var(--ink-2);
  max-width: 62ch; }
.pro-state form { flex: none; }
/* The free state's Get Pro is a link, not a form — same slot, same rule. */
.pro-state > .btn { flex: none; }
@media (max-width: 620px) {
  .pro-state { flex-direction: column; align-items: stretch; }
  .pro-state form, .pro-state .btn { width: 100%; }
}
