/* ============================================================
   BELLA - App Styles
   Save to: D:\bella\backend\static\css\app.css
   Replace existing file
   Sprint 18: #screen-landing redesigned — resumes Open Item 27 (paused
   Sprint 10). Added to the shared 1200px wide-screen group; new
   .landing-hero-grid (responsive 1/2/4-col image grid) and
   .landing-content (centered, readability-capped) sections replace
   the old narrow phone-strip layout. Restyled to Bella's own tokens,
   not the "BridalgownsNZ" reference's visual style. See the SCREEN:
   LANDING section below for full detail.
   Sprint 14: dress-style accordion list widened from a 720px cap to
   the full 1200px screen width, and its example-image row dropped
   from 4 to 3 images — together these bring the example images up
   to roughly the same size as a .pref-card image on the style-vision
   screen. Description text now runs the full width per line as a
   deliberate, confirmed tradeoff — see the DRESS-STYLE ACCORDION
   CARDS section below for the full note.
   Sprint 14 (cont'd): silhouette moved off the shared .pref-card grid
   onto its own accordion-card layout, mirroring dress-style's pattern
   with a checkmark control instead of a heart (multi-select) — see
   the new SILHOUETTE ACCORDION CARDS section below. .pref-card itself
   is now used only by the 6 single-select screens.
   Sprint 13: movement/coverage bulk-question screen (#screen-bulk-
   question) widened to the same 1200px layout as preference-select/
   silhouette, with .question-list now a responsive grid and
   .question-card restyled to a full-width-image-on-top card matching
   .pref-card's proportions — see BULK YES/NO QUESTION SCREENS below.
   Also fixed a pre-existing dead-CSS bug: the old #screen-movement/
   #screen-coverage selector never matched anything real.
   Sprint 12: added the DRESS-STYLE ACCORDION CARDS section (own class
   namespace, not a reuse of .pref-card/.pref-card-list) for the
   redesigned dress-style step.
   All styles for the Bella PWA. Structural conventions (screen
   system, .btn/.input/.error-msg classes, CSS-variable design
   tokens) follow the same pattern as the sienna sibling project
   for cross-project legibility — see project context §4.3. Colour
   palette, fonts, and the preference-flow components below are
   Bella-specific.
   ============================================================ */

/* ── Google Fonts ─────────────────────────────────────────── */
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;0,700;1,500&family=Jost:wght@300;400;500;600&display=swap');

/* ── Design tokens ────────────────────────────────────────── */
:root {
  --bg:            #FBF7F3;
  --surface:       #F3E4E0;
  --border:        #E4CFC8;
  --dusty-rose:    #C08A82;
  --dusty-rose-dark: #A9756C;
  --champagne:     #C9A66B;
  --charcoal:      #3A3532;
  --stone:         #8F8580;
  --stone-light:   #C9BFB8;
  --white:         #FFFFFF;
  --error:         #C0392B;
  --success:       #4A7C59;

  --font-display:  'Cormorant Garamond', Georgia, serif;
  --font-ui:       'Jost', system-ui, sans-serif;

  --radius-sm:     8px;
  --radius-md:     14px;
  --radius-lg:     20px;
  --radius-full:   999px;

  --shadow-sm:     0 1px 3px rgba(58,53,50,0.08);
  --shadow-md:     0 4px 16px rgba(58,53,50,0.10);
  --shadow-lg:     0 8px 32px rgba(58,53,50,0.14);

  --max-w:         480px;
  --screen-pad:    24px;
}

/* ── Reset ────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 16px; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-ui);
  background: var(--surface);
  color: var(--charcoal);
  min-height: 100dvh;
  line-height: 1.5;
}
img { display: block; max-width: 100%; }
button { cursor: pointer; font-family: var(--font-ui); border: none; background: none; }
input { font-family: var(--font-ui); }
a { color: var(--dusty-rose); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── App shell ────────────────────────────────────────────── */
#app {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

/* ── App header (new, Sprint 18 follow-up — Log out, Open Item 45)
   Single shared header, sibling to every .screen (see app.html) —
   #app's flex-column layout means this simply renders above
   whichever screen is currently .active, with no positioning tricks
   needed. Hidden by default; shown only on the post-auth screens via
   the .visible class, toggled in app.js's showScreen(). Matches the
   1200px width + border-framing already used by every screen (see
   the wide-screen group and desktop-framing rules below) so it reads
   as one continuous piece with the screen beneath it, not a
   separate floating bar. */
