/* The withsunny.co homepage (Figma 341:2 desktop, 348:2 phone). The About
   draft and the tools pages' header and footer (apps/tools/marketing-shell.ts)
   read this sheet too.
   Layout: 1248px content column with 96px margins at 1440; the live room runs
   the window's full width under the hero, everything else sits on the column.

   The order pictures read finished without JavaScript: home.js rewinds them,
   then plays each as it comes into view.

   Type: the Figma file sets headlines in CC Timeline Mid and text in CC
   Timeline, which we only have as a trial. The page uses TikTok Sans (the
   live site's face) for both, narrowed a little for headlines so they sit
   close to Timeline's widths. Swap the --font-* tokens when the licence
   lands. Eyebrows stay in Sunny Marker; the wordmark is a drawing
   (img/sunny-wordmark.svg, Figma 279:429). */

@font-face {
  font-family: "TikTok Sans";
  src: url("/fonts/TikTokSans-Variable-latin.woff2") format("woff2");
  font-weight: 300 900;
  /* The font's slant axis (0 to -6). Declaring it lets em and i use the
     real oblique below instead of a browser-slanted fake italic. */
  font-style: oblique 0deg 6deg;
  font-display: swap;
}

@font-face {
  font-family: "Sunny Marker";
  src: url("/fonts/sunny-marker/webfonts/SunnyMarker-Variable-1.313.woff2") format("woff2");
  font-weight: 300 700;
  font-stretch: 75% 125%;
  font-display: swap;
}

