/* AskSphere — Build Your Dream Setup
   Drop-in replacement for styles.css. Targets the existing DOM produced by
   script.js: no renderer changes required. */

:root {
  --ink: #0f0e0c;
  --ink-muted: #6b6560;
  --ink-subtle: #9e9893;
  --warm: #f4f2ee;
  --stone: #e8e5e0;
  --border: #dedad4;
  --border-strong: #c2beb7;
  --signal: #ea580c;          /* progress edge only */
  --signal-text: #c2410c;     /* validation text only */
  --sans: 'DM Sans', system-ui, -apple-system, sans-serif;
  --mono: 'Space Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --ease: cubic-bezier(.22, .61, .36, 1);
  --gut: 56px;
  --lead: 58px;   /* option row: index / icon column */
  --tail: 56px;   /* option row: checkbox column */
  --row: 80px;
  /* side padding that also clears a phone's rounded corners and camera when it's on its side
     (the pages use viewport-fit=cover) */
  --pad-l: max(var(--gut), env(safe-area-inset-left, 0px));
  --pad-r: max(var(--gut), env(safe-area-inset-right, 0px));
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* No rubber-band bounce: a step that fits on one screen stays put when dragged
   up or down (and sideways swipes don't wobble the page); steps taller than the
   screen still scroll normally. */
html, body { overscroll-behavior: none; overflow-x: clip; }

/* Safari on the iPhone Duo's outer screen keeps its controls in a column down one side and fills the space behind
   them with the page's background colour, so the root takes the colour of whatever covers the screen: the dark
   loading screen (script.js adds .orb-showing) or the feedback pop-up's dimmed page. */
html { background: var(--warm); transition: background-color 300ms ease; }
html.orb-showing { background: #151210; }
html:has(.feedback-dialog[open]:not(.closing)) { background: color-mix(in srgb, var(--warm) 64%, #0f0e0c); }

body {
  background: var(--warm);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--border-strong); }
a:hover { color: var(--signal-text); border-bottom-color: var(--signal-text); }

.stars { display: none; }                     /* starfield retired; JS still targets it */
.welcome-meta-mobile { display: none; }       /* superseded by .spec-block */

.debug-console {
  display: none; position: fixed; bottom: 12px; left: 12px; z-index: 200;
  max-width: 380px; max-height: 40vh; overflow: auto;
  padding: 12px 14px; background: #151210; color: #e8e5e0;
  font: 400 11px/1.5 var(--mono);
}
.debug-close { position: absolute; top: 6px; right: 10px; cursor: pointer; }
.debug-log.error { color: #ff9d76; }
.debug-log.success { color: #9ecf9e; }

/* ── shell ─────────────────────────────────────────────────────── */
.container { display: flex; flex-direction: column; min-height: 100vh; }
/* 100vh on iOS Safari includes the area behind the browser toolbar, which pushed
   the Next button off the visible screen; dvh tracks what is actually visible. */
@supports (min-height: 100dvh) { .container { min-height: 100dvh; } }

.panel-left {                                  /* now a masthead bar */
  position: sticky; top: 0; z-index: 40; flex: 0 0 auto;
  height: 60px; background: var(--warm);
  border-bottom: 1px solid var(--border);
}
.panel-left-inner {
  height: 100%; display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 0 var(--pad-r) 0 var(--pad-l);
}
.logo {
  font-family: var(--sans); font-size: 11px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
}
.panel-left-meta {
  display: flex; align-items: center; gap: 10px;
  font: 400 11px/1.2 var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-muted);
}
.panel-left-meta .divider { display: none; }
.panel-left .main-title, .panel-left .subtitle { display: none; }

.panel-right { flex: 1; display: flex; flex-direction: column; min-width: 0; }

/* ── progress ──────────────────────────────────────────────────── */
.progress-container { display: none; flex: 0 0 auto; }
.progress-container.show { display: block; }
.progress-bar { height: 2px; background: var(--border); }
.progress-fill {
  position: relative; height: 100%; width: 0;
  background: var(--ink); transition: width 420ms var(--ease);
}
.progress-fill::after {
  content: ''; position: absolute; right: 0; top: 0;
  width: 12.5%; height: 100%; background: var(--signal);
}
.progress-text {
  padding: 12px var(--pad-r) 0 var(--pad-l); text-align: right;
  font: 400 11px/1.2 var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-muted);
}

/* ── screens ───────────────────────────────────────────────────── */
.question-container { display: none; }
.question-container.hidden { display: none !important; }
.question-container.show {
  display: flex; flex-direction: column; flex: 1 0 auto;
  padding: 64px var(--pad-r) 44px var(--pad-l);
  animation: enter 460ms var(--ease) both;
}
@keyframes enter { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* entry */
.entry-grid { display: flex; gap: 64px; align-items: flex-start; flex: 0 0 auto; }
.entry-left { flex: 1; min-width: 0; max-width: 760px; }
.entry-index {
  display: block; margin-bottom: 26px;
  font: 400 12px/1.2 var(--mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-muted);
}
.main-title {
  margin: 0 0 22px; font-family: var(--sans); font-weight: 800;
  font-size: 78px; line-height: .96; letter-spacing: -.038em; text-wrap: balance;
}
.main-title span { display: inline; }
.title-soft { color: var(--ink-muted); }

.spec-block { flex: 0 0 auto; width: 260px; border-top: 1px solid var(--ink); }
.spec-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; padding: 13px 0; border-bottom: 1px solid var(--border);
}
.spec-key {
  font: 500 10.5px/1.2 var(--sans); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-muted);
}
.spec-val { font: 700 12px/1.2 var(--mono); color: var(--ink); }

/* question head */
.question-label {
  display: block; margin-bottom: 14px;
  font: 500 11px/1.2 var(--sans); letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-muted);
}
.question-label:empty { display: none; }
.question-title {
  margin: 0 0 12px; font-family: var(--sans); font-weight: 700;
  font-size: 46px; line-height: 1.04; letter-spacing: -.032em; text-wrap: balance;
}
.question-description {
  margin: 0 0 34px; font-size: 16px; line-height: 1.6;
  color: var(--ink-muted); max-width: 480px; text-wrap: pretty;
}
#welcomeScreen .question-description { font-size: 17px; margin-bottom: 0; max-width: 460px; }

/* ── options as a parts list ───────────────────────────────────── */
.options-grid {
  display: flex; flex-direction: column;
  border-top: 1px solid var(--ink); counter-reset: opt;
}
.option-card {
  display: grid;
  grid-template-columns: var(--lead) 1fr var(--tail);
  grid-template-rows: 1fr auto;
  min-height: var(--row);
  border-bottom: 1px solid var(--border);
  background: transparent; cursor: pointer;
  transition: background 200ms var(--ease);
  animation: enter 360ms var(--ease) both;
}
.option-card:hover { background: rgba(255, 255, 255, .62); }
.option-card.selected { background: #fff; }

/* mono index in the lead cell */
.option-card::before {
  counter-increment: opt;
  content: counter(opt, decimal-leading-zero);
  grid-column: 1; grid-row: 1 / -1;
  display: flex; align-items: center; justify-content: center;
  border-right: 1px solid var(--border);
  font: 400 12px/1 var(--mono); color: var(--ink-muted);
  transition: background 200ms var(--ease), color 200ms;
}
.option-card.selected::before { background: var(--ink); color: #fff; }
.option-card:has(.option-icon)::before { display: none; }

/* lucide icon replaces the index where config.js supplies one */
.option-icon {
  grid-column: 1; grid-row: 1 / -1;
  display: flex; align-items: center; justify-content: center;
  border-right: 1px solid var(--border);
  color: var(--ink-muted);
  transition: background 200ms var(--ease), color 200ms;
}
.option-icon svg { width: 23px; height: 23px; stroke-width: 1.2; }
.option-card.selected .option-icon { background: var(--ink); color: #fff; }

.option-title {
  grid-column: 2; grid-row: 1; align-self: end; padding: 16px 22px 0;
  font-size: 17px; font-weight: 500; letter-spacing: -.012em; line-height: 1.25;
}
.option-card.selected .option-title { font-weight: 600; }
.option-card:not(:has(.option-description)) .option-title {
  grid-row: 1 / -1; align-self: center; padding: 16px 22px;
}
.option-description {
  grid-column: 2; grid-row: 2; align-self: start; padding: 4px 22px 0; margin-bottom: 16px;
  font-size: 13.5px; line-height: 1.4; color: var(--ink-muted); text-wrap: pretty;
  /* margin, not padding, below: the clamp clips at the padding edge, so padding would show the cut-off line */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}

/* checkbox in the tail cell */
.option-card::after {
  content: ''; grid-column: 3; grid-row: 1 / -1;
  align-self: center; justify-self: center;
  width: 13px; height: 13px; border: 1px solid var(--border-strong);
  transition: all 200ms var(--ease);
}
.option-card.selected::after { background: var(--ink); border-color: var(--ink); }

/* ── A/B image pick ───────────────────────────────────────────── */
.options-grid.random-pick,
.options-grid.image-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px; border-top: 0;
}
.option-card.image-card {
  display: block; position: relative; aspect-ratio: 4 / 5;
  min-height: 0; overflow: hidden; border: 0; background: var(--stone);
  box-shadow: none; transition: box-shadow 200ms var(--ease);
}
.option-card.image-card::before, .option-card.image-card::after { display: none; }
.option-card.image-card:hover { background: var(--stone); }
.option-card.image-card.selected { background: var(--stone); box-shadow: inset 0 0 0 4px var(--ink); }
.image-card-thumb { position: absolute; inset: 0; }
.image-card-thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 700ms var(--ease);
}
.image-card.selected .image-card-thumb img { transform: scale(1.03); }
/* A/B pick: side by side on desktop, stacked on mobile; both cropped to the same 3:2 box */
.options-grid.random-pick { grid-template-columns: 1fr 1fr; }
@media (max-width: 699px) {
  .options-grid.random-pick { grid-template-columns: 1fr; }
}
.random-pick .option-card.image-card { aspect-ratio: 3 / 2; }
.image-card-thumb.img-missing { background: var(--stone); }
.image-card-thumb.img-missing img { visibility: hidden; }   /* no broken-image icon */
/* A photo on its way (script.js showCardImage): the card's stone with a soft light passing over it, after a beat so
   a quick load never flashes it. Then the photo fades up out of soft focus. */
.image-card-thumb.loading img { opacity: 0; }
.image-card-thumb.loading::before {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 60%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .45), transparent);
  transform: translateX(-100%); animation: cardShimmer 1600ms var(--ease) 400ms infinite;
}
@keyframes cardShimmer { to { transform: translateX(267%); } }
/* scale, not transform, so a card picked mid-fade keeps its selected zoom */
.image-card-thumb.revealed img { animation: cardImageIn 800ms var(--ease) backwards; }
@keyframes cardImageIn {
  from { opacity: 0; filter: blur(14px); scale: 1.04; }
  40%  { opacity: 1; }
  to   { opacity: 1; filter: blur(0); scale: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .image-card-thumb.loading::before { animation: none; }
  .image-card-thumb.revealed img { animation: fade 300ms ease backwards; }
}
.image-card-label {
  position: absolute; top: 0; left: 0; height: 40px;
  display: flex; align-items: center; padding: 0 14px;
  background: rgba(255, 255, 255, .55); color: var(--ink);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  font: 700 13px/1 var(--mono); transition: all 200ms var(--ease);
}
.image-card.selected .image-card-label { background: var(--ink); color: #fff; }
/* A/B pick: two separate prints rather than one strip. Each has a fine light line just inside its edge and a frosted
   caption in its corner; the one picked gets a ring standing off it and a tick, and the other steps back (it comes
   forward again on hover, to show it can still be picked). */
.options-grid.random-pick { gap: 16px; }
.random-pick .option-card.image-card { outline: 1.5px solid transparent; outline-offset: 5px; transition: outline-color 220ms var(--ease); }
.random-pick .option-card.image-card.selected { box-shadow: none; outline-color: var(--ink); }
.random-pick .image-card-thumb::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3);
}
.random-pick .image-card-thumb img { transition: transform 700ms var(--ease), opacity 300ms var(--ease), filter 300ms var(--ease); }
.random-pick:has(.selected) .image-card:not(.selected) .image-card-thumb img { opacity: .55; filter: saturate(.7); }
.random-pick:has(.selected) .image-card:not(.selected):hover .image-card-thumb img { opacity: .85; filter: none; }
.random-pick .image-card-label {
  top: auto; bottom: 10px; left: 10px; height: 28px; padding: 0 10px;
  background: rgba(244, 242, 238, .6); border: 1px solid rgba(255, 255, 255, .55);
  font: 500 10.5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
}
.random-pick .image-card.selected .image-card-label { border-color: var(--ink); }
.random-pick .image-card.selected .image-card-label::before { content: '\2713'; margin-right: 6px; }

/* ── checkbox group (priorities) ───────────────────────────────── */
.checkbox-group { display: flex; flex-direction: column; border-top: 1px solid var(--ink); }
.checkbox-item {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 68px; padding: 14px 0 14px 22px;
  border-bottom: 1px solid var(--border); cursor: pointer;
  transition: background 200ms var(--ease);
}
.checkbox-item:hover { background: rgba(255, 255, 255, .62); }
.checkbox-item.selected { background: #fff; }
.checkbox-item .option-title { all: unset; font: 500 17px/1.25 var(--sans); letter-spacing: -.012em; }
.checkbox-item::after {
  content: ''; width: 13px; height: 13px; margin-right: 21px;
  border: 1px solid var(--border-strong); transition: all 200ms var(--ease);
}
.checkbox-item.selected::after { background: var(--ink); border-color: var(--ink); }

/* ── inputs ────────────────────────────────────────────────────── */
.input-group { display: flex; flex-direction: column; gap: 9px; margin-bottom: 22px; }
.input-label {
  font: 500 11px/1.2 var(--sans); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink);
}
.input-field {
  width: 100%; padding: 16px; background: #fff;
  border: 1px solid var(--border); border-radius: 0;
  color: var(--ink); font-family: var(--sans); font-size: 16px;
  transition: border-color 200ms;
}
.input-field:focus { outline: none; border-color: var(--ink); }
.textarea-field { min-height: 170px; line-height: 1.55; resize: vertical; }
.field-error { font: 400 12px/1.4 var(--mono) !important; color: var(--signal-text) !important; }
.input-note { font-size: 13px; line-height: 1.45; color: var(--ink-muted); max-width: 480px; text-wrap: pretty; }

.file-upload { position: relative; }
.file-upload input[type=file] { position: absolute; opacity: 0; width: 0; height: 0; }
.file-upload-label {
  display: flex; flex-direction: column; gap: 10px;
  align-items: center; justify-content: center; text-align: center;
  min-height: 190px; padding: 32px 24px; background: #fff;
  border: 1px dashed var(--border-strong); cursor: pointer;
  font-size: 19px; font-weight: 600; letter-spacing: -.015em;
}
.file-upload-label div + div {
  font: 400 12px/1.2 var(--mono) !important; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-muted) !important;
}