.app-header {
  display: none;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding: 16px var(--screen-pad);
  justify-content: flex-end;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.app-header.visible { display: flex; }

.logout-link {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--stone);
  padding: 4px 0;
  transition: color 0.15s ease;
}
.logout-link:hover { color: var(--dusty-rose-dark); text-decoration: underline; }

@media (min-width: 520px) {
  .app-header.visible {
    border-left: 1px solid var(--border);
    border-right: 1px solid var(--border);
  }
}

/* ── Screen system ─────────────────────────────────────────────
   Width is controlled per-screen, not on #app, so most screens
   (landing, auth, bulk-question) keep the narrow centered-column
   feel via --max-w, while the two card-grid screens
   (preference-select, silhouette) opt into a much wider max-width
   below — see PREFERENCE-FLOW CARDS section. */
.screen {
  display: none;
  flex-direction: column;
  flex: 1;
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: var(--screen-pad);
  background: var(--bg);
  animation: screenIn 0.3s ease;
}
.screen.active { display: flex; }

@keyframes screenIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Wordmark ─────────────────────────────────────────────── */
/* Sprint 18: .wordmark / .wordmark span removed — the landing
   screen (its only user) dropped the "bella / find your dress"
   wordmark block per an explicit request this sprint. Left as a
   comment, not silently deleted, in case a future screen wants this
   component back — same convention as the Sprint 13 dead-selector
   note elsewhere in this file. */

/* ── Typography ───────────────────────────────────────────── */
.screen-title {
  font-family: var(--font-display);
  font-size: 1.875rem;
  font-weight: 600;
  color: var(--charcoal);
  line-height: 1.2;
  margin-bottom: 8px;
}
.screen-subtitle {
  font-size: 0.9375rem;
  color: var(--stone);
  line-height: 1.5;
  margin-bottom: 32px;
}
.label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--charcoal);
  margin-bottom: 6px;
  letter-spacing: 0.01em;
}
.hint {
  font-size: 0.8125rem;
  color: var(--stone);
  margin-top: 6px;
  line-height: 1.4;
}

/* ── Inputs ───────────────────────────────────────────────── */
.input {
  width: 100%;
  padding: 14px 16px;
  font-size: 1rem;
  color: var(--charcoal);
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color 0.2s, box-shadow 0.2s;
  outline: none;
  -webkit-appearance: none;
}
.input::placeholder { color: var(--stone-light); }
.input:focus {
  border-color: var(--dusty-rose);
  box-shadow: 0 0 0 3px rgba(192,138,130,0.14);
}
.input.error { border-color: var(--error); }

.input-group { margin-bottom: 20px; }

/* ── Phone input row (country dropdown + local number) ──────
   Same two-part pattern as sienna: fixed-width country <select>
   + flexible local-number <input>. E.164 assembly happens in
   app.js buildE164FromParts(). NZ/AU only, per auth.py. */
.phone-input-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.phone-country-select {
  flex: 0 0 auto;
  width: 120px;
  padding: 14px 10px;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238F8580' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 28px;
}
.phone-local-input {
  flex: 1 1 auto;
  min-width: 0;
}

/* ── Buttons ──────────────────────────────────────────────── */
.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 15px 24px;
  font-size: 0.9375rem;
  font-weight: 600;
  border-radius: var(--radius-full);
  transition: background 0.2s, transform 0.1s, box-shadow 0.2s, opacity 0.2s;
  letter-spacing: 0.01em;
}
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.5; pointer-events: none; }

.btn-primary {
  background: var(--dusty-rose);
  color: var(--white);
  box-shadow: 0 2px 8px rgba(192,138,130,0.32);
}
.btn-primary:hover { background: var(--dusty-rose-dark); box-shadow: 0 4px 16px rgba(169,117,108,0.32); }

.btn-secondary {
  background: var(--surface);
  color: var(--charcoal);
  border: 1.5px solid var(--border);
}
.btn-secondary:hover { background: var(--border); }