:root {
  color-scheme: light;

  /* Color (Figma "Sunny color" variables) */
  --ink: #000;
  --ink-soft: #6f6c65;
  --ink-faint: #a9a59c;
  --ink-inverse: #fff;
  --paper: #f5f3ee;
  --card: #fff;
  --room: #f1f3f4; /* the room embed paints this exact color */
  --stroke: #e7e4dd;
  --well: #eeebe4; /* the ground under the order pictures */
  --live: #1f7a45;
  --live-fill: #2fae5f;
  --flag: #b4690e;
  --flag-bg: #fbf1e2;
  --live-bg: color-mix(in srgb, var(--live-fill) 14%, var(--card));

  /* Type */
  --font-display: "TikTok Sans", system-ui, sans-serif;
  --font-text: "TikTok Sans", system-ui, sans-serif;
  --font-marker: "Sunny Marker", "TikTok Sans", cursive;
  --display-wght: 800;
  --display-wdth: 92;
  --display: clamp(2.75rem, 1.1rem + 4.4vw, 4.75rem); /* 76px at 1440, 44px on phones */
  --headline: clamp(2rem, 1rem + 2.9vw, 3.5rem); /* 56px at 1440, 32px on phones */
  --price: clamp(1.625rem, 1rem + 1.7vw, 2.5rem); /* 40px at 1440, 26px on phones */
  --lede: clamp(1.125rem, 1rem + 0.45vw, 1.375rem);
  --step-title: 1.375rem;
  --card-title: 1.22rem;
  --body: 1.17rem;
  --body-small: 1.0625rem;
  --caption: 1.03rem;
  --label: 0.94rem;
  --chip: 0.84rem;

  /* Layout */
  --gutter: clamp(20px, 6.667vw, 96px);
  --content: 1248px;
  --radius-card: 18px;
  --radius-panel: 28px;

  /* Motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  font-variation-settings: "wdth" 100;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--card);
  color: var(--ink);
  font-family: var(--font-text);
  font-weight: 450;
  font-size: var(--body);
  line-height: 1.3;
  overflow-x: hidden;
}

/* TikTok Sans has no italic, only a slant axis. Asking for italic would
   stack a fake slant on the real one, so emphasis asks for the oblique. */
em,
i,
cite {
  font-style: oblique 6deg;
}

img {
  max-width: 100%;
  display: block;
}

h1,
h2,
h3,
p,
ol,
ul,
figure {
  margin: 0;
}

ol,
ul {
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.wrap {
  width: 100%;
  max-width: calc(var(--content) + 2 * var(--gutter));
  margin-inline: auto;
  padding-left: max(var(--gutter), env(safe-area-inset-left, 0px));
  padding-right: max(var(--gutter), env(safe-area-inset-right, 0px));
}

/* ---------- type roles ---------- */

.display,
.headline,
.price strong {
  font-family: var(--font-display);
  font-weight: var(--display-wght);
  font-variation-settings: "wdth" var(--display-wdth);
  letter-spacing: -0.02em;
  line-height: 1;
  text-wrap: balance;
}

.display {
  font-size: var(--display);
}

.headline {
  font-size: var(--headline);
}

.eyebrow {
  font-family: var(--font-marker);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1.3;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* The wordmark is an image sized by height, so it scales with its slot. */
.wordmark {
  display: block;
  width: auto;
  height: 23px;
}

/* ---------- buttons, capsule ---------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  height: 46px;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  font: inherit;
  font-weight: 600;
  font-size: 1.125rem;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.button-ink {
  background: var(--ink);
  color: var(--ink-inverse);
}

.capsule {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 520px;
  height: 66px;
  padding: 6px;
  border: 1.5px solid var(--stroke);
  border-radius: 999px;
  background: var(--card);
}

.capsule input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding: 0 0 0 18px;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: var(--caption);
  color: var(--ink);
}

.capsule input::placeholder {
  color: var(--ink-soft);
}

.capsule input:focus {
  outline: none;
}

.capsule:focus-within {
  border-color: var(--ink);
}

.capsule .button {
  height: 100%;
  padding: 0 22px;
}

.form-note {
  min-height: 1.4em;
  margin-top: 10px;
  font-size: var(--label);
  color: var(--ink-soft);
}

/* A bad address or a failed signup. --flag alone is too light for small text
   on paper, so it's darkened here; the black card uses it as is. */
.form-note.error {
  color: color-mix(in srgb, var(--flag) 75%, var(--ink));
}

/* ---------- nav ---------- */

.nav {
  display: flex;
  align-items: center;
  gap: 16px;
  height: 96px;
}

.brand {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--ink);
  text-decoration: none;
}

/* The bar sits at the top of the page and scrolls away with it. It carries
   the wordmark alone, since Bright is in the headline. */
.nav-bar {
  background: var(--card);
}

@media (prefers-reduced-motion: no-preference) {
  .nav .wordmark {
    animation: wordmark-rise 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.1s backwards;
  }
}

@keyframes wordmark-rise {
  from {
    opacity: 0;
    translate: 0 14px;
  }
}

.nav-links {
  display: flex;
  gap: 36px;
  margin-left: auto;
  margin-right: 32px;
}

.nav-links a {
  font-size: 1.125rem;
  color: var(--ink-soft);
  text-decoration: none;
}

.nav-links a:hover {
  color: var(--ink);
}

/* ---------- hero ---------- */

/* Bright, inline (Figma 275:249, after Muse's hero): the box holds the gap
   between "Sunny" and "makes", and the render, sunbeams and all, is 1.55em
   and spills past the box behind the words on either side. It is the
   look-left pose mirrored to face the claim and tilted 16 degrees. */
.title-bright {
  position: relative;
  display: inline-block;
  width: 0.64em;
  height: 0.72em;
  /* The mirrored sun sits right of centre, so "makes" gets one extra word
     space to read as a normal gap. */
  margin-inline: -0.03em 0.15em;
  vertical-align: baseline;
}

.title-bright img {
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 50%;
  width: 1.55em;
  max-width: none;
  height: auto;
  margin: -0.775em 0 0 -0.775em;
  rotate: 16deg;
  scale: -1 1;
}

/* Bright comes up like the sun it is, then bobs. The entrance keeps the
   mirror in its scale; the bob rides on transform. */
@media (prefers-reduced-motion: no-preference) {
  .title-bright img {
    animation:
      bob 6s ease-in-out infinite,
      sun-up 1s cubic-bezier(0.22, 1, 0.36, 1) 0.15s backwards;
  }
}

@keyframes sun-up {
  from {
    opacity: 0;
    translate: 0 40%;
    scale: -0.72 0.72;
  }
}

@keyframes bob {
  50% {
    transform: translateY(-3px) rotate(-1.5deg);
  }
}

.lede {
  max-width: 560px;
  margin-top: 28px;
  font-size: var(--lede);
  line-height: 1.4;
  color: var(--ink-soft);
}

.lede strong {
  font-weight: 450;
  color: var(--ink);
}

.hero {
  padding-block: 40px 0;
}

.hero-title {
  /* Bright's glow paints behind the letters, never over them. */
  isolation: isolate;
  max-width: 940px;
  margin-top: 16px;
}

/* The lede on the left, the signup on the right, centred on each other. */
.hero-intro {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 48px;
  margin-top: 32px;
}

.hero-intro .lede {
  margin-top: 0;
}

.hero-signup {
  position: relative;
  flex: 0 1 520px;
}

.hero-signup .form-note {
  position: absolute;
  top: 100%;
  left: 24px;
}

/* ---------- live room ---------- */

/* No card: the stage clips the embed on the band's own color, its edges faded
   so the floor glow never ends in a hard line. The frame and poster run 72px
   past the bottom to clip the embed's reset button. */
.room-stage {
  --fade:
    linear-gradient(to right, transparent, #000 12%, #000 88%, transparent),
    linear-gradient(to bottom, transparent, #000 10%, #000 86%, transparent);
  position: relative;
  aspect-ratio: 1000 / 851;
  overflow: hidden;
  -webkit-mask-image: var(--fade);
  -webkit-mask-composite: source-in;
  mask-image: var(--fade);
  mask-composite: intersect;
}

.room-poster,
.room-frame {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: calc(100% + 72px);
  border: 0;
}

.room-poster {
  z-index: 1;
  object-fit: cover;
  transition:
    opacity 700ms ease,
    visibility 0s linear 700ms;
}

.room-cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: grab;
}

.room-configs {
  pointer-events: auto;
  display: inline-flex;
  gap: 4px;
  padding: 5px;
  border: 1.5px solid var(--stroke);
  border-radius: 999px;
  background: var(--card);
}

.room-configs button {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 42px;
  padding: 0 20px 0 6px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font: inherit;
  font-size: var(--label);
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

.room-configs button img {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: cover;
}

.room-configs button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--ink-inverse);
}

.room-configs[aria-disabled="true"] button {
  cursor: default;
}

.room-configs[aria-busy="true"] [aria-pressed="true"] img {
  animation: pulse 1s ease-in-out infinite;
}

@keyframes pulse {
  50% {
    opacity: 0.4;
  }
}

.price {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.price strong {
  font-size: var(--price);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.price-meta {
  font-size: var(--body-small);
  color: var(--ink-soft);
}

/* The room runs the page's full width on the embed's own paint, fading in
   from the hero and out into the orders below. The options, the quote's
   lines and the total float in a column over the paint on the right. */
.band {
  --col: 300px;
  /* From the column's left edge to the band's right edge. */
  --side: calc(
    (100% - min(100%, var(--content) + 2 * var(--gutter))) / 2 + var(--gutter) + var(--col) + 32px
  );
  position: relative;
  margin-top: 56px;
  background: linear-gradient(
    var(--card),
    var(--room) 64px,
    var(--room) calc(100% - 64px),
    var(--paper)
  );
}

.band-room {
  position: relative;
  height: clamp(560px, 50vw, 800px);
}

.band .room-stage {
  --fade: linear-gradient(transparent, #000 64px, #000 calc(100% - 64px), transparent);
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  -webkit-mask-image: var(--fade);
  mask-image: var(--fade);
}

/* The frame runs 72px past the bottom to clip the embed's reset button, and
   under the column on the right; it reaches as far past the band's left
   edge, so the room, centred in its frame, centres in the space left of the
   column. */
.room-shift {
  position: absolute;
  top: 0;
  right: 0;
  bottom: -72px;
  left: calc(-1 * var(--side));
}

.band .room-poster,
.band .room-frame {
  height: 100%;
}

/* Scaled by height, as the embed frames the room, and centred. */
.band .room-poster {
  left: 50%;
  width: auto;
  max-width: none;
  object-fit: fill;
  translate: -50% 0;
}

.band-room.loaded .room-poster {
  opacity: 0;
  visibility: hidden;
}

/* With a mouse the room takes drags straight away, and the wheel still
   scrolls the page (the embed's follow mode). Touch screens get a cover, so
   a swipe over the room scrolls the page until the room is tapped. */
.band .room-cover {
  display: none;
}

@media (hover: none) {
  .band .room-cover {
    display: block;
  }
}

.band-room.live .room-cover {
  display: none;
}

/* The column. Only its controls take the pointer; drags anywhere else
   reach the room under it. */
.band-ui {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  pointer-events: none;
}

.band-side {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: var(--col);
}

.band-side .room-configs {
  align-self: flex-start;
}

/* One chip per view: the whole room, then each line of the quote. */
.pieces {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  /* Only matters once the row scrolls (under 1180px). It lives here so
     Blossom reads it even when the page opens wide. */
  scroll-snap-type: x mandatory;
}

/* With a mouse, Blossom (home.js) drags the row when it scrolls. It turns
   the snap off when it starts and hands it back through has-snap; snap
   pauses mid-drag so the row can coast. */
.pieces[has-snap="true"] {
  scroll-snap-type: var(--snap-type) !important;
}

.pieces[has-overflow="true"] {
  cursor: grab;
}

.pieces[has-overflow="true"]:active {
  cursor: grabbing;
  scroll-snap-type: none !important;
}

.pieces[blossom-carousel] * {
  -webkit-user-drag: none;
  user-select: none;
}

.piece {
  pointer-events: auto;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  grid-template-areas:
    "thumb name price"
    "thumb sub price";
  align-items: center;
  column-gap: 12px;
  row-gap: 1px;
  width: 100%;
  padding: 6px 16px 6px 6px;
  border: 0;
  border-radius: 16px;
  background: var(--card);
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.06),
    0 6px 16px -8px rgb(0 0 0 / 0.18);
  font: inherit;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
  transition:
    background-color 0.15s ease,
    color 0.15s ease,
    translate 0.2s var(--ease-out);
}

.piece:hover {
  translate: 0 -1px;
}

.piece[aria-pressed="true"] {
  background: var(--ink);
  color: var(--ink-inverse);
}

.piece:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.piece-thumb {
  grid-area: thumb;
  width: 40px;
  height: 40px;
  border-radius: 11px;
  background: var(--room);
  object-fit: cover;
}

.piece-name {
  grid-area: name;
  align-self: end;
  overflow: hidden;
  font-size: 0.9375rem;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.piece-sub {
  grid-area: sub;
  align-self: start;
  overflow: hidden;
  font-size: var(--chip);
  color: var(--ink-soft);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.piece[aria-pressed="true"] .piece-sub {
  color: rgb(255 255 255 / 0.65);
}

.piece-price {
  grid-area: price;
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.band-total {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  padding-left: 6px;
  /* A soft halo keeps the total readable when a close-up fills the room
     behind it. On the whole-room view it lands on the backdrop and vanishes. */
  text-shadow:
    0 0 12px var(--room),
    0 0 24px var(--room);
}

/* A status, not a button: check and words, no fill. */
.band-checked {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: var(--label);
  font-weight: 600;
  color: var(--live);
}

.check {
  display: grid;
  place-items: center;
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--live);
}

.check svg {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: var(--ink-inverse);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* A piece on its own stage (double-clicked in the room): its card takes the
   column's place, with arrows to the pieces either side on top, and the way
   back sits over the room, top left. */
.band-side[data-solo] {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  /* Hung from the top, level with the way back, so the arrows stay put
     while the card under them changes height. */
  align-self: flex-start;
  margin-top: 32px;
}

.band-side[data-solo] > :not(.piece-card) {
  display: none;
}

.piece-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  width: min(100%, 420px);
}

.piece-card[hidden] {
  display: none;
}

@media (prefers-reduced-motion: no-preference) {
  .piece-card {
    animation: piece-card-in 0.3s var(--ease-out);
  }

  /* Each step to another piece. */
  .piece-detail {
    animation: piece-detail-in 0.2s ease-out;
  }
}

@keyframes piece-card-in {
  from {
    opacity: 0;
    translate: 0 6px;
  }
}

@keyframes piece-detail-in {
  from {
    opacity: 0;
  }
}

/* It keeps its place while hidden, so the embed can frame the piece below
   it (home.js, sendSoloFrame). */
.room-back {
  position: absolute;
  /* Centred on the arrows' pill, which is 10px taller. */
  top: 37px;
  left: 0;
  right: 0;
  z-index: 2;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition:
    opacity 0.2s ease,
    visibility 0s 0.2s;
}

.band-room[data-solo] .room-back {
  visibility: visible;
  opacity: 1;
  transition: opacity 0.2s ease;
}

.piece-back {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 42px;
  padding: 0 20px 0 12px;
  border: 1.5px solid var(--stroke);
  border-radius: 999px;
  background: var(--card);
  font: inherit;
  font-size: var(--label);
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.piece-back:hover {
  border-color: var(--ink-faint);
}

.piece-back:focus-visible,
.piece-step:focus-visible,
.piece-link:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.piece-back svg,
.piece-step svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Previous, "3 of 9", next: the same pill as the quote options. */
.piece-pager {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px;
  border: 1.5px solid var(--stroke);
  border-radius: 999px;
  background: var(--card);
}

.piece-pager[hidden] {
  display: none;
}

.piece-step {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition:
    background-color 0.15s ease,
    scale 0.1s ease;
}

.piece-step:hover {
  background: var(--room);
}

.piece-step:active {
  scale: 0.94;
}

.piece-step svg {
  width: 20px;
  height: 20px;
}

.piece-pos {
  min-width: 64px;
  font-size: var(--label);
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.piece-detail {
  pointer-events: auto;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 20px;
  border-radius: var(--radius-card);
  background: var(--card);
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.06),
    0 6px 16px -8px rgb(0 0 0 / 0.18);
}

.piece-detail-name {
  font-size: var(--card-title);
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
}

.piece-detail-sub,
.piece-detail-size {
  font-size: var(--label);
  color: var(--ink-soft);
}

.piece-detail-sub:empty,
.piece-detail-size:empty {
  display: none;
}

.piece-detail-size {
  font-variant-numeric: tabular-nums;
}

.piece-detail-price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 8px;
  margin-top: 12px;
}

.piece-detail-price strong {
  font-size: 1.75rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.piece-detail-price span {
  font-size: var(--label);
  color: var(--ink-soft);
}

/* The chairs or finishes this piece can take; the one showing is ringed. */
.piece-swaps {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--stroke);
}

.piece-swaps[hidden] {
  display: none;
}

.swap-label {
  font-size: var(--label);
  color: var(--ink-soft);
}

.swap-label b {
  font-weight: 600;
  color: var(--ink);
}

.swap-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.swap-choice {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: var(--room);
  cursor: pointer;
  transition:
    box-shadow 0.15s ease,
    translate 0.2s var(--ease-out);
}

.swap-finish .swap-choice {
  width: 40px;
  height: 40px;
  border-radius: 50%;
}

.swap-choice img {
  width: 100%;
  height: 100%;
  border-radius: inherit;
  object-fit: contain;
}

.swap-finish .swap-choice img {
  object-fit: cover;
}

.swap-choice:hover {
  translate: 0 -1px;
}

.swap-choice[aria-pressed="true"] {
  box-shadow:
    0 0 0 2px var(--card),
    0 0 0 3.5px var(--ink);
}

.swap-choice:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 4px;
}

.piece-swaps[aria-busy="true"] [aria-pressed="true"] img {
  animation: pulse 1s ease-in-out infinite;
}

.piece-link {
  margin-top: 12px;
  font-size: var(--label);
  font-weight: 600;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--ink-faint);
  text-underline-offset: 3px;
}

.piece-link[hidden] {
  display: none;
}

.piece-link::after {
  content: " ↗";
}

/* ---------- orders ---------- */

.orders {
  padding-block: 112px;
  background: var(--paper);
}

.orders .headline {
  margin-top: 16px;
}

.orders-lede {
  max-width: 600px;
  margin-top: 24px;
  font-size: var(--lede);
  line-height: 1.4;
  color: var(--ink-soft);
}

.order-steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin-top: 64px;
}

.order-step {
  display: flex;
  flex-direction: column;
}

/* A picture's tile. The scene inside (/orders/orders.js) is drawn at the
   tile's own size and cut by its edge. */
.step-pic {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 24px;
  background: var(--well);
  overflow: hidden;
}

.step-title {
  margin-top: 24px;
  font-size: var(--step-title);
  font-weight: 600;
  line-height: 1.25;
}

.step-body {
  max-width: 24em;
  margin-top: 8px;
  font-size: var(--body-small);
  line-height: 1.45;
  color: var(--ink-soft);
  text-wrap: pretty;
}

/* ---------- how it works ---------- */

.how,
.faq {
  padding-block: 112px 0;
}

.how .headline {
  margin-top: 16px;
}

.how-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 40px minmax(0, 390px) 40px minmax(0, 1fr);
  align-items: start;
  gap: 18px;
  margin-top: 56px;
}

.how-col {
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-self: start;
}

.col-label {
  font-size: var(--caption);
  color: var(--ink-soft);
}

.how-arrow {
  align-self: center;
  margin-top: 40px;
  font-size: 1.75rem;
  text-align: center;
  color: var(--ink-faint);
}

.items {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.items li {
  display: flex;
  align-items: center;
  gap: 16px;
}

.items li > span:last-child {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--label);
  color: var(--ink-soft);
}

.items strong {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink);
}

.tile {
  display: grid;
  grid-template: 100% / 100%;
  place-items: center;
  flex: none;
  width: 54px;
  height: 54px;
  padding: 7px;
  border-radius: 14px;
  background: var(--paper);
}

.tile img,
.tile svg {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.tile .doc {
  fill: var(--card);
  stroke: var(--stroke);
  stroke-width: 1.5;
}

.tile .doc-line {
  stroke: var(--ink-faint);
  stroke-width: 1.6;
  stroke-linecap: round;
}

.tile .doc-tag {
  font: 700 5.5px var(--font-text);
  fill: var(--ink-soft);
}

.tile .ok-fill {
  fill: var(--live-fill);
}

.tile .ok-tick {
  fill: none;
  stroke: #0b3d1f;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tile .ai-back {
  fill: #2f8cf0;
}

.tile .ai-front {
  fill: #18b6f0;
  stroke: var(--paper);
  stroke-width: 1.5;
}

.tile .ai-plus {
  stroke: #0a3a66;
  stroke-width: 2;
  stroke-linecap: round;
}

.tile .quote-fill {
  fill: #f28b2c;
}

.tile .quote-dot {
  fill: #e5401f;
}

.tile .quote-ping {
  fill: #e5401f;
  stroke: var(--paper);
  stroke-width: 1.5;
}

.sunny-card {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 40px 32px;
  border-radius: var(--radius-panel);
  background: var(--paper);
  text-align: center;
}

.sunny-card img {
  width: 128px;
  height: 128px;
}

.sunny-card p {
  font-size: var(--step-title);
  font-weight: 600;
  line-height: 1.25;
  text-wrap: balance;
}

/* The middle card: Sunny knows your catalog. */

.knows-card {
  gap: 10px;
  padding: 36px 28px 32px;
}

/* A square room study with a product sketch and finish samples. Preserve
   its proportions and transparent shadow. Two classes outrank the generic
   .sunny-card img sizing. */
.sunny-card .knows-art {
  width: min(100%, 220px);
  height: auto;
  margin: -12px 0 2px;
}

.knows-card .knows-title {
  font-size: var(--step-title);
}

.knows-list {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  margin-top: 6px;
}

.knows-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--body-small);
  color: var(--ink-soft);
}