.error-message {
  display: none; margin-top: 20px; padding: 14px 16px;
  background: #fff; border: 1px solid var(--ink);
  font-size: 13px; line-height: 1.55;
}

/* ── buttons ───────────────────────────────────────────────────── */
.button-group { display: flex; align-items: center; gap: 10px; margin-top: auto; padding-top: 40px; }
#welcomeScreen .button-group { margin-top: 24px; padding-top: 0; }
.btn {
  font-family: var(--sans); border-radius: 0; cursor: pointer;
  transition: background 200ms var(--ease), color 200ms, border-color 200ms;
}
.btn-primary {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 20px;
  min-width: 196px; min-height: 58px; padding: 0 22px;
  font-size: 13px; font-weight: 600; letter-spacing: .02em;
  color: #fff; background: var(--ink); border: none;
}
.btn-primary:hover:not(:disabled) { background: #332e29; }
.btn-primary:disabled { opacity: .3; cursor: not-allowed; }
.btn-secondary {
  background: transparent; border: none; padding: 18px 2px; margin-right: auto;
  font: 400 12px/1.2 var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-muted);
}
.btn-secondary:hover { color: var(--ink); }
.btn-secondary.hidden { display: none; }
/* Next stays on the right even on question 1, where Back (which pushes it right) is hidden. */
#questionScreen .button-group .btn-primary { margin-left: auto; }