.btn-ghost {
  background: transparent;
  color: var(--dusty-rose);
  font-weight: 500;
}
.btn-ghost:hover { text-decoration: underline; }

.btn-sm {
  padding: 10px 20px;
  font-size: 0.875rem;
}

/* ── Error message ────────────────────────────────────────── */
.error-msg {
  display: none;
  background: #FBECEA;
  border: 1px solid #F0C6C0;
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-size: 0.875rem;
  color: var(--error);
  margin-bottom: 16px;
  line-height: 1.4;
}
.error-msg.visible { display: block; }

/* ── Divider ──────────────────────────────────────────────── */
.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 24px 0;
  color: var(--stone-light);
  font-size: 0.8125rem;
}
.divider::before, .divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ── Header bar (screens with back nav) ──────────────────────*/
.screen-header {
  display: flex;
  align-items: center;
  margin-bottom: 32px;
  padding-top: 8px;
}
.back-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--stone);
  font-size: 0.875rem;
  font-weight: 500;
  padding: 4px 0;
  margin-right: auto;
  transition: color 0.2s;
}
.back-btn:hover { color: var(--charcoal); }
.back-btn svg { width: 18px; height: 18px; }

/* ── Progress dots (auth steps + preference-flow steps) ─────
   Reused for both the 2-step auth flows and the longer 9-step
   preference walkthrough — .steps-row renders one .step-dot per
   step, .active marking completed/current steps. Kept as a single
   generic component rather than sienna's flow-specific .trial-step,
   since Bella has two flows of very different lengths sharing the
   same visual idea. */
.steps-row {
  display: flex;
  gap: 6px;
  margin-bottom: 40px;
}
.step-dot {
  height: 3px;
  flex: 1;
  background: var(--border);
  border-radius: var(--radius-full);
  transition: background 0.3s;
}
.step-dot.active { background: var(--dusty-rose); }

/* ── Code entry ───────────────────────────────────────────── */
.code-input {
  font-size: 1.375rem;
  letter-spacing: 0.15em;
  text-align: center;
  font-weight: 600;
  text-transform: uppercase;
}
.resend-row {
  text-align: center;
  margin-top: 16px;
}

/* ════════════════════════════════════════════════════════════
   SCREEN: LANDING (Sprint 18 — resumes Open Item 27)
   Widened to the standard 1200px group (see the opt-out selector
   above) rather than the narrow --max-w phone-strip used by the
   other pre-walkthrough screens (register/login). Two stacked
   sections: a responsive hero image grid, then a centered content
   block (wordmark, headline, pitch copy, two CTAs). Restyled to
   Bella's own ivory/blush/dusty-rose tokens and Cormorant Garamond
   + Jost fonts — deliberately NOT replicating the blue-CTA reference
   screenshot's own visual style, per the standing Sprint 10 decision.
   Nav links intentionally absent — dropped from scope, not omitted
   by oversight (same standing decision).
   ════════════════════════════════════════════════════════════ */
#screen-landing {
  padding-bottom: 56px;
}

/* Hero grid: 1 col mobile -> 2 col tablet -> 4 col desktop, same
   breakpoint pattern as .pref-card-list/.question-list elsewhere in
   this file, for visual consistency across the app. */
.landing-hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: 40px;
}
@media (min-width: 640px) {
  .landing-hero-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .landing-hero-grid { grid-template-columns: repeat(4, 1fr); gap: 16px; }
}
.landing-hero-img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--surface); /* visible placeholder tone until real files are in place */
}

/* Content block: centered, capped for readability even at the full
   1200px screen width — same "wide shell, narrow readable column"
   idea already used by the dress-style accordion's description text. */
.landing-content {
  max-width: 560px;
  margin: 0 auto;
  text-align: center;
}
/* .landing-wordmark rule removed Sprint 18 alongside .wordmark above
   — the div it targeted no longer exists in app.html. */
.landing-headline {
  font-family: var(--font-display);
  font-size: 2.375rem;
  font-weight: 600;
  color: var(--charcoal);
  line-height: 1.15;
  margin-bottom: 16px;
  letter-spacing: -0.01em;
}
.landing-headline em {
  font-style: italic;
  color: var(--dusty-rose-dark);
}
.landing-body {
  font-size: 1rem;
  color: var(--stone);
  line-height: 1.6;
  margin: 0 auto 32px;
  max-width: 480px;
}