.knows-list li::before {
  content: "";
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--live)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='m5.5 10.4 3 3 6-6.6' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    center / 100% no-repeat;
}

/* The illustration can rise above the card on wide screens. Side lists
   keep their own row spacing instead of stretching to the card's height. */
@media (min-width: 1181px) {
  .knows-card {
    padding-top: 0;
  }

  .sunny-card .knows-art {
    margin-top: -60px;
  }
}

/* ---------- questions ---------- */

.faq-grid {
  display: grid;
  grid-template-columns: minmax(0, 400px) minmax(0, 1fr);
  align-items: start;
  gap: 96px;
}

.faq-intro {
  display: flex;
  flex-direction: column;
  gap: 13px;
}

.faq-note {
  margin-top: 24px;
  font-size: var(--label);
  color: var(--ink-soft);
}

.faq-note a {
  color: var(--ink);
  text-underline-offset: 3px;
}

.faq-list details {
  border-top: 1px solid var(--stroke);
}

.faq-list details:last-child {
  border-bottom: 1px solid var(--stroke);
}

.faq-list summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-block: 24px;
  font-size: var(--step-title);
  font-weight: 600;
  line-height: 1.3;
  cursor: pointer;
  list-style: none;
}

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

/* The toggle: a ring with a plus whose upright bar folds away when open. */
.faq-list summary::after {
  content: "";
  flex: none;
  width: 36px;
  height: 36px;
  border: 1.5px solid var(--stroke);
  border-radius: 50%;
  background:
    linear-gradient(var(--ink), var(--ink)) center / 13px 1.75px no-repeat,
    linear-gradient(var(--ink), var(--ink)) center / 1.75px 13px no-repeat;
  transition:
    transform 200ms ease,
    background-size 200ms ease,
    border-color 200ms ease;
}