/* ── band ──────────────────────────────────────────────────────── */
.setup-carousel {
  position: relative; flex: 0 0 auto; margin: 36px calc(var(--pad-r) * -1) 0 calc(var(--pad-l) * -1);
  height: 305px; overflow: hidden;
  border-top: 1px solid var(--border); background: var(--stone);
}
/* The photos take their width from the band's height (409 x 305 on desktop), so a screen with room to spare can
   stretch the band without squashing them */
.carousel-track {
  position: absolute; inset: 0 auto 0 0;
  display: flex; gap: 2px; width: max-content;
  animation: band 60s linear infinite;
}
.carousel-track img { display: block; height: 100%; width: auto; aspect-ratio: 409 / 305; object-fit: cover; }
@keyframes band { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ── loading ───────────────────────────────────────────────────── */
/* After the last question: the energy orb, centred on the dark screen, with one line of
   copy under it. script.js holds it for APP_SETTINGS.LOADING_MIN_MS, fades it out
   (.leaving) and opens the results page. */
.loading-screen {
  display: none; position: fixed; inset: 0; z-index: 60;
  align-items: center; justify-content: center; background: #151210;
  animation: fade 460ms ease both;
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.loading-content {
  display: flex; flex-direction: column; align-items: center; gap: 48px;
  padding: 28px var(--pad-r) 28px var(--pad-l);
  transition: opacity 400ms var(--ease), transform 400ms var(--ease);
}
.loading-screen.leaving .loading-content { opacity: 0; transform: scale(.96); }
.loading-text {
  text-align: center;
  font: 400 11px/1.5 var(--mono); letter-spacing: .24em; text-transform: uppercase;
  color: rgba(254, 215, 170, .55);
}

/* The energy orb. Pure CSS, a 3D ember sphere with a glowing amber-orange rim
   (the site's --signal orange), fiery ribbons turning inside it in 3D, and a warm
   halo that breathes slowly while a soft light drifts round behind the rim. */
.loading-orb {
  --size: min(220px, 60vw, 46svh);   /* svh: still clear of the line under it on a phone on its side */
  position: relative; isolation: isolate;
  width: var(--size); aspect-ratio: 1; border-radius: 50%;
  filter: saturate(.7);   /* tones the whole orb down at once: body, rim, ribbons, glow */
  animation: orbIn 900ms var(--ease) both, sphereFloat 6s ease-in-out infinite;
}

/* the sphere's answer, 8-ball style: each line surfaces out of the haze and sinks back */
.orb-message {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center; padding: 0 19%;
  text-align: center; text-wrap: balance;
  font: 500 17px/1.25 var(--sans); letter-spacing: .01em; color: #fff;
  text-shadow: 0 0 18px rgba(249, 115, 22, .95), 0 0 2px rgba(255, 255, 255, .6);
  transition: opacity 400ms var(--ease), filter 400ms var(--ease), transform 400ms var(--ease);
}
.orb-message.out { opacity: 0; filter: blur(6px); transform: scale(.94); }

/* halo behind the orb */
.orb-glow {
  position: absolute; inset: -16%; z-index: -2; border-radius: 50%;
  background: conic-gradient(from 0deg, #ea580c, #f59e0b, #c2410c, #fb923c, #b45309, #ea580c);
  filter: blur(30px); opacity: .3;
  animation: orbTurn 12s linear infinite, orbBreathe 4s ease-in-out infinite alternate;
}

/* one soft light in the rim's own amber, drifting slowly round behind it */
.loading-orb::before {
  content: ''; position: absolute; inset: -20%; z-index: -2; border-radius: 50%;
  background: radial-gradient(ellipse 120px 46px at 50% 13%, rgba(251, 146, 60, .5), transparent);
  filter: blur(26px);
  animation: orbTurn 14s linear infinite;
}

/* dark interior, lit from the rim so it reads as a ball, not a disc */
.orb-body {
  position: absolute; inset: 0; z-index: -1; border-radius: 50%;
  background:
    radial-gradient(circle at 34% 28%, rgba(255, 170, 80, .22), transparent 42%),
    radial-gradient(circle at 50% 50%, #1a0702 0%, #3a1004 50%, #7a2408 80%, #c2410c 100%);
  box-shadow:
    inset 0 0 26px rgba(249, 115, 22, .7),
    inset -14px -18px 34px rgba(180, 40, 10, .45),
    inset 12px 10px 28px rgba(253, 186, 116, .35);
}

/* smoky ribbons: thin glowing rings tilted at different angles, spinning slowly in 3D */
.orb-ribbons {
  position: absolute; inset: 0; transform-style: preserve-3d;
  animation: orbTumble 24s linear infinite;
}
.orb-ribbons i {
  position: absolute; inset: 3%; border-radius: 50%;
  border: 1px solid rgba(249, 115, 22, .35);
  border-top-color: rgba(254, 215, 120, .6);
  border-left-color: rgba(251, 146, 60, .5);
  box-shadow: 0 0 8px rgba(234, 88, 12, .3), inset 0 0 8px rgba(253, 186, 116, .2);
  filter: blur(.6px);
  animation: ribbonSpin var(--d, 12s) linear infinite;
}
.orb-ribbons i:nth-child(1) { --x: 70deg;  --z: 10deg;  --d: 11s; }
.orb-ribbons i:nth-child(2) { --x: 55deg;  --z: 70deg;  --d: 15s; inset: 5%; }
.orb-ribbons i:nth-child(3) { --x: 80deg;  --z: 130deg; --d: 13s; }
.orb-ribbons i:nth-child(4) { --x: 40deg;  --z: 200deg; --d: 18s; inset: 7%; opacity: .6; }
.orb-ribbons i:nth-child(5) { --x: 65deg;  --z: 260deg; --d: 14s; opacity: .7; }
.orb-ribbons i:nth-child(6) { --x: 85deg;  --z: 320deg; --d: 17s; inset: 4%; opacity: .5; }

/* the bright edge: a colour-shifting ring, slightly blurred like light on smoke */
.orb-rim {
  position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from 90deg, #fb923c, #fde68a, #ea580c, #fbbf24, #f97316, #fb923c);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 1.5px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 1.5px));
  filter: blur(1px) drop-shadow(0 0 4px rgba(249, 115, 22, .6));
  opacity: .85;
  animation: orbTurn 7s linear infinite reverse;
}

@keyframes orbIn { from { opacity: 0; transform: scale(.86); } }
@keyframes sphereFloat { 0%, 100% { translate: 0 0; } 50% { translate: 0 -7px; } }
@keyframes orbBreathe { to { opacity: .5; scale: 1.08; } }
@keyframes orbTurn { to { transform: rotate(360deg); } }
@keyframes orbTumble { from { transform: rotateY(0) rotateX(12deg); } to { transform: rotateY(360deg) rotateX(12deg); } }
@keyframes ribbonSpin {
  from { transform: rotateZ(var(--z, 0deg)) rotateX(var(--x, 60deg)) rotateY(0); }
  to   { transform: rotateZ(var(--z, 0deg)) rotateX(var(--x, 60deg)) rotateY(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .loading-orb, .loading-orb::before, .orb-glow, .orb-rim, .orb-ribbons, .orb-ribbons i { animation: none; }
  .orb-ribbons i { transform: rotateZ(var(--z)) rotateX(var(--x)); }
}

/* ── mobile ────────────────────────────────────────────────────── */
@media (max-width: 1040px) {
  :root { --gut: 36px; }
  .entry-grid { flex-direction: column; gap: 44px; }
  .spec-block { width: 100%; }
  /* results: the intro's own bottom margin is gap enough above the profile rows */
  #resultsContent .entry-grid { gap: 0; }
  .main-title { font-size: 58px; }
  .question-title { font-size: 38px; }
  .setup-carousel { height: 245px; }
}

@media (max-width: 700px) {
  :root { --gut: 20px; --lead: 54px; --tail: 42px; --row: 60px; }
  .panel-left { height: 52px; }
  /* lift the Next button clear of the phone's rounded corners and home bar */
  .question-container.show { padding: 20px var(--pad-r) calc(32px + env(safe-area-inset-bottom, 0px)) var(--pad-l); }
  .main-title { font-size: 40px; line-height: 1.02; letter-spacing: -.03em; }
  .question-label { margin-bottom: 8px; }
  .question-title { font-size: 25px; line-height: 1.08; margin-bottom: 7px; }
  .question-description { font-size: 13.5px; line-height: 1.45; margin-bottom: 18px; }
  #welcomeScreen .question-description { font-size: 16px; }
  .option-title { font-size: 15.5px; padding: 11px 14px 0; }
  .option-card:not(:has(.option-description)) .option-title { padding: 11px 14px; }
  .option-description { font-size: 12.5px; padding: 3px 14px 0; margin-bottom: 11px; -webkit-line-clamp: 2; }
  .option-icon svg { width: 21px; height: 21px; }
  .button-group { padding-top: 18px; }
  #welcomeScreen .button-group { margin-top: 20px; }
  .btn-primary { flex: 1; min-width: 0; min-height: 54px; padding: 0 20px; }
  .btn-secondary { padding: 15px 2px; }
  .input-group { gap: 7px; margin-bottom: 15px; }
  .input-field { padding: 14px 15px; }
  .textarea-field { min-height: 140px; }
  .file-upload-label { min-height: 132px; padding: 24px 20px; font-size: 16px; }
  .setup-carousel { height: 183px; margin-top: 24px; }
  .progress-text { padding-top: 10px; }
}

/* sketch-reveal.css — append to styles.css
   A quiet line sketch that draws itself just above the Continue button.
   Uses the existing tokens; adds no new colours. */

@keyframes skStroke {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

@keyframes skWipe {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

.sketch-band {
  position: absolute;
  inset: 0;
}

.sketch-img {
  position: absolute;
  inset: 0;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  clip-path: inset(0 0 100% 0);
  animation: skStroke 150ms linear both;
}

@keyframes skDraw {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}
@keyframes skFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* The strip reserves its room before an answer is picked, so nothing shifts when a sketch appears. It takes the
   space between the answers and the buttons (which sit at the foot of the screen): at least --sketch-h of drawing,
   and on a screen with room to spare the drawing grows, up to --sketch-max, centred in that space. sketch-reveal.js
   weighs the lines for the size it's drawn at, and leaves the drawing out of a strip too short to show it (on the
   folded Duo, where the minimum is 0 so the step fits first). The answers' block stretches down to the buttons so
   the strip can take that space. */
:root { --sketch-h: 220px; --sketch-max: 300px; --sketch-pad: 24px; }
.sketch-strip {
  position: relative;
  flex: 1 0 auto;
  min-height: calc(var(--sketch-h) + var(--sketch-pad));
  margin-top: 36px;
  pointer-events: none;
  opacity: .95;
}
#questionContent:has(> .sketch-strip) { display: flex; flex-direction: column; flex: 1 0 auto; }

/* The sketch's own viewBox ratio (set inline per sketch) at the strip's height, centred */
.sketch-box {
  position: absolute; top: 50%; left: 50%; translate: -50% -50%;
  height: min(calc(100% - var(--sketch-pad)), var(--sketch-max)); max-width: 100%;
  animation: skFade 300ms ease both;
}
.sketch-box svg { display: block; }
/* the label on step 4's measure under the desk (sketch-reveal.js sizes it), on a patch of the page's colour so the
   line stops either side of it */
.sketch-label text { font-family: var(--mono); letter-spacing: .02em; fill: var(--ink); stroke: none; }
.sketch-label rect { fill: var(--warm); stroke: none; }
/* a question's note under its sketch (config.js sketchNote): the drawing keeps clear of it */
.sketch-note {
  position: absolute; left: 0; right: 0; bottom: 0;
  font-size: 11.5px; line-height: 1.3; color: var(--ink-subtle); text-align: center; text-wrap: balance;
}
.sketch-strip:has(.sketch-note) { --note-h: 20px; min-height: calc(var(--sketch-h) + var(--sketch-pad) + var(--note-h)); }
.sketch-strip:has(.sketch-note) .sketch-box {
  top: calc(50% - var(--note-h) / 2); height: min(calc(100% - var(--sketch-pad) - var(--note-h)), var(--sketch-max));
}

/* steps 2 (vibe) and 4 (desk space): extra room between the options and the drawing */
.sketch-strip[data-question="vibe"],
.sketch-strip[data-question="space-size"] { margin-top: 96px; }

@media (max-width: 699px) {
  :root { --sketch-h: 136px; --sketch-max: 220px; --sketch-pad: 12px; }
  .sketch-strip { margin-top: 20px; }
  .sketch-strip[data-question="vibe"],
  .sketch-strip[data-question="space-size"] { margin-top: 52px; }
}

@media (prefers-reduced-motion: reduce) {
  .sketch-box path {
    animation: none !important;
    stroke-dashoffset: 0 !important;
  }
  .sketch-img {
    animation: none !important;
    clip-path: none !important;
  }
  .sketch-box, .sketch-label { animation: none !important; }
}


/* ── results page (results.html) ──────────────────────────────────
   Reuses the questionnaire's shell and components; only what they
   don't cover is here, using the same tokens. */
.results-page [hidden] { display: none !important; }
.results-page .logo { border-bottom: 0; }

.results-sweep {
  position: relative; width: 220px; height: 2px; margin-top: 8px;
  background: var(--border); overflow: hidden;
}
.results-sweep::after {
  content: ''; position: absolute; top: 0; left: 0;
  width: 25%; height: 100%; background: var(--signal);
  animation: sweep 1400ms var(--ease) infinite;
}
@keyframes sweep { from { transform: translateX(-100%); } to { transform: translateX(400%); } }

/* The top: the headline and intro on the left with the answers at the foot, level with the foot of the render
   beside them (4:5, like the images, so nothing is cropped; the label sits under it). Two columns down to tablets;
   on phones one, the render before the answers. .results-hero only groups the render and its label in the HTML. */
.results-top {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 520px); column-gap: 64px;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "text image" "spec image" ". note";
}
.results-top-text { grid-area: text; }
.results-top > .spec-block { grid-area: spec; align-self: end; width: 100%; max-width: 440px; }
.results-hero { display: contents; }
.results-hero > .results-hero-cell { grid-area: image; }
.results-hero-cell { position: relative; margin: 0; aspect-ratio: 4 / 5; overflow: hidden; background: var(--stone); }
.results-hero-cell img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
}
.results-hero-pending, .results-hero-soon {
  position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: flex-end;
  gap: 10px; padding: 28px;
  font: 400 12px/1.2 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-muted);
}

/* "Illustrative concept." under the render */
.results-hero-note {
  grid-area: note; margin: 10px 0 0;
  font: 400 12px/1.5 var(--sans); color: var(--ink-muted); text-wrap: pretty;
}
.results-hero-note strong { font-weight: 600; color: var(--ink); }

/* While the render is made: the questionnaire's sketch for each answer draws itself in turn, centred on the
   box, with a line of copy under it that changes with each sketch (results.js) */
.results-hero-cell .results-hero-pending {
  justify-content: center; align-items: center; text-align: center; gap: 30px;
}
.results-sketch { width: 86%; aspect-ratio: 250 / 152; transition: opacity 500ms var(--ease); }
.results-sketch svg { display: block; width: 100%; height: 100%; }
.results-sketch.out { opacity: 0; }
.loading-message {
  max-width: 26ch; min-height: 2.6em; line-height: 1.3;
  transition: opacity 400ms var(--ease);
}
.loading-message.out { opacity: 0; }

/* When the render arrives it takes over from the sketch rather than popping in (results.js revealImage): it comes
   up under the finished sketch, pale and soft like the drawing, then sharpens into colour as the sketch and its
   line fade off it. Keep the duration in sync with IMAGE_REVEAL_MS. */
.results-hero-cell img.develop { animation: develop 1700ms var(--ease) backwards; }
@keyframes develop {
  from { opacity: 0; filter: grayscale(1) brightness(1.12) contrast(.9) blur(10px); transform: scale(1.04); }
  30%  { opacity: 1; }
  to   { opacity: 1; filter: grayscale(0) brightness(1) contrast(1) blur(0); transform: scale(1); }
}
.results-hero-cell .results-hero-pending { transition: opacity 800ms var(--ease) 200ms; }
.results-hero-cell .results-hero-pending.out { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .results-hero-cell img.develop { animation: fade 300ms ease backwards; }
}

/* Hero captions: quieter than the questionnaire's option labels */
.results-hero-cell .image-card-label {
  height: 30px; padding: 0 11px;
  font: 400 10px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-muted);
}

.carousel-btn:focus-visible, .product-carousel:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.results-section-label { margin: 64px 0 14px; }

/* products: the questionnaire's parts-list rows, with thumbnail and price */
.options-grid.results-items { border-top: 1px solid var(--ink); }
.option-card.product-row {
  grid-template-columns: var(--lead) 84px 1fr auto;
  grid-template-rows: auto auto 1fr;
  color: var(--ink); border-bottom: 1px solid var(--border);
}
.option-card.product-row:hover { color: var(--ink); border-bottom-color: var(--border); }
.option-card.product-row::after { display: none; }
.product-thumb {
  grid-column: 2; grid-row: 1 / -1; align-self: center; justify-self: center;
  width: 64px; height: 64px; background: #fff; overflow: hidden;
}
.product-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* Amazon's product photos sit on white; multiply lets that white take the page's colour (the image files are unchanged) */
.results-page .product-thumb { background: transparent; }
.results-page .product-thumb img { mix-blend-mode: multiply; }
/* the page container fades in, which isolates it: give it the page colour so the photos have something to blend with */
.results-page .question-container { background: var(--warm); }
.product-category {
  grid-column: 3; grid-row: 1; padding: 16px 22px 0;
  font: 500 10.5px/1.2 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-muted);
}
.product-row .option-title { grid-column: 3; grid-row: 2; align-self: start; padding: 5px 22px 0; font-weight: 600; }
.product-row .option-description { grid-column: 3; grid-row: 3; }
.product-price {
  grid-column: 4; grid-row: 1 / -1; align-self: center; padding: 0 22px;
  font: 700 13px/1.2 var(--mono); white-space: nowrap;
}

/* the total on the left, "Add all 7 to Amazon basket" on the right (stacked on phones) */
.results-checkout { display: flex; align-items: center; gap: 16px 40px; padding-top: 26px; }
.results-total { display: flex; flex-direction: column; gap: 8px; }
.results-total-value { line-height: 1.3; }
.results-total-amount { font: 700 26px/1 var(--mono); }
.results-total-note { font: 400 12px/1.4 var(--mono); color: var(--ink-muted); }

/* each product row is a carousel: native horizontal scrolling that snaps card by card, one whole card
   at a time (no edge of the next card shows; the counter and arrows say there are more).
   Vertical scrolling of the page is untouched. */
.product-carousel {
  --controls-w: 152px;   /* the ‹ 1 / 3 › column; kept free on rows without options so the prices line up */
  display: grid; grid-template-columns: minmax(0, 1fr) var(--controls-w);
  border-bottom: 1px solid var(--border);
}
.carousel-viewport { grid-column: 1; grid-row: 1; }
.carousel-viewport {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain; scrollbar-width: none;
}
.carousel-viewport::-webkit-scrollbar { display: none; }
.results-page .carousel-card {
  flex: 0 0 100%; min-width: 0; border-bottom: 0;
  scroll-snap-align: start; scroll-snap-stop: always;
  animation: none;   /* the fade-in would isolate the card and stop the thumbnails blending into the page */
}
.results-page .carousel-card { grid-template-columns: 64px 1fr auto; }
.results-page .carousel-card::before { display: none; }
.carousel-card .product-thumb { grid-column: 1; }
.carousel-card .product-category, .carousel-card.product-row .option-title,
.carousel-card.product-row .option-description { grid-column: 2; }
.carousel-card .product-price { grid-column: 3; }
.carousel-card:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.product-diff { display: block; margin-top: 4px; font: 400 11px/1.3 var(--mono); color: var(--ink-muted); }

/* product, price, then the controls: they belong to the row, so they sit outside the scrolling cards */
.carousel-controls {
  grid-column: 2; grid-row: 1; align-self: center; justify-self: end;
  display: flex; align-items: center; gap: 4px; position: relative; z-index: 1;   /* above the cards on phones */
}
.carousel-btn {
  width: 36px; height: 36px; border-radius: 0; cursor: pointer;
  background: transparent; border: 0; color: var(--ink);
  font: 400 18px/1 var(--mono);
  transition: background 200ms var(--ease);
}
.carousel-btn:hover:not(:disabled) { background: #fff; }
.carousel-btn:disabled { opacity: .2; cursor: not-allowed; }
.carousel-count { min-width: 4.2em; text-align: center; font: 400 12px/1.2 var(--mono); letter-spacing: .06em; color: var(--ink-muted); }

.results-page .button-group.results-actions { margin-top: 0; padding-top: 30px; }
.results-page a.btn { border-bottom: 0; }
.results-page a.btn-primary:hover { color: #fff; }

/* Download PDF and Email me this PDF are outlined, so the orange basket button is the page's one filled action */
.results-page :is(#pdfBtn, #emailBtn) { background: transparent; color: var(--ink); border: 1px solid var(--ink); }
.results-page :is(#pdfBtn, #emailBtn):hover:not(:disabled) { background: var(--ink); color: #fff; }

/* Add-all-to-basket: the page's main action, in the signal orange */
.basket-cta { display: flex; flex-direction: column; gap: 10px; width: min(380px, 100%); margin-left: auto; }
.basket-cta[hidden] { display: none; }
.results-page a.btn.basket-btn {
  width: 100%; justify-content: space-between;
  background: var(--signal); border-color: var(--signal); color: #fff;
}
.results-page a.btn.basket-btn:hover { background: var(--signal-text); border-color: var(--signal-text); color: #fff; }
.basket-note { margin: 0; font: 400 12px/1.5 var(--mono); color: var(--ink-muted); }

/* the PDF buttons' message: "Couldn't prepare your PDF..." in orange, "On its way to j•••@example.com..." in grey */
.results-pdf-note { margin-top: 12px; text-align: right; font: 400 12px/1.5 var(--mono); color: var(--signal-text); }
.results-pdf-note.ok { color: var(--ink-muted); }

@media (max-width: 1040px) {
  /* a narrower render; the four answers take two rows of two */
  .results-top { grid-template-columns: minmax(0, 1fr) minmax(0, 44%); column-gap: 40px; }
  .results-page .spec-block { display: grid; grid-template-columns: 1fr 1fr; column-gap: 24px; }
}

@media (max-width: 700px) {
  .results-top { grid-template-columns: 1fr; grid-template-rows: none; grid-template-areas: "text" "image" "note" "spec"; }
  .results-top > .spec-block { max-width: none; margin-top: 28px; }
  .results-hero-layout { display: none; }   /* no empty placeholder on phones */
  .results-section-label { margin-top: 44px; }
  .results-page .spec-block { column-gap: 16px; }
  .results-checkout { flex-direction: column; align-items: stretch; padding-top: 18px; }
  .results-total { flex-direction: row; justify-content: space-between; align-items: baseline; }
  .results-total-value { text-align: right; }
  .basket-cta { width: 100%; }
  .option-card.product-row { grid-template-columns: var(--lead) 64px 1fr; grid-template-rows: auto auto auto auto; }
  .product-thumb { width: 48px; height: 48px; }
  .product-category { padding: 11px 14px 0; }
  .product-row .option-title { padding: 4px 14px 0; }
  .product-price { grid-column: 3; grid-row: 4; padding: 2px 14px 11px; }
  .results-total-amount { font-size: 20px; }
  .results-page .carousel-card { grid-template-columns: 48px 1fr; }
  .carousel-card .product-price { grid-column: 2; }
  /* phone: the product on top, then one line with the price on the left and the controls on the right.
     The controls sit over the bottom line of the cards; the price keeps clear of them (it wraps) */
  .product-carousel { --controls-w: 112px; grid-template-columns: minmax(0, 1fr); }
  .carousel-controls { grid-column: 1; align-self: end; margin: 0 0 6px 0; gap: 4px; }
  .carousel-btn { width: 32px; height: 32px; }
  .carousel-count { min-width: 3.6em; letter-spacing: 0; }
  .carousel-card .product-diff { white-space: normal; }   /* wraps rather than running under the controls */
  .has-options .carousel-card .product-price {
    min-height: 44px; padding: 6px calc(var(--controls-w) + 22px) 6px 14px;
    display: flex; flex-direction: column; justify-content: center;
  }
  /* the PDF buttons full width first, 'Start again' below them */
  .results-actions { flex-wrap: wrap; }
  .results-pdf-note { text-align: left; }
  .results-actions .btn-primary { order: -1; flex: 1 1 100%; }
}

/* ── feedback: "What stopped this being useful?" ──────────────────
   A line at the foot of the page, below a hairline, whose button opens the questions in a pop-up
   (<dialog id="feedbackDialog">): a card in the middle of a wide screen, a sheet up from the bottom of a phone. */
.feedback-entry {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 24px;
  margin-top: 56px; padding-top: 28px; border-top: 1px solid var(--border);
}
.feedback-entry-title { margin: 0; font: 600 17px/1.3 var(--sans); letter-spacing: -.012em; }
.feedback-entry-hint { margin: 4px 0 0; font-size: 13.5px; line-height: 1.4; color: var(--ink-muted); }
/* outlined, like Download PDF, so the basket stays the page's one filled action */
.feedback-open {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 20px;
  min-width: 196px; min-height: 50px; padding: 0 20px;
  font-size: 13px; font-weight: 600; letter-spacing: .02em;
  color: var(--ink); background: transparent; border: 1px solid var(--ink);
}
.feedback-open:hover { background: var(--ink); color: #fff; }

.feedback-dialog {
  width: 480px; max-width: calc(100vw - 32px); max-height: calc(100vh - 48px); max-height: calc(100dvh - 48px);
  margin: auto; padding: 0; overflow-y: auto; overscroll-behavior: contain;
  background: var(--warm); color: var(--ink); border: 1px solid var(--ink);
  box-shadow: 0 18px 50px rgba(15, 14, 12, .22);
}
.feedback-dialog::backdrop { background: rgba(15, 14, 12, .36); }
/* in: rises and fades up over a dimming page; out (results.js adds .closing, then closes it): the reverse, quicker */
.feedback-dialog[open] { animation: feedbackIn 320ms var(--ease) both; }
.feedback-dialog[open]::backdrop { animation: fade 320ms ease both; }
.feedback-dialog.closing { animation: feedbackOut 200ms var(--ease) both; }
.feedback-dialog.closing::backdrop { animation: feedbackFadeOut 200ms ease both; }
@keyframes feedbackIn { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes feedbackOut { to { opacity: 0; transform: translateY(16px); } }
@keyframes feedbackFadeOut { to { opacity: 0; } }

.feedback-card { position: relative; display: flex; flex-direction: column; padding: 28px 28px 24px; }
.feedback-title {
  margin: 0 0 6px; padding-right: 36px;
  font: 700 18px/1.2 var(--sans); letter-spacing: -.02em;
}
.feedback-hint { margin: 0 0 18px; font-size: 13.5px; line-height: 1.4; color: var(--ink-muted); }
.feedback-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
.feedback-chip {
  min-height: 44px; padding: 0 16px; background: transparent; cursor: pointer;
  border: 1px solid var(--border-strong); border-radius: 0;
  font: 500 14px/1.2 var(--sans); letter-spacing: -.005em; color: var(--ink);
  transition: background 200ms var(--ease), color 200ms, border-color 200ms var(--ease);
}
.feedback-chip:hover { background: rgba(255, 255, 255, .62); border-color: var(--ink); }
.feedback-chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 600; }
.feedback-chip:focus-visible, .feedback-close:focus-visible, .feedback-open:focus-visible,
.feedback-send:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }   /* the textarea shows focus like the quiz's: its border turns black */
.feedback-comment-group { margin-bottom: 0; }
/* one line until it's used */
.feedback-comment {
  min-height: 46px; height: 46px; padding: 12px 14px; resize: none;
  transition: height 200ms var(--ease);
}
.feedback-comment:focus, .feedback-comment:not(:placeholder-shown) { height: 96px; }
.feedback-actions { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 16px; }
.feedback-status { flex: 1; margin: 0; font: 400 12px/1.5 var(--mono); color: var(--signal-text); }
.feedback-status:empty { display: none; }
.feedback-send { min-width: 156px; min-height: 46px; margin-left: auto; }

/* after Send: the thank-you, centred in the space the form left (results.js holds the card's height) */
.feedback-thanks {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  text-align: center; animation: fade 300ms ease both;
}
.feedback-thanks-mark {
  width: 48px; height: 48px; fill: none; stroke: var(--ink); stroke-width: 1.3;
  stroke-linecap: round; stroke-linejoin: round;
}
/* the ring from the top, then the tick (the questionnaire's skDraw) */
.feedback-thanks-mark :is(circle, path) { stroke-dasharray: 1; animation: skDraw 520ms var(--ease) both; }
.feedback-thanks-mark circle { transform: rotate(-90deg); transform-origin: 24px 24px; }
.feedback-thanks-mark path { animation-duration: 320ms; animation-delay: 380ms; }
.feedback-thanks-text { margin: 0; font: 600 17px/1.3 var(--sans); letter-spacing: -.012em; }

.feedback-close {
  position: absolute; top: 12px; right: 12px; width: 44px; height: 44px;
  background: none; border: 0; cursor: pointer;
  font: 300 26px/1 var(--sans); color: var(--ink-muted);
  transition: color 200ms;
}
.feedback-close:hover { color: var(--ink); }

@media (max-width: 700px) {
  .feedback-entry { margin-top: 40px; padding-top: 24px; }
  .feedback-open { flex: 1 1 100%; min-height: 54px; }
  /* a sheet the full width of the phone, sliding up from the bottom edge */
  .feedback-dialog {
    width: 100%; max-width: none; max-height: 88vh; max-height: 88dvh; margin: auto 0 0;
    border-width: 1px 0 0; box-shadow: 0 -8px 24px rgba(15, 14, 12, .12);
  }
  .feedback-dialog[open] { animation-name: feedbackSheetIn; }
  .feedback-dialog.closing { animation-name: feedbackSheetOut; }
  .feedback-card {
    padding: 20px max(16px, env(safe-area-inset-right, 0px)) calc(16px + env(safe-area-inset-bottom, 0px))
             max(16px, env(safe-area-inset-left, 0px));
  }
  .feedback-title { font-size: 17px; }
  .feedback-hint { margin-bottom: 14px; font-size: 12.5px; }
  .feedback-chips { gap: 6px; margin-bottom: 18px; }
  .feedback-chip { min-height: 40px; padding: 0 13px; font-size: 13.5px; }
  .feedback-actions { margin-top: 14px; }
  .feedback-send { flex: 1; min-width: 0; min-height: 50px; }
  .feedback-status { flex-basis: 100%; }
  .feedback-actions:has(.feedback-status:not(:empty)) { flex-wrap: wrap; }
  .feedback-close { top: 6px; right: 6px; }
}
@keyframes feedbackSheetIn { from { transform: translateY(100%); } to { transform: none; } }
@keyframes feedbackSheetOut { to { transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) {
  .feedback-dialog[open], .feedback-dialog[open]::backdrop, .feedback-thanks,
  .feedback-thanks-mark :is(circle, path) { animation: none; }
  .feedback-comment, .feedback-chip { transition: none !important; }
}


/* ── foldables, and phones on their side ──────────────────────────
   The breakpoints above go by width alone. Two more screen shapes get their own layout, the iPhone Duo's above all
   (its Safari viewports are in webkit.org/blog/18486). It's detected by shape, not model: Safari doesn't say which
   iPhone it is on, and other foldables share these shapes.
   - Big and nearly square, held upright: the Duo open and turned upright (669 x 867), another foldable's inner
     screen. At 600-700px wide that was the phone layout, which left small type over an empty band at the foot;
     this is a roomier version of it that fills the screen.
   - Wide and short: the Duo open (951 x 585), its outer screen on its side (594 x 368), any phone on its side. The
     question sits on the left and its answers on the right, so the step and Next fit on the screen.
   When the Duo is half-folded, Safari's Viewport Segments API (a preview behind a feature flag in Safari 27.1)
   says where the fold is, and the two sides line up with it, at the end. */

@media (min-width: 600px) and (max-width: 700px) and (min-height: 760px) {
  :root { --gut: 36px; --lead: 58px; --tail: 52px; --row: 68px; }
  .panel-left { height: 60px; }
  :root { --sketch-h: 124px; }
  .question-container.show { padding-top: 26px; padding-bottom: calc(32px + env(safe-area-inset-bottom, 0px)); }
  .main-title { font-size: 54px; line-height: .98; letter-spacing: -.035em; }
  .question-label { margin-bottom: 12px; }
  .question-title { font-size: 34px; line-height: 1.06; margin-bottom: 10px; }
  .question-description { font-size: 15px; line-height: 1.5; margin-bottom: 22px; }
  #welcomeScreen .question-description { font-size: 17px; }
  .option-title { font-size: 16.5px; padding: 11px 20px 0; }
  .option-card:not(:has(.option-description)) .option-title { padding: 11px 20px; }
  .option-description { font-size: 13px; padding: 3px 20px 0; margin-bottom: 11px; }
  .option-icon svg { width: 22px; height: 22px; }
  .sketch-strip, .sketch-strip:is([data-question="vibe"], [data-question="space-size"]) { margin-top: 20px; }
  /* the A/B photos side by side, upright like the other image cards */
  .options-grid.random-pick { grid-template-columns: 1fr 1fr; }
  .random-pick .option-card.image-card { aspect-ratio: 4 / 5; }
  /* the results' top in two columns again, the render beside the headline */
  .results-top {
    grid-template-columns: minmax(0, 1fr) minmax(0, 48%); grid-template-rows: auto 1fr auto;
    grid-template-areas: "text image" "spec image" ". note"; column-gap: 28px;
  }
  .results-top > .spec-block { margin-top: 24px; }
  .results-page .main-title { font-size: 40px; }
  .results-page .question-description { font-size: 14px; }
}

/* Short and upright: the Duo's outer screen (382 x 580, about 80px shorter than other iPhones), the Duo's inner
   screen split between two apps (385 x 571), an iPhone SE. Spacing, rows and the question's type scale with the
   screen's height, the answers' type is a size down and their descriptions keep to one line, and the sketch has no
   minimum (it shows in whatever room is left, or not at all), so each step's answers and Next fit on the screen with
   room for the sketch. The A/B photos sit side by side so both are in view at once. The welcome is compact enough to
   fit too, its photo band taking whatever height is left at the foot. */
@media (orientation: portrait) and (max-width: 700px) and (max-height: 620px) {
  :root { --row: clamp(44px, 8svh, 52px); --sketch-h: 0px; --sketch-pad: 8px; }
  .panel-left { height: 44px; }
  .progress-text { padding-top: 6px; }
  .question-container.show { padding-top: 10px; padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
  .question-label { margin-bottom: 4px; }
  .question-title { font-size: clamp(20px, 3.9svh, 24px); margin-bottom: 5px; }
  .question-description { font-size: 13px; line-height: 1.4; margin-bottom: 10px; }
  .option-title { padding-top: 8px; }
  .option-card:not(:has(.option-description)) .option-title { padding: 8px 14px; }
  .option-description { line-height: 1.3; margin-bottom: 7px; -webkit-line-clamp: 1; }
  /* the questions a size down, so the answer's sketch gets more of the screen */
  #questionScreen { --row: clamp(44px, 7.6svh, 50px); }
  #questionScreen .question-title { font-size: clamp(19px, 3.5svh, 22px); }
  #questionScreen .question-description { font-size: 12.5px; margin-bottom: 9px; }
  #questionScreen .option-title { font-size: 14.5px; padding-top: 7px; }
  #questionScreen .option-card:not(:has(.option-description)) .option-title { padding: 7px 14px; }
  #questionScreen .option-description { font-size: 11.5px; margin-bottom: 6px; }
  #questionScreen .option-icon svg { width: 19px; height: 19px; }
  /* the welcome, compact: its photo band takes what's left at the foot */
  #welcomeScreen.show { padding-top: 16px; padding-bottom: 0; }
  #welcomeScreen .entry-index { margin-bottom: 10px; font-size: 11px; }
  #welcomeScreen .main-title { font-size: clamp(27px, 5.3svh, 31px); margin-bottom: 10px; }
  #welcomeScreen .question-description { font-size: 14px; }
  #welcomeScreen .button-group { margin-top: 16px; }
  #welcomeScreen .entry-grid { gap: 18px; }
  #welcomeScreen .spec-row { padding: 9px 0; }
  #welcomeScreen .setup-carousel { flex-grow: 1; height: 96px; margin-top: 18px; }
  .sketch-strip, .sketch-strip:is([data-question="vibe"], [data-question="space-size"]) { margin-top: 6px; }
  .button-group { padding-top: 10px; }
  .btn-primary { min-height: 48px; }
  .options-grid.random-pick { grid-template-columns: 1fr 1fr; }
  .random-pick .option-card.image-card { aspect-ratio: 4 / 5; }
  .input-group { margin-bottom: 12px; }
  .input-field { padding: 12px 14px; }
}

/* the welcome band runs down to the foot of the screen (its photos widen with it), on both shapes */
@media (min-width: 600px) and (max-width: 700px) and (min-height: 760px),
       (orientation: landscape) and (max-width: 1040px) and (max-height: 620px),
       (horizontal-viewport-segments: 2) {
  #welcomeScreen.show { padding-bottom: 0; }
  #welcomeScreen .setup-carousel { flex-grow: 1; }
}

/* Wide and short. Questions in two columns: the question (and its answer's sketch) on the left, the answers and
   Next on the right. #questionContent's answers fill rows 1-5 on the right; row 5 takes any spare height, so Next
   sits at the foot of the screen. */
@media (orientation: landscape) and (max-width: 1040px) and (max-height: 620px), (horizontal-viewport-segments: 2) {
  :root { --row: 60px; --lead: 52px; --tail: 44px; }
  .question-container.show { padding-top: 28px; padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px)); }
  .main-title { font-size: 46px; }
  .question-title { font-size: 32px; }
  .entry-index { margin-bottom: 16px; }
  .option-title { font-size: 16px; padding: 11px 18px 0; }
  .option-card:not(:has(.option-description)) .option-title { padding: 11px 18px; }
  .option-description { font-size: 12.5px; padding: 2px 18px 0; margin-bottom: 11px; -webkit-line-clamp: 2; }
  .btn-primary { min-height: 52px; }

  /* welcome: the title beside the spec rows again, as on a wide screen */
  .entry-grid { flex-direction: row; gap: 40px; }
  .spec-block { width: 240px; }
  #welcomeScreen .setup-carousel { height: 160px; margin-top: 28px; }

  #questionScreen.show {
    display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); column-gap: 40px;
    grid-template-rows: auto auto auto auto 1fr auto auto;
  }
  /* the A/B photos get most of the width */
  #questionScreen.show:has(.random-pick) { grid-template-columns: minmax(0, 3fr) minmax(0, 7fr); }
  #questionScreen > .question-label { grid-area: 1 / 1; }
  #questionScreen > .question-title { grid-area: 2 / 1; }
  #questionScreen > .question-description { grid-area: 3 / 1; margin-bottom: 0; }
  #questionContent { grid-column: 2; grid-row: 1 / 6; }
  /* a step with a sketch: its strip moves to the left, under the question, down beside Next (rows 4-7) */
  #questionContent:has(> .sketch-strip) { display: contents; }
  #questionContent:has(> .sketch-strip) > :not(.sketch-strip) { grid-column: 2; grid-row: 1 / 6; }
  #questionContent > .sketch-strip,
  #questionContent > .sketch-strip:is([data-question="vibe"], [data-question="space-size"]) {
    grid-area: 4 / 1 / 8; margin-top: 20px;
  }
  .sketch-box { left: 0; translate: 0 -50%; }   /* in line with the question above it */
  .sketch-note { text-align: left; }
  #questionScreen > .error-message { grid-area: 6 / 2; }
  #questionScreen > .button-group { grid-area: 7 / 2; padding-top: 16px; }
  .options-grid.random-pick { grid-template-columns: 1fr 1fr; }
  /* stretch: when the height cap bites, the photo keeps its column's width and crops a little more */
  .random-pick .option-card.image-card {
    aspect-ratio: 4 / 5; max-height: calc(100svh - 220px); min-height: 140px; justify-self: stretch;
  }

  /* results: the render beside the headline, no taller than the screen */
  .results-top {
    grid-template-columns: minmax(0, 1fr) min(46%, calc((100svh - 130px) * .8)); grid-template-rows: auto 1fr auto;
    grid-template-areas: "text image" "spec image" ". note"; column-gap: 32px;
  }
  .results-top > .spec-block { max-width: 440px; margin-top: 20px; }
}

/* A phone on its side, or the Duo's outer screen on its side: shorter still. The answers get the whole right-hand
   column and Next moves to the foot of the left one, under the question and its sketch, so a step of six answers
   fits without scrolling; the sketch takes whatever height is left between the question and Next. */
@media (orientation: landscape) and (max-width: 1040px) and (max-height: 440px) {
  :root { --row: 44px; }
  .panel-left { height: 44px; }
  .progress-text { padding-top: 8px; }
  .question-container.show { padding-top: 16px; padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
  #welcomeScreen .entry-index { display: none; }
  .main-title { font-size: 28px; line-height: 1.03; letter-spacing: -.03em; margin-bottom: 12px; }
  .question-label { margin-bottom: 8px; }
  .question-title { font-size: 24px; line-height: 1.08; margin-bottom: 7px; }
  .question-description { font-size: 13px; line-height: 1.45; }
  #welcomeScreen .question-description { font-size: 14.5px; }
  #welcomeScreen .button-group { margin-top: 16px; }
  .entry-grid { gap: 28px; }
  .spec-block { width: 200px; }
  .spec-row { padding: 10px 0; }
  #welcomeScreen .setup-carousel { height: 80px; margin-top: 20px; }
  .option-title { font-size: 15px; padding: 8px 14px 0; }
  .option-card:not(:has(.option-description)) .option-title { padding: 8px 14px; }
  .option-description { font-size: 12px; line-height: 1.3; padding: 2px 14px 0; margin-bottom: 7px; -webkit-line-clamp: 1; }
  .btn-primary { min-height: 48px; }
  :root { --sketch-h: 0px; }
  #questionContent > .sketch-strip,
  #questionContent > .sketch-strip:is([data-question="vibe"], [data-question="space-size"]) { grid-area: 4 / 1 / 7; margin-top: 12px; }
  #questionContent, #questionContent:has(> .sketch-strip) > :not(.sketch-strip) { grid-row: 1 / 8; }
  #questionScreen > .error-message { grid-area: 6 / 1; }
  #questionScreen > .button-group { grid-area: 7 / 1; padding-top: 12px; }
  .input-group { gap: 6px; margin-bottom: 10px; }
  .input-field { padding: 11px 14px; }
  .random-pick .option-card.image-card { max-height: calc(100svh - 104px); }
  .results-top { grid-template-columns: minmax(0, 1fr) min(42%, calc((100svh - 80px) * .8)); column-gap: 24px; }
  .results-page .main-title { font-size: 30px; }
  .results-page .question-description { font-size: 13px; margin-bottom: 0; }
  .loading-content { gap: 24px; }
}

/* The Duo half-folded like a book: two pages side by side. Each layout's two columns meet at the fold, the loading
   orb and the feedback pop-up sit on the right-hand page, clear of it. */
@media (horizontal-viewport-segments: 2) {
  :root {
    --page-l: calc(env(viewport-segment-width 0 0) - var(--pad-l) - var(--gut));   /* the left page, less margins */
    --fold-gap: calc(env(viewport-segment-left 1 0) - env(viewport-segment-right 0 0) + 2 * var(--gut));
  }
  #questionScreen.show, #questionScreen.show:has(.random-pick) {
    grid-template-columns: var(--page-l) minmax(0, 1fr); column-gap: var(--fold-gap);
  }
  .entry-grid { gap: var(--fold-gap); }
  .entry-left { flex: 0 0 var(--page-l); }
  .spec-block { flex: 0 1 300px; }
  .results-top {
    grid-template-columns: var(--page-l) min(calc(env(viewport-segment-width 1 0) - var(--gut) - var(--pad-r)),
                                             calc((100svh - 130px) * .8));
    column-gap: var(--fold-gap);
  }
  .loading-screen { padding-left: env(viewport-segment-left 1 0); }
  .feedback-dialog { left: env(viewport-segment-left 1 0); max-width: calc(env(viewport-segment-width 1 0) - 32px); }
}

/* Half-folded like a laptop: the orb on the upper half, the feedback sheet on the lower */
@media (vertical-viewport-segments: 2) {
  .loading-screen { align-items: flex-start; }
  .loading-content { height: env(viewport-segment-bottom 0 0); justify-content: center; }
  .feedback-dialog { max-height: env(viewport-segment-height 0 1); }
}