/* Two CTAs: stacked on mobile (existing .btn is already full-width),
   side by side from tablet width up once there's room for both. */
.landing-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
@media (min-width: 640px) {
  .landing-actions {
    flex-direction: row;
    justify-content: center;
  }
  .landing-actions .btn { width: auto; min-width: 220px; }
}

/* ════════════════════════════════════════════════════════════
   PREFERENCE-FLOW CARDS
   Shared by all 6 single-select screens (rendered dynamically by
   app.js's shared renderer). As of Sprint 14, silhouette no longer
   uses this component — it moved to its own accordion-card layout,
   same pattern as dress-style (Sprint 12) — see SILHOUETTE ACCORDION
   CARDS below. .pref-card-check (the heart icon) is still shared
   across all 6 single-select screens.
   ════════════════════════════════════════════════════════════ */
/* These screens opt out of the standard --max-w narrow column — the
   card grid needs real room at tablet/desktop widths. On small
   viewports max-width simply never becomes the limiting factor, so
   mobile is unaffected (still full-width, single column).
   #screen-bulk-question added Sprint 13, replacing a dead rule that
   targeted #screen-movement/#screen-coverage — those IDs never
   existed in app.html (the real shared section id is
   #screen-bulk-question), so the old rule never applied to anything.
   #screen-landing added Sprint 18 (Open Item 27). #screen-register/
   -register-code/-login/-login-code added later the same sprint, for
   visual consistency across the whole pre-walkthrough flow — their
   actual form content stays capped to a narrow readable column via
   .auth-content (below), same idea as .landing-content/.dress-style-
   list capping their own content inside a wide shell. */
#screen-preference-select,
#screen-silhouette,
#screen-bulk-question,
#screen-complete,
#screen-landing,
#screen-register,
#screen-register-code,
#screen-login,
#screen-login-code {
  padding-top: 48px;
  max-width: 1200px;
}

/* Sprint 18: wraps the actual form content on all four auth screens
   (register, register-code, login, login-code) — keeps the form
   itself the same visual width it always was (matches --max-w, the
   original narrow phone-strip value) while the screen around it now
   gets the same wide bordered shell as every other screen. */
.auth-content {
  max-width: var(--max-w);
  margin: 0 auto;
}

/* Responsive grid: 1 col mobile -> 2 col tablet -> 3 col desktop. */
.pref-card-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  margin-bottom: 24px;
}
@media (min-width: 640px) {
  .pref-card-list { grid-template-columns: repeat(2, 1fr); gap: 24px; }
}
@media (min-width: 1024px) {
  .pref-card-list { grid-template-columns: repeat(3, 1fr); gap: 28px; }
}

/* Card: full-width image on top, text block below. Used by the 6
   single-select screens only as of Sprint 14 — silhouette moved off
   this shared component into its own accordion layout (see below). */
.pref-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  text-align: left;
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
  position: relative;
}
.pref-card:hover { border-color: var(--dusty-rose); }
.pref-card:active { transform: scale(0.99); }
.pref-card.selected {
  border-color: var(--dusty-rose);
  box-shadow: 0 0 0 2px rgba(192,138,130,0.18);
}
.pref-card-image {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--surface);
  flex-shrink: 0;
}
.pref-card-text {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px;
}
.pref-card-title {
  font-weight: 600;
  color: var(--charcoal);
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.pref-card-desc {
  font-size: 0.8125rem;
  color: var(--stone);
  line-height: 1.5;
}

/* Heart select-indicator, overlaid on the top-right corner of the
   image. Outline by default; fills solid dusty-rose when selected.
   Shared by both single-select cards and the silhouette multi-select
   cards (per product decision: heart = select, for either shape). */
.pref-card-check {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(58,53,50,0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}
.pref-card-check svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: var(--white);
  stroke-width: 2;
  transition: fill 0.15s, stroke 0.15s;
}
.pref-card.selected .pref-card-check {
  background: rgba(58,53,50,0.5);
}
.pref-card.selected .pref-card-check svg {
  fill: var(--dusty-rose);
  stroke: var(--white);
}

/* ════════════════════════════════════════════════════════════
   DRESS-STYLE ACCORDION CARDS
   Single-column, single-select list used only by the dress-style
   step of the preference walkthrough (loadDressStyleStep in app.js).
   Deliberately its own class namespace, not a reuse of .pref-card /
   .pref-card-list above — those remain shared by the other 5
   single-select screens plus silhouette, and stay untouched here.
   Renders inside the same #screen-preference-select shell (still
   max-width: 1200px, per the rule above).
   Sprint 14: widened from a 720px-capped single column to the full
   1200px width, so the 3-across example-image row (see below) can
   match the image size used by the single-select .pref-card screens
   (e.g. style-vision). Deliberate tradeoff, confirmed with the user:
   description text now runs the full 1200px width per line too,
   rather than staying narrow/readable — accepted in exchange for
   true image-size parity. If line length becomes a real readability
   problem later, a text-only max-width (independent of the image
   row) is the fallback to revisit.
   ════════════════════════════════════════════════════════════ */
.dress-style-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto 24px;
}