.faq-list summary:hover::after {
  border-color: var(--ink-faint);
}

.faq-list details[open] summary::after {
  transform: rotate(180deg);
  background-size:
    13px 1.75px,
    1.75px 0;
}

.faq-list details p {
  max-width: 65ch;
  padding-bottom: 26px;
  font-size: var(--body-small);
  line-height: 1.45;
  color: var(--ink-soft);
}

@media (prefers-reduced-motion: no-preference) {
  .faq-list details[open] p {
    animation: reveal 220ms ease;
  }
}

@keyframes reveal {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

/* ---------- close ---------- */

.start {
  padding-block: 112px 0;
}

.cta-card {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding: 72px;
  border-radius: 30px;
  background: var(--ink);
  color: var(--ink-inverse);
}

.cta-copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 860px;
}

.cta-sub {
  font-size: var(--lede);
  color: var(--ink-faint);
}

.cta-card .capsule {
  margin-top: 26px;
  border: 0;
}

.cta-card .form-note {
  color: var(--ink-faint);
}

.cta-card .form-note.error {
  color: var(--flag);
}

.cta-bright {
  position: absolute;
  right: -110px;
  top: 50%;
  width: 300px;
  height: 300px;
  transform: translateY(-50%);
}

.dealer-line {
  margin-top: 32px;
  text-wrap: pretty;
  font-size: 1.25rem;
  color: var(--ink-soft);
}

.dealer-line a {
  color: var(--ink);
  text-decoration: none;
}

.dealer-line a:hover {
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* ---------- footer ---------- */

.site-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 32px;
  margin-top: 104px;
  padding-block: 48px;
  border-top: 2px solid var(--stroke);
}

.brand-small img {
  width: 36px;
  height: 36px;
}

.brand-small .wordmark {
  width: auto;
  height: 20px;
}

.copyright {
  font-size: 1rem;
  color: var(--ink-soft);
}

.foot-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 32px;
  margin-left: auto;
  font-size: 1rem;
}

.foot-links a {
  color: var(--ink-soft);
  text-decoration: none;
}

.foot-links a:hover,
.foot-links .foot-mail {
  color: var(--ink);
}

/* ---------- narrower screens ---------- */

@media (max-width: 1180px) {
  .how-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }

  .how-arrow {
    display: none;
  }

  .faq-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  /* Under 1181px the room is 3:2 and the column moves under it: the chips in
     a row that scrolls sideways, then the options and the total. */
  .hero {
    padding-block: 64px 0;
  }

  .band-room {
    height: auto;
  }

  .band-room::before {
    content: "";
    display: block;
    padding-top: calc(100% * 2 / 3);
  }

  .room-shift {
    left: 0;
  }

  .band .room-poster {
    left: 0;
    width: 100%;
    object-fit: cover;
    translate: none;
  }

  .room-back {
    top: 16px;
  }

  .band-side[data-solo] {
    margin-top: 0;
  }

  .band-ui {
    position: static;
    display: block;
    padding-block: 4px 80px;
    pointer-events: auto;
  }

  .band-side {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "pieces pieces"
      "total configs";
    align-items: center;
    gap: 24px;
    width: auto;
  }

  .band-side .room-configs {
    grid-area: configs;
    pointer-events: auto;
  }

  .pieces {
    grid-area: pieces;
    display: flex;
    gap: 8px;
    margin-inline: calc(-1 * var(--gutter));
    padding: 4px var(--gutter) 12px;
    overflow-x: auto;
    scroll-padding-inline: var(--gutter);
    scrollbar-width: none;
  }

  .pieces::-webkit-scrollbar {
    display: none;
  }

  .pieces li {
    flex: none;
    scroll-snap-align: start;
  }

  .piece {
    min-width: 210px;
  }

  .band-total {
    grid-area: total;
  }

  .order-steps {
    grid-template-columns: minmax(0, 1fr);
    max-width: 560px;
    gap: 48px;
  }

  /* One column: a wider tile, so a picture isn't mostly the bottom of a list. */
  .step-pic {
    aspect-ratio: 3 / 2;
  }
}