.dress-style-card {
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  padding: 20px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.dress-style-card.selected {
  border-color: var(--dusty-rose);
  box-shadow: 0 0 0 2px rgba(192,138,130,0.18);
}

.dress-style-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.dress-style-card-title {
  font-weight: 600;
  color: var(--charcoal);
  font-size: 1.0625rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* Heart select-indicator — same visual language as .pref-card-check
   (outline default, fills dusty-rose when selected), but inline in
   the header row rather than absolutely positioned over an image,
   since this card layout has no top image of its own. */
.dress-style-card-heart {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}
.dress-style-card-heart svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: var(--stone);
  stroke-width: 2;
  transition: fill 0.15s, stroke 0.15s;
}
.dress-style-card-heart:hover svg { stroke: var(--dusty-rose); }
.dress-style-card.selected .dress-style-card-heart {
  background: var(--surface);
}
.dress-style-card.selected .dress-style-card-heart svg {
  fill: var(--dusty-rose);
  stroke: var(--dusty-rose-dark);
}

.dress-style-card-desc {
  font-size: 0.875rem;
  color: var(--stone);
  line-height: 1.5;
  margin-bottom: 16px;
}

/* Accordion toggle bar — full-width, low-emphasis, independent of
   the heart/selection control above. Collapsed by default per card;
   toggling never affects singleSelectChoice. */
.dress-style-accordion-toggle {
  display: block;
  width: 100%;
  padding: 10px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--charcoal);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-align: center;
  transition: background 0.15s, border-color 0.15s;
}
.dress-style-accordion-toggle:hover {
  background: var(--surface);
  border-color: var(--dusty-rose);
}

/* 3-across example image row (Sprint 14 — was 4-across at the old
   720px card width; dropped to 3 alongside the width increase above
   so each image reaches roughly the same size as a .pref-card image
   on the style-vision screen). Temp placeholder URLs point at the
   real eventual static path — see getDressStyleExampleImages() in
   app.js — so no markup rework is needed once real image files are
   dropped into place. app.js now requests jpgs 1-3 only, not 1-4. */
.dress-style-examples {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-top: 16px;
}
.dress-style-examples[hidden] { display: none; }
.dress-style-example-img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface);
}
@media (max-width: 640px) {
  /* Below tablet width, 3 columns of ~380px-target images no longer
     fit — drop to 2 so each stays legible. Threshold raised from the
     old 480px cutoff since the row is now much wider at full size. */
  .dress-style-examples { grid-template-columns: repeat(2, 1fr); }
}

/* ════════════════════════════════════════════════════════════
   SILHOUETTE ACCORDION CARDS (Sprint 14)
   Silhouette moved off the shared .pref-card/.pref-card-list grid
   (used until Sprint 13) onto its own accordion-card layout, mirroring
   DRESS-STYLE ACCORDION CARDS above almost exactly — same list/card/
   toggle/example-row structure — with two deliberate differences:
   1. Checkmark control instead of a heart, since silhouette is
      multi-select (several can be chosen) and the heart icon is
      reserved elsewhere for single-select.
   2. Example images use the real, already-live image_url_1/2/3
      fields from GET /dress-silhouette (Sprint 7), not a client-
      built path — no getSilhouetteExampleImages() helper needed.
   Renders inside the same #screen-silhouette shell (already
   max-width: 1200px, see the rule above) — #silhouette-list's class
   was swapped in app.html from .pref-card-list to .silhouette-list.
   ════════════════════════════════════════════════════════════ */
.silhouette-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto 24px;
}

.silhouette-card {
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  padding: 20px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.silhouette-card.selected {
  border-color: var(--dusty-rose);
  box-shadow: 0 0 0 2px rgba(192,138,130,0.18);
}

.silhouette-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.silhouette-card-title {
  font-weight: 600;
  color: var(--charcoal);
  font-size: 1.0625rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* Checkmark select-indicator — same circular badge treatment as
   dress-style's heart, different icon/fill logic since this is a
   multi-select toggle rather than an exclusive choice. */
.silhouette-card-check {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}
.silhouette-card-check svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: var(--stone);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke 0.15s;
}
.silhouette-card-check:hover svg { stroke: var(--dusty-rose); }
.silhouette-card.selected .silhouette-card-check {
  background: var(--dusty-rose);
}
.silhouette-card.selected .silhouette-card-check svg {
  stroke: var(--white);
}

.silhouette-card-desc {
  font-size: 0.875rem;
  color: var(--stone);
  line-height: 1.5;
  margin-bottom: 16px;
}

.silhouette-accordion-toggle {
  display: block;
  width: 100%;
  padding: 10px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--charcoal);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-align: center;
  transition: background 0.15s, border-color 0.15s;
}
.silhouette-accordion-toggle:hover {
  background: var(--surface);
  border-color: var(--dusty-rose);
}

/* 3-across, real image_url_1/2/3 — same target size as the widened
   dress-style example row (see that section's Sprint 14 note). */
.silhouette-examples {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-top: 16px;
}
.silhouette-examples[hidden] { display: none; }
.silhouette-example-img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface);
}
@media (max-width: 640px) {
  .silhouette-examples { grid-template-columns: repeat(2, 1fr); }
}

/* ════════════════════════════════════════════════════════════
   BULK YES/NO QUESTION SCREENS (movement, coverage)
   ════════════════════════════════════════════════════════════ */
#screen-movement,
#screen-coverage {
  /* Intentionally removed Sprint 13 — dead rule, #screen-movement and
     #screen-coverage never existed in app.html. Superseded by
     #screen-bulk-question in the PREFERENCE-FLOW CARDS section above,
     which now carries the equivalent (and correctly-targeted)
     padding-top. Left as a comment, not deleted outright, so a future
     session doesn't wonder whether this was accidentally dropped. */
}
/* Responsive grid, same breakpoints as .pref-card-list, so
   movement/coverage visually match the single-select screens. */
.question-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  margin-bottom: 24px;
}
@media (min-width: 640px) {
  .question-list { grid-template-columns: repeat(2, 1fr); gap: 24px; }
}
@media (min-width: 1024px) {
  .question-list { grid-template-columns: repeat(3, 1fr); gap: 28px; }
}
/* Card: full-width image on top, text+answer buttons below — same
   structure as .pref-card, sized to match. app.js's markup (image
   followed by a .question-card-body wrapper) needs no change; only
   this CSS changed to stack it vertically instead of as a row. */
.question-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  padding: 0;
}
.question-card-image {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--surface);
  flex-shrink: 0;
}
.question-card-body {
  padding: 16px;
  display: flex;
  flex-direction: column;
}
.question-text {
  font-size: 0.9375rem;
  color: var(--charcoal);
  font-weight: 500;
  line-height: 1.4;
  margin-bottom: 4px;
}
.question-note {
  font-size: 0.8125rem;
  color: var(--stone);
  line-height: 1.4;
  margin-bottom: 14px;
}
.answer-toggle {
  display: flex;
  gap: 8px;
}
.answer-btn {
  flex: 1;
  padding: 10px;
  font-size: 0.875rem;
  font-weight: 600;
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--border);
  background: var(--bg);
  color: var(--stone);
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.answer-btn.selected {
  border-color: var(--dusty-rose);
  background: var(--dusty-rose);
  color: var(--white);
}