@media (max-width: 900px) {
  .room-stage {
    aspect-ratio: 39 / 34;
  }

  .cta-card {
    padding: 48px 24px 160px;
  }

  .cta-bright {
    top: auto;
    right: -40px;
    bottom: -70px;
    width: 220px;
    height: 220px;
    transform: none;
  }

  .hero-intro {
    flex-direction: column;
    align-items: stretch;
    gap: 28px;
  }

  .hero-signup {
    flex: none;
  }

  .hero-signup .form-note {
    position: static;
  }
}

/* Phones follow Figma 348:2. */
@media (max-width: 720px) {
  .nav {
    height: 64px;
  }

  .nav-links {
    display: none;
  }

  .nav .wordmark {
    height: 20px;
  }

  .nav-cta {
    height: 40px;
    margin-left: auto;
    padding: 0 18px;
    font-size: 1rem;
  }

  .eyebrow {
    font-size: 0.95rem;
  }

  .lede {
    margin-top: 16px;
    font-size: 1.0625rem;
  }

  .how,
  .faq,
  .start {
    padding-top: 64px;
  }

  .faq-list summary {
    gap: 16px;
    padding-block: 16px;
    font-size: 1.0625rem;
  }

  .how-col {
    gap: 14px;
  }

  .sunny-card {
    gap: 12px;
    padding: 28px 20px;
  }

  .sunny-card img {
    width: 88px;
    height: 88px;
  }

  /* The closing card: Bright on top, looking down at the offer. */
  .cta-card {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 24px 24px 28px;
    border-radius: 28px;
  }

  .cta-bright {
    position: static;
    display: block;
    width: 112px;
    height: 112px;
    transform: none;
  }

  .cta-card .capsule {
    margin-top: 8px;
  }

  .dealer-line {
    margin-top: 22px;
    font-size: 1rem;
  }

  /* Footer: brand and copyright, then the links, then the address. */
  .site-foot {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 18px 16px;
    margin-top: 60px;
    padding-block: 28px 40px;
  }

  .copyright,
  .foot-links {
    font-size: 0.9375rem;
  }

  .foot-links {
    grid-column: 1 / -1;
    margin-left: 0;
    gap: 10px 20px;
  }

  .foot-mail {
    flex-basis: 100%;
  }

  /* The room is square, and the options sit under the chips. */
  .hero {
    padding-block: 20px 0;
  }

  .hero-title {
    margin-top: 22px;
  }

  .hero-intro {
    margin-top: 16px;
    gap: 24px;
  }

  .hero-intro .lede {
    font-size: 1.0625rem;
  }

  .band {
    margin-top: 36px;
  }

  .band-room::before {
    padding-top: 100%;
  }

  .band-ui {
    padding-bottom: 64px;
  }

  .band-side {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "pieces"
      "configs"
      "total";
    gap: 20px;
  }

  .band-side .room-configs {
    justify-self: start;
  }

  .piece {
    min-width: 190px;
  }

  .orders {
    padding-block: 56px 64px;
  }

  .orders .headline {
    margin-top: 10px;
  }

  .orders-lede {
    margin-top: 12px;
    font-size: 1.0625rem;
  }

  .order-steps {
    gap: 36px;
    margin-top: 36px;
  }

  .step-pic {
    aspect-ratio: 4 / 3;
    border-radius: 22px;
  }

  .step-title {
    margin-top: 16px;
    font-size: 1.1875rem;
  }

  .step-body {
    margin-top: 6px;
    font-size: 1rem;
  }

  .knows-card {
    gap: 10px;
    padding: 28px 20px;
  }
}

@media (max-width: 480px) {
  /* The email field and the button stack as two separate pills. */
  .capsule {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    max-width: none;
    height: auto;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
  }

  .capsule input {
    flex: none;
    height: 52px;
    padding: 0 20px;
    border: 1.5px solid var(--stroke);
    border-radius: 26px;
    background: var(--card);
  }

  .capsule input:focus {
    border-color: var(--ink);
  }

  .capsule .button {
    height: 52px;
  }

  .cta-card .capsule input {
    border-color: rgb(255 255 255 / 0.45);
    background: transparent;
    color: var(--ink-inverse);
  }

  .cta-card .capsule input::placeholder {
    color: rgb(255 255 255 / 0.6);
  }

  .cta-card .capsule input:focus {
    border-color: var(--ink-inverse);
  }

  .cta-card .capsule .button {
    background: var(--card);
    color: var(--ink);
  }
}