/* ════════════════════════════════════════════════════════════
   DRESS MATCHES (screen-complete, repurposed Sprint 16)
   Replaces the original static "You're all set!" holding screen —
   this screen now fetches and renders real dress matches once the
   silhouette step's "Find My Dresses" button is clicked (see
   app.js loadDressMatchesStep). Old holding-screen styles
   (centered layout, .complete-icon) removed entirely along with
   the markup they styled, since this screen's whole purpose
   changed, not just its data source. Width/padding now comes from
   the wide-screen opt-out group above, same as preference-select/
   silhouette/bulk-question — a 3-photo row per dress needs real
   room, same reasoning as those screens' card grids.

   This session (favorites, new): each dress is now a
   .dress-match-card (photos + a Like/Liked button beneath), not a
   bare .dress-match-row — see .dress-match-card/.dress-match-like-btn
   below. #favorited-dresses reuses .dress-matches-list's own layout
   rules (same class) and is hidden via :empty when nothing's been
   favorited yet, rather than a separate JS-toggled display rule.
   ════════════════════════════════════════════════════════════ */
.dress-matches-list {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-bottom: 28px;
}

/* Favorited section sits above the regular results (DOM order in
   app.html) and simply disappears — no heading, no border, no
   placeholder — until at least one dress has been liked. */
#favorited-dresses:empty {
  display: none;
  margin-bottom: 0;
}

.dress-match-card {
  display: flex;
  flex-direction: column;
}

/* One row of photos per dress. auto-fit/minmax rather than a fixed
   repeat(3, 1fr): most dresses have all 3 images, but front/back/
   detail are each independently nullable (Sprint 15 import), so a
   dress with only 1-2 images should still lay out cleanly rather
   than leaving empty grid cells. */
.dress-match-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 12px;
}
.dress-match-photo {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

/* Full-width, spans the entire card beneath the photo row — per the
   product requirement ("button that spans the entire width").
   Unselected/selected states follow the same outline-to-filled
   convention already used by .answer-btn above, for visual
   consistency across the app rather than inventing a third pattern. */
.dress-match-like-btn {
  width: 100%;
  margin-top: 10px;
  padding: 12px 16px;
  border: 1.5px solid var(--dusty-rose);
  border-radius: var(--radius-md);
  background: var(--white);
  color: var(--dusty-rose-dark);
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.dress-match-like-btn:hover:not(:disabled) {
  border-color: var(--dusty-rose-dark);
}
.dress-match-like-btn:disabled {
  opacity: 0.6;
  cursor: default;
}
.dress-match-like-btn.liked {
  border-color: var(--dusty-rose);
  background: var(--dusty-rose);
  color: var(--white);
}

.dress-matches-empty {
  text-align: center;
  color: var(--stone);
  font-size: 0.9375rem;
  padding: 48px 24px;
}

/* ── Loading spinner (inline) ─────────────────────────────── */
.spinner {
  width: 18px;
  height: 18px;
  border: 2px solid rgba(255,255,255,0.4);
  border-top-color: var(--white);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  flex-shrink: 0;
}
.spinner-dark {
  border-color: rgba(58,53,50,0.2);
  border-top-color: var(--charcoal);
}
@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Full-screen loading state, used while a preference screen's
   options are being fetched. */
.screen-loading {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.screen-loading .spinner { width: 28px; height: 28px; }

/* ── Toast notification ───────────────────────────────────── */
.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(80px);
  background: var(--charcoal);
  color: var(--white);
  padding: 12px 20px;
  border-radius: 16px;
  font-size: 0.875rem;
  font-weight: 500;
  white-space: normal;
  word-wrap: break-word;
  text-align: center;
  z-index: 9999;
  transition: transform 0.3s ease;
  pointer-events: none;
  width: max-content;
  max-width: min(calc(var(--max-w) - 48px), 360px);
}
.toast.visible { transform: translateX(-50%) translateY(0); }

/* ── Responsive: desktop framing ───────────────────────────
   Applies to every screen (including the wide card-grid screens,
   which just frame a much larger box via their own max-width
   override below). */
@media (min-width: 520px) {
  .screen {
    border-left: 1px solid var(--border);
    border-right: 1px solid var(--border);
  }
}